OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Generates a syntax tree from a Mojo IDL file.""" | 5 """Generates a syntax tree from a Mojo IDL file.""" |
6 | 6 |
7 import imp | 7 import imp |
8 import os.path | 8 import os.path |
9 import sys | 9 import sys |
10 | 10 |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 value = int(p[1][1:]) | 276 value = int(p[1][1:]) |
277 if value > _MAX_ORDINAL_VALUE: | 277 if value > _MAX_ORDINAL_VALUE: |
278 raise ParseError(self.filename, "Ordinal value %d too large:" % value, | 278 raise ParseError(self.filename, "Ordinal value %d too large:" % value, |
279 lineno=p.lineno(1), | 279 lineno=p.lineno(1), |
280 snippet=self._GetSnippet(p.lineno(1))) | 280 snippet=self._GetSnippet(p.lineno(1))) |
281 p[0] = ast.Ordinal(value, filename=self.filename, lineno=p.lineno(1)) | 281 p[0] = ast.Ordinal(value, filename=self.filename, lineno=p.lineno(1)) |
282 else: | 282 else: |
283 p[0] = ast.Ordinal(None) | 283 p[0] = ast.Ordinal(None) |
284 | 284 |
285 def p_enum(self, p): | 285 def p_enum(self, p): |
286 """enum : ENUM NAME LBRACE enum_field_list RBRACE SEMI""" | 286 """enum : ENUM NAME LBRACE nonempty_enum_value_list RBRACE SEMI |
| 287 | ENUM NAME LBRACE nonempty_enum_value_list COMMA RBRACE SEMI""" |
287 p[0] = ('ENUM', p[2], p[4]) | 288 p[0] = ('ENUM', p[2], p[4]) |
288 | 289 |
289 def p_enum_field_list(self, p): | 290 def p_nonempty_enum_value_list_1(self, p): |
290 """enum_field_list : enum_field | 291 """nonempty_enum_value_list : enum_value""" |
291 | enum_field COMMA enum_field_list | 292 p[0] = [p[1]] |
292 | """ | |
293 if len(p) == 2: | |
294 p[0] = _ListFromConcat(p[1]) | |
295 elif len(p) > 3: | |
296 p[0] = _ListFromConcat(p[1], p[3]) | |
297 | 293 |
298 def p_enum_field(self, p): | 294 def p_nonempty_enum_value_list_2(self, p): |
299 """enum_field : NAME | 295 """nonempty_enum_value_list : nonempty_enum_value_list COMMA enum_value""" |
300 | NAME EQUALS constant""" | 296 p[0] = p[1] |
301 if len(p) == 2: | 297 p[0].append(p[3]) |
302 p[0] = ('ENUM_FIELD', p[1], None) | 298 |
303 else: | 299 def p_enum_value(self, p): |
304 p[0] = ('ENUM_FIELD', p[1], p[3]) | 300 """enum_value : NAME |
| 301 | NAME EQUALS int |
| 302 | NAME EQUALS identifier_wrapped""" |
| 303 p[0] = ('ENUM_VALUE', p[1], p[3] if len(p) == 4 else None) |
305 | 304 |
306 def p_const(self, p): | 305 def p_const(self, p): |
307 """const : CONST typename NAME EQUALS constant SEMI""" | 306 """const : CONST typename NAME EQUALS constant SEMI""" |
308 p[0] = ('CONST', p[2], p[3], p[5]) | 307 p[0] = ('CONST', p[2], p[3], p[5]) |
309 | 308 |
310 def p_constant(self, p): | 309 def p_constant(self, p): |
311 """constant : literal | 310 """constant : literal |
312 | identifier_wrapped""" | 311 | identifier_wrapped""" |
313 p[0] = p[1] | 312 p[0] = p[1] |
314 | 313 |
315 def p_identifier_wrapped(self, p): | 314 def p_identifier_wrapped(self, p): |
316 """identifier_wrapped : identifier""" | 315 """identifier_wrapped : identifier""" |
317 p[0] = ('IDENTIFIER', p[1]) | 316 p[0] = ('IDENTIFIER', p[1]) |
318 | 317 |
319 def p_identifier(self, p): | 318 def p_identifier(self, p): |
320 """identifier : NAME | 319 """identifier : NAME |
321 | NAME DOT identifier""" | 320 | NAME DOT identifier""" |
322 p[0] = ''.join(p[1:]) | 321 p[0] = ''.join(p[1:]) |
323 | 322 |
324 def p_literal(self, p): | 323 def p_literal(self, p): |
325 """literal : number | 324 """literal : int |
| 325 | float |
326 | TRUE | 326 | TRUE |
327 | FALSE | 327 | FALSE |
328 | DEFAULT | 328 | DEFAULT |
329 | STRING_LITERAL""" | 329 | STRING_LITERAL""" |
330 p[0] = p[1] | 330 p[0] = p[1] |
331 | 331 |
332 def p_number(self, p): | 332 def p_int(self, p): |
333 """number : digits | 333 """int : int_const |
334 | PLUS digits | 334 | PLUS int_const |
335 | MINUS digits""" | 335 | MINUS int_const""" |
336 p[0] = ''.join(p[1:]) | 336 p[0] = ''.join(p[1:]) |
337 | 337 |
338 def p_digits(self, p): | 338 def p_int_const(self, p): |
339 """digits : INT_CONST_DEC | 339 """int_const : INT_CONST_DEC |
340 | INT_CONST_HEX | 340 | INT_CONST_HEX""" |
341 | FLOAT_CONST""" | |
342 p[0] = p[1] | 341 p[0] = p[1] |
343 | 342 |
| 343 def p_float(self, p): |
| 344 """float : FLOAT_CONST |
| 345 | PLUS FLOAT_CONST |
| 346 | MINUS FLOAT_CONST""" |
| 347 p[0] = ''.join(p[1:]) |
| 348 |
344 def p_error(self, e): | 349 def p_error(self, e): |
345 if e is None: | 350 if e is None: |
346 # Unexpected EOF. | 351 # Unexpected EOF. |
347 # TODO(vtl): Can we figure out what's missing? | 352 # TODO(vtl): Can we figure out what's missing? |
348 raise ParseError(self.filename, "Unexpected end of file") | 353 raise ParseError(self.filename, "Unexpected end of file") |
349 | 354 |
350 raise ParseError(self.filename, "Unexpected %r:" % e.value, lineno=e.lineno, | 355 raise ParseError(self.filename, "Unexpected %r:" % e.value, lineno=e.lineno, |
351 snippet=self._GetSnippet(e.lineno)) | 356 snippet=self._GetSnippet(e.lineno)) |
352 | 357 |
353 def _GetSnippet(self, lineno): | 358 def _GetSnippet(self, lineno): |
354 return self.source.split('\n')[lineno - 1] | 359 return self.source.split('\n')[lineno - 1] |
355 | 360 |
356 | 361 |
357 def Parse(source, filename): | 362 def Parse(source, filename): |
358 lexer = Lexer(filename) | 363 lexer = Lexer(filename) |
359 parser = Parser(lexer, source, filename) | 364 parser = Parser(lexer, source, filename) |
360 | 365 |
361 lex.lex(object=lexer) | 366 lex.lex(object=lexer) |
362 yacc.yacc(module=parser, debug=0, write_tables=0) | 367 yacc.yacc(module=parser, debug=0, write_tables=0) |
363 | 368 |
364 tree = yacc.parse(source) | 369 tree = yacc.parse(source) |
365 return tree | 370 return tree |
OLD | NEW |