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