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