| 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 # | 64 # |
| 65 # It's also possible to have a function handling multiple rules with different | 65 # It's also possible to have a function handling multiple rules with different |
| 66 # left-hand-sides. We do not do this. | 66 # left-hand-sides. We do not do this. |
| 67 # | 67 # |
| 68 # See http://www.dabeaz.com/ply/ply.html#ply_nn25 for more details. | 68 # See http://www.dabeaz.com/ply/ply.html#ply_nn25 for more details. |
| 69 | 69 |
| 70 # TODO(vtl): Get rid of the braces in the module "statement". (Consider | 70 # TODO(vtl): Get rid of the braces in the module "statement". (Consider |
| 71 # renaming "module" -> "package".) Then we'll be able to have a single rule | 71 # renaming "module" -> "package".) Then we'll be able to have a single rule |
| 72 # for root (by making module "optional"). | 72 # for root (by making module "optional"). |
| 73 def p_root_1(self, p): | 73 def p_root_1(self, p): |
| 74 """root : import_list module LBRACE definition_list RBRACE""" | 74 """root : """ |
| 75 p[0] = ast.Mojom(p[2], p[1], p[4]) | 75 p[0] = ast.Mojom(None, ast.ImportList(), []) |
| 76 | 76 |
| 77 def p_root_2(self, p): | 77 def p_root_2(self, p): |
| 78 """root : import_list definition_list""" | 78 """root : root module""" |
| 79 p[0] = ast.Mojom(None, p[1], p[2]) | 79 if p[1].module is not None: |
| 80 raise ParseError(self.filename, |
| 81 "Multiple \"module\" statements not allowed:", |
| 82 p[2].lineno, snippet=self._GetSnippet(p[2].lineno)) |
| 83 if p[1].import_list.items or p[1].definition_list: |
| 84 raise ParseError( |
| 85 self.filename, |
| 86 "\"module\" statements must precede imports and definitions:", |
| 87 p[2].lineno, snippet=self._GetSnippet(p[2].lineno)) |
| 88 p[0] = p[1] |
| 89 p[0].module = p[2] |
| 80 | 90 |
| 81 def p_import_list_1(self, p): | 91 def p_root_3(self, p): |
| 82 """import_list : """ | 92 """root : root import""" |
| 83 p[0] = ast.ImportList() | 93 if p[1].definition_list: |
| 94 raise ParseError(self.filename, |
| 95 "\"import\" statements must precede definitions:", |
| 96 p[2].lineno, snippet=self._GetSnippet(p[2].lineno)) |
| 97 p[0] = p[1] |
| 98 p[0].import_list.Append(p[2]) |
| 84 | 99 |
| 85 def p_import_list_2(self, p): | 100 def p_root_4(self, p): |
| 86 """import_list : import_list import""" | 101 """root : root definition""" |
| 87 p[0] = p[1] | 102 p[0] = p[1] |
| 88 p[0].Append(p[2]) | 103 p[0].definition_list.append(p[2]) |
| 89 | 104 |
| 90 def p_import(self, p): | 105 def p_import(self, p): |
| 91 """import : IMPORT STRING_LITERAL SEMI""" | 106 """import : IMPORT STRING_LITERAL SEMI""" |
| 92 # 'eval' the literal to strip the quotes. | 107 # 'eval' the literal to strip the quotes. |
| 93 # TODO(vtl): This eval is dubious. We should unquote/unescape ourselves. | 108 # TODO(vtl): This eval is dubious. We should unquote/unescape ourselves. |
| 94 p[0] = ast.Import(eval(p[2])) | 109 p[0] = ast.Import(eval(p[2]), filename=self.filename, lineno=p.lineno(2)) |
| 95 | 110 |
| 96 def p_module(self, p): | 111 def p_module(self, p): |
| 97 """module : attribute_section MODULE identifier_wrapped """ | 112 """module : attribute_section MODULE identifier_wrapped SEMI""" |
| 98 p[0] = ast.Module(p[3], p[1], filename=self.filename, lineno=p.lineno(2)) | 113 p[0] = ast.Module(p[3], p[1], filename=self.filename, lineno=p.lineno(2)) |
| 99 | 114 |
| 100 def p_definition_list(self, p): | |
| 101 """definition_list : definition definition_list | |
| 102 | """ | |
| 103 if len(p) > 1: | |
| 104 p[0] = p[2] | |
| 105 p[0].insert(0, p[1]) | |
| 106 else: | |
| 107 p[0] = [] | |
| 108 | |
| 109 def p_definition(self, p): | 115 def p_definition(self, p): |
| 110 """definition : struct | 116 """definition : struct |
| 111 | interface | 117 | interface |
| 112 | enum | 118 | enum |
| 113 | const""" | 119 | const""" |
| 114 p[0] = p[1] | 120 p[0] = p[1] |
| 115 | 121 |
| 116 def p_attribute_section_1(self, p): | 122 def p_attribute_section_1(self, p): |
| 117 """attribute_section : """ | 123 """attribute_section : """ |
| 118 p[0] = None | 124 p[0] = None |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 p[0] = "handle<" + p[3] + ">" | 270 p[0] = "handle<" + p[3] + ">" |
| 265 | 271 |
| 266 def p_array(self, p): | 272 def p_array(self, p): |
| 267 """array : ARRAY LANGLE typename RANGLE""" | 273 """array : ARRAY LANGLE typename RANGLE""" |
| 268 p[0] = p[3] + "[]" | 274 p[0] = p[3] + "[]" |
| 269 | 275 |
| 270 def p_fixed_array(self, p): | 276 def p_fixed_array(self, p): |
| 271 """fixed_array : ARRAY LANGLE typename COMMA INT_CONST_DEC RANGLE""" | 277 """fixed_array : ARRAY LANGLE typename COMMA INT_CONST_DEC RANGLE""" |
| 272 value = int(p[5]) | 278 value = int(p[5]) |
| 273 if value == 0 or value > _MAX_ARRAY_SIZE: | 279 if value == 0 or value > _MAX_ARRAY_SIZE: |
| 274 raise ParseError(self.filename, "Fixed array size %d invalid" % value, | 280 raise ParseError(self.filename, "Fixed array size %d invalid:" % value, |
| 275 lineno=p.lineno(5), | 281 lineno=p.lineno(5), |
| 276 snippet=self._GetSnippet(p.lineno(5))) | 282 snippet=self._GetSnippet(p.lineno(5))) |
| 277 p[0] = p[3] + "[" + p[5] + "]" | 283 p[0] = p[3] + "[" + p[5] + "]" |
| 278 | 284 |
| 279 def p_associative_array(self, p): | 285 def p_associative_array(self, p): |
| 280 """associative_array : MAP LANGLE identifier COMMA typename RANGLE""" | 286 """associative_array : MAP LANGLE identifier COMMA typename RANGLE""" |
| 281 p[0] = p[5] + "{" + p[3] + "}" | 287 p[0] = p[5] + "{" + p[3] + "}" |
| 282 | 288 |
| 283 def p_interfacerequest(self, p): | 289 def p_interfacerequest(self, p): |
| 284 """interfacerequest : identifier AMP""" | 290 """interfacerequest : identifier AMP""" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 | 385 |
| 380 def Parse(source, filename): | 386 def Parse(source, filename): |
| 381 lexer = Lexer(filename) | 387 lexer = Lexer(filename) |
| 382 parser = Parser(lexer, source, filename) | 388 parser = Parser(lexer, source, filename) |
| 383 | 389 |
| 384 lex.lex(object=lexer) | 390 lex.lex(object=lexer) |
| 385 yacc.yacc(module=parser, debug=0, write_tables=0) | 391 yacc.yacc(module=parser, debug=0, write_tables=0) |
| 386 | 392 |
| 387 tree = yacc.parse(source) | 393 tree = yacc.parse(source) |
| 388 return tree | 394 return tree |
| OLD | NEW |