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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 # then we name the functions |p_foo_bar_N| (for left-hand-side |foo_bar|), | 79 # then we name the functions |p_foo_bar_N| (for left-hand-side |foo_bar|), |
80 # where N is a number (numbered starting from 1). Note that using multiple | 80 # where N is a number (numbered starting from 1). Note that using multiple |
81 # functions is actually more efficient than having single functions handle | 81 # functions is actually more efficient than having single functions handle |
82 # multiple rules (and, e.g., distinguishing them by examining |len(p)|). | 82 # multiple rules (and, e.g., distinguishing them by examining |len(p)|). |
83 # | 83 # |
84 # It's also possible to have a function handling multiple rules with different | 84 # It's also possible to have a function handling multiple rules with different |
85 # left-hand-sides. We do not do this. | 85 # left-hand-sides. We do not do this. |
86 # | 86 # |
87 # See http://www.dabeaz.com/ply/ply.html#ply_nn25 for more details. | 87 # See http://www.dabeaz.com/ply/ply.html#ply_nn25 for more details. |
88 | 88 |
| 89 # TODO(vtl): Get rid of this ('MODULE', ...) stuff and replace it with an |
| 90 # ast.Mojom node. This will require putting the imports into a list (say |
| 91 # ast.ImportList). |
| 92 # TODO(vtl): Get rid of the braces in the module "statement". (Consider |
| 93 # renaming "module" -> "package".) |
89 def p_root(self, p): | 94 def p_root(self, p): |
90 """root : import root | 95 """root : import root |
91 | module | 96 | module LBRACE definition_list RBRACE |
92 | definition_list""" | 97 | definition_list""" |
93 if len(p) > 2: | 98 if len(p) == 3: |
94 p[0] = _ListFromConcat(p[1], p[2]) | 99 p[0] = p[2] |
| 100 p[0].insert(0, p[1]) |
| 101 elif len(p) == 5: |
| 102 p[0] = [('MODULE', p[1].name, p[1].attribute_list, p[3])] |
95 else: | 103 else: |
96 # Generator expects a module. If one wasn't specified insert one with an | 104 p[0] = [('MODULE', None, None, p[1])] |
97 # empty name. | |
98 if p[1][0] != 'MODULE': | |
99 p[0] = [('MODULE', None, None, p[1])] | |
100 else: | |
101 p[0] = [p[1]] | |
102 | 105 |
103 def p_import(self, p): | 106 def p_import(self, p): |
104 """import : IMPORT STRING_LITERAL""" | 107 """import : IMPORT STRING_LITERAL""" |
105 # 'eval' the literal to strip the quotes. | 108 # 'eval' the literal to strip the quotes. |
106 p[0] = ('IMPORT', eval(p[2])) | 109 p[0] = ('IMPORT', eval(p[2])) |
107 | 110 |
108 def p_module(self, p): | 111 def p_module(self, p): |
109 """module : attribute_section MODULE identifier_wrapped LBRACE \ | 112 """module : attribute_section MODULE identifier_wrapped """ |
110 definition_list RBRACE""" | 113 p[0] = ast.Module(p[3], p[1], filename=self.filename, lineno=p.lineno(2)) |
111 p[0] = ('MODULE', p[3], p[1], p[5]) | |
112 | 114 |
113 def p_definition_list(self, p): | 115 def p_definition_list(self, p): |
114 """definition_list : definition definition_list | 116 """definition_list : definition definition_list |
115 | """ | 117 | """ |
116 if len(p) > 1: | 118 if len(p) > 1: |
117 p[0] = _ListFromConcat(p[1], p[2]) | 119 p[0] = _ListFromConcat(p[1], p[2]) |
118 | 120 |
119 def p_definition(self, p): | 121 def p_definition(self, p): |
120 """definition : struct | 122 """definition : struct |
121 | interface | 123 | interface |
122 | enum | 124 | enum |
123 | const""" | 125 | const""" |
124 p[0] = p[1] | 126 p[0] = p[1] |
125 | 127 |
126 def p_attribute_section(self, p): | 128 def p_attribute_section_1(self, p): |
127 """attribute_section : LBRACKET attribute_list RBRACKET | 129 """attribute_section : """ |
128 | """ | 130 p[0] = None |
129 if len(p) > 3: | 131 |
130 p[0] = p[2] | 132 def p_attribute_section_2(self, p): |
| 133 """attribute_section : LBRACKET attribute_list RBRACKET""" |
| 134 p[0] = p[2] |
131 | 135 |
132 def p_attribute_list_1(self, p): | 136 def p_attribute_list_1(self, p): |
133 """attribute_list : """ | 137 """attribute_list : """ |
134 p[0] = ast.AttributeList() | 138 p[0] = ast.AttributeList() |
135 | 139 |
136 def p_attribute_list_2(self, p): | 140 def p_attribute_list_2(self, p): |
137 """attribute_list : nonempty_attribute_list""" | 141 """attribute_list : nonempty_attribute_list""" |
138 p[0] = p[1] | 142 p[0] = p[1] |
139 | 143 |
140 def p_nonempty_attribute_list_1(self, p): | 144 def p_nonempty_attribute_list_1(self, p): |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 | 367 |
364 def Parse(source, filename): | 368 def Parse(source, filename): |
365 lexer = Lexer(filename) | 369 lexer = Lexer(filename) |
366 parser = Parser(lexer, source, filename) | 370 parser = Parser(lexer, source, filename) |
367 | 371 |
368 lex.lex(object=lexer) | 372 lex.lex(object=lexer) |
369 yacc.yacc(module=parser, debug=0, write_tables=0) | 373 yacc.yacc(module=parser, debug=0, write_tables=0) |
370 | 374 |
371 tree = yacc.parse(source) | 375 tree = yacc.parse(source) |
372 return tree | 376 return tree |
OLD | NEW |