| Index: mojo/public/tools/bindings/pylib/mojom/parse/parser.py
|
| diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
|
| index 35070efe99298d29cd8a53ec573eb27499f384c1..e5269c7fd5f7fbbb942c699692396419a79c8a4b 100644
|
| --- a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
|
| +++ b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
|
| @@ -71,41 +71,47 @@ class Parser(object):
|
| # renaming "module" -> "package".) Then we'll be able to have a single rule
|
| # for root (by making module "optional").
|
| def p_root_1(self, p):
|
| - """root : import_list module LBRACE definition_list RBRACE"""
|
| - p[0] = ast.Mojom(p[2], p[1], p[4])
|
| + """root : """
|
| + p[0] = ast.Mojom(None, ast.ImportList(), [])
|
|
|
| def p_root_2(self, p):
|
| - """root : import_list definition_list"""
|
| - p[0] = ast.Mojom(None, p[1], p[2])
|
| -
|
| - def p_import_list_1(self, p):
|
| - """import_list : """
|
| - p[0] = ast.ImportList()
|
| + """root : root module"""
|
| + if p[1].module is not None:
|
| + raise ParseError(self.filename,
|
| + "Multiple \"module\" statements not allowed:",
|
| + p[2].lineno, snippet=self._GetSnippet(p[2].lineno))
|
| + if p[1].import_list.items or p[1].definition_list:
|
| + raise ParseError(
|
| + self.filename,
|
| + "\"module\" statements must precede imports and definitions:",
|
| + p[2].lineno, snippet=self._GetSnippet(p[2].lineno))
|
| + p[0] = p[1]
|
| + p[0].module = p[2]
|
| +
|
| + def p_root_3(self, p):
|
| + """root : root import"""
|
| + if p[1].definition_list:
|
| + raise ParseError(self.filename,
|
| + "\"import\" statements must precede definitions:",
|
| + p[2].lineno, snippet=self._GetSnippet(p[2].lineno))
|
| + p[0] = p[1]
|
| + p[0].import_list.Append(p[2])
|
|
|
| - def p_import_list_2(self, p):
|
| - """import_list : import_list import"""
|
| + def p_root_4(self, p):
|
| + """root : root definition"""
|
| p[0] = p[1]
|
| - p[0].Append(p[2])
|
| + p[0].definition_list.append(p[2])
|
|
|
| def p_import(self, p):
|
| """import : IMPORT STRING_LITERAL SEMI"""
|
| # 'eval' the literal to strip the quotes.
|
| # TODO(vtl): This eval is dubious. We should unquote/unescape ourselves.
|
| - p[0] = ast.Import(eval(p[2]))
|
| + p[0] = ast.Import(eval(p[2]), filename=self.filename, lineno=p.lineno(2))
|
|
|
| def p_module(self, p):
|
| - """module : attribute_section MODULE identifier_wrapped """
|
| + """module : attribute_section MODULE identifier_wrapped SEMI"""
|
| p[0] = ast.Module(p[3], p[1], filename=self.filename, lineno=p.lineno(2))
|
|
|
| - def p_definition_list(self, p):
|
| - """definition_list : definition definition_list
|
| - | """
|
| - if len(p) > 1:
|
| - p[0] = p[2]
|
| - p[0].insert(0, p[1])
|
| - else:
|
| - p[0] = []
|
| -
|
| def p_definition(self, p):
|
| """definition : struct
|
| | interface
|
| @@ -271,7 +277,7 @@ class Parser(object):
|
| """fixed_array : ARRAY LANGLE typename COMMA INT_CONST_DEC RANGLE"""
|
| value = int(p[5])
|
| if value == 0 or value > _MAX_ARRAY_SIZE:
|
| - raise ParseError(self.filename, "Fixed array size %d invalid" % value,
|
| + raise ParseError(self.filename, "Fixed array size %d invalid:" % value,
|
| lineno=p.lineno(5),
|
| snippet=self._GetSnippet(p.lineno(5)))
|
| p[0] = p[3] + "[" + p[5] + "]"
|
|
|