class Puppet::Pops::Parser::PNParser

Constants

LIT_FALSE
LIT_NIL
LIT_TRUE
TOKEN_BOOL
TOKEN_END
TOKEN_FLOAT
TOKEN_IDENTIFIER
TOKEN_INT
TOKEN_KEY
TOKEN_LB
TOKEN_LC
TOKEN_LP
TOKEN_NIL
TOKEN_RB
TOKEN_RC
TOKEN_RP
TOKEN_STRING
TOKEN_WS
TYPE_ALPHA
TYPE_DELIM
TYPE_DIGIT
TYPE_END
TYPE_IDENTIFIER
TYPE_KEY_START
TYPE_MINUS
TYPE_STRING_START
TYPE_WS

Public Class Methods

char_types() click to toggle source
   # File lib/puppet/pops/parser/pn_parser.rb
52 def self.char_types
53   unless instance_variable_defined?(:@char_types)
54     @char_types = Array.new(0x80, TYPE_IDENTIFIER)
55     @char_types[0] = TYPE_END
56     [0x09, 0x0d, 0x0a, 0x20].each { |n| @char_types[n] = TYPE_WS }
57     [TOKEN_LP, TOKEN_RP, TOKEN_LB, TOKEN_RB, TOKEN_LC, TOKEN_RC].each { |n| @char_types[n] = TYPE_DELIM }
58     @char_types[0x2d] = TYPE_MINUS
59     (0x30..0x39).each { |n| @char_types[n] = TYPE_DIGIT }
60     (0x41..0x5a).each { |n| @char_types[n] = TYPE_ALPHA }
61     (0x61..0x7a).each { |n| @char_types[n] = TYPE_ALPHA }
62     @char_types[TOKEN_KEY] = TYPE_KEY_START
63     @char_types[TOKEN_STRING] = TYPE_STRING_START
64     @char_types.freeze
65   end
66   @char_types
67 end
new() click to toggle source
   # File lib/puppet/pops/parser/pn_parser.rb
36 def initialize
37   @char_types = self.class.char_types
38 end

Public Instance Methods

parse(text, locator = nil, offset = nil) click to toggle source
   # File lib/puppet/pops/parser/pn_parser.rb
40 def parse(text, locator = nil, offset = nil)
41   @locator = locator
42   @offset = offset
43   @text = text
44   @codepoints = text.codepoints.to_a.freeze
45   @pos = 0
46   @token = TOKEN_END
47   @token_value = nil
48   next_token
49   parse_next
50 end

Private Instance Methods

consume_float(s, d) click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
267 def consume_float(s, d)
268   parse_error(_('digit expected')) if skip_decimal_digits == 0
269   c = peek_cp
270   if d == 0x2e # '.'
271     if c == 0x45 || c == 0x65 # 'E' or 'e'
272       @pos += 1
273       parse_error(_('digit expected')) if skip_decimal_digits == 0
274       c = peek_cp
275     end
276   end
277   parse_error(_('digit expected')) if @char_types[c] == TYPE_ALPHA
278   @token_value = @text[s...@pos].to_f
279   @token = TOKEN_FLOAT
280 end
consume_identifier(s) click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
198 def consume_identifier(s)
199   while @char_types[peek_cp] >= TYPE_IDENTIFIER do
200     @pos += 1
201   end
202   id = @text[s...@pos]
203   case id
204   when LIT_TRUE
205     @token = TOKEN_BOOL
206     @token_value = true
207   when LIT_FALSE
208     @token = TOKEN_BOOL
209     @token_value = false
210   when LIT_NIL
211     @token = TOKEN_NIL
212     @token_value = nil
213   else
214     @token = TOKEN_IDENTIFIER
215     @token_value = id
216   end
217 end
consume_string() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
219 def consume_string
220   s = @pos
221   b = String.new
222   loop do
223     c = next_cp
224     case c
225     when TOKEN_END
226       @pos = s - 1
227       parse_error(_('unterminated quote'))
228     when TOKEN_STRING
229       @token_value = b
230       @token = TOKEN_STRING
231       break
232     when 0x5c # '\'
233       c = next_cp
234       case c
235       when 0x74 # 't'
236         b << "\t"
237       when 0x72 # 'r'
238         b << "\r"
239       when 0x6e # 'n'
240         b << "\n"
241       when TOKEN_STRING
242         b << '"'
243       when 0x5c # '\'
244         b << "\\"
245       when 0x6f # 'o'
246         c = 0
247         3.times do
248           n = next_cp
249           if 0x30 <= n && n <= 0x37c
250             c *= 8
251             c += n - 0x30
252           else
253             parse_error(_('malformed octal quote'))
254           end
255         end
256         b << c
257       else
258         b << "\\"
259         b << c
260       end
261     else
262       b << c
263     end
264   end
265 end
next_cp() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
304 def next_cp
305   c = 0
306   if @pos < @codepoints.size
307     c = @codepoints[@pos]
308     @pos += 1
309   end
310   c
311 end
next_token() click to toggle source

