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

Public Instance Methods

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

Private Instance Methods

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

All methods below belong to the PN lexer

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