All methods below belong to the PN lexer

    # File lib/puppet/pops/parser/pn_parser.rb
150 def next_token
151   skip_white
152   s = @pos
153   c = next_cp
154 
155   case @char_types[c]
156   when TYPE_END
157     @token_value = nil
158     @token = TOKEN_END
159 
160   when TYPE_MINUS
161     if @char_types[peek_cp] == TYPE_DIGIT
162       next_token # consume float or integer
163       @token_value = -@token_value
164     else
165       consume_identifier(s)
166     end
167 
168   when TYPE_DIGIT
169     skip_decimal_digits
170     c = peek_cp
171     if c == 0x2e # '.'
172       @pos += 1
173       consume_float(s, c)
174     else
175       @token_value = @text[s..@pos].to_i
176       @token = TOKEN_INT
177     end
178 
179   when TYPE_DELIM
180     @token_value = @text[s]
181     @token = c
182 
183   when TYPE_KEY_START
184     if @char_types[peek_cp] == TYPE_ALPHA
185       next_token
186       @token = TOKEN_KEY
187     else
188       parse_error(_("expected identifier after ':'"))
189     end
190 
191   when TYPE_STRING_START
192     consume_string
193   else
194     consume_identifier(s)
195   end
196 end
parse_array() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
112 def parse_array
113   next_token
114   PN::List.new(parse_elements(TOKEN_RB))
115 end
parse_call() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
130 def parse_call
131   next_token
132   parse_error(_("expected identifier to follow '('")) unless @token == TOKEN_IDENTIFIER
133   name = @token_value
134   next_token
135   PN::Call.new(name, *parse_elements(TOKEN_RP))
136 end
parse_elements(end_token) click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
138 def parse_elements(end_token)
139   elements = []
140   while @token != end_token && @token != TOKEN_END
141     elements << parse_next
142   end
143   parse_error(_("missing '%{token}' to end list") % { token: end_token.chr(Encoding::UTF_8) } ) unless @token == end_token
144   next_token
145   elements
146 end
parse_error(message) click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
 88 def parse_error(message)
 89   file = ''
 90   line = 1
 91   pos = 1
 92   if @locator
 93     file = @locator.file
 94     line = @locator.line_for_offset(@offset)
 95     pos  = @locator.pos_on_line(@offset)
 96   end
 97   @codepoints[0, @pos].each do |c|
 98     if c == 0x09
 99       line += 1
100       pos = 1
101     end
102   end
103   raise Puppet::ParseError.new(message, file, line, pos)
104 end
parse_literal() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
106 def parse_literal
107   pn = PN::Literal.new(@token_value)
108   next_token
109   pn
110 end
parse_map() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
117 def parse_map
118   next_token
119   entries = []
120   while @token != TOKEN_RC && @token != TOKEN_END
121     parse_error(_('map key expected')) unless @token == TOKEN_KEY
122     key = @token_value
123     next_token
124     entries << parse_next.with_name(key)
125   end
126   next_token
127   PN::Map.new(entries)
128 end
parse_next() click to toggle source
   # File lib/puppet/pops/parser/pn_parser.rb
71 def parse_next
72   case @token
73   when TOKEN_LB
74     parse_array
75   when TOKEN_LC
76     parse_map
77   when TOKEN_LP
78     parse_call
79   when TOKEN_BOOL, TOKEN_INT, TOKEN_FLOAT, TOKEN_STRING, TOKEN_NIL
80     parse_literal
81   when TOKEN_END
82     parse_error(_('unexpected end of input'))
83   else
84     parse_error(_('unexpected %{value}' % { value: @token_value }))
85   end
86 end
peek_cp() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
313 def peek_cp
314   @pos < @codepoints.size ? @codepoints[@pos] : 0
315 end
skip_decimal_digits() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
282 def skip_decimal_digits
283   count = 0
284   c = peek_cp
285   if c == 0x2d || c == 0x2b # '-' or '+'
286     @pos += 1
287     c = peek_cp
288   end
289 
290   while @char_types[c] == TYPE_DIGIT do
291     @pos += 1
292     c = peek_cp
293     count += 1
294   end
295   count
296 end
skip_white() click to toggle source
    # File lib/puppet/pops/parser/pn_parser.rb
298 def skip_white
299   while @char_types[peek_cp] == TYPE_WS do
300     @pos += 1
301   end
302 end