diff options
author | Eli Bendersky <eliben@gmail.com> | 2012-07-06 15:48:57 +0300 |
---|---|---|
committer | Eli Bendersky <eliben@gmail.com> | 2012-07-06 15:48:57 +0300 |
commit | a1da7fd5a98b8a09c5b973cae6b1322ade973c33 (patch) | |
tree | 639cc0a4e54a820e8bc2721cfe935b7b75f7f951 /pycparser/c_parser.py | |
parent | a291586d16a16fbd8c44ccd9e70efed36222c878 (diff) | |
download | pycparser-a1da7fd5a98b8a09c5b973cae6b1322ade973c33.tar.gz |
Make sure the parser remembers the coordinates of simple string types
(such as 'int' or typedef_name) by always keeping them in an IdentifierType
node. This allows to correctly report some errors, which fixes issue 60.
Also cleanup some whitespace & formatting issues, and replace deprecated
unittest methods for python3.
Diffstat (limited to 'pycparser/c_parser.py')
-rw-r--r-- | pycparser/c_parser.py | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py index ee8e157..b91b6ab 100644 --- a/pycparser/c_parser.py +++ b/pycparser/c_parser.py @@ -262,13 +262,13 @@ class CParser(PLYParser): type.quals = decl.quals # The typename is a list of types. If any type in this - # list isn't a simple string type, it must be the only + # list isn't an IdentifierType, it must be the only # type in the list (it's illegal to declare "int enum .." # If all the types are basic, they're collected in the # IdentifierType holder. # for tn in typename: - if not isinstance(tn, str): + if not isinstance(tn, c_ast.IdentifierType): if len(typename) > 1: self._parse_error( "Invalid multiple types specified", tn.coord) @@ -276,7 +276,11 @@ class CParser(PLYParser): type.type = tn return decl - type.type = c_ast.IdentifierType(typename) + # At this point, we know that typename is a list of IdentifierType + # nodes. Concatenate all the names into a single list. + type.type = c_ast.IdentifierType( + [name for id in typename for name in id.names], + coord=typename[0].coord) return decl def _add_declaration_specifier(self, declspec, newspec, kind): @@ -451,25 +455,26 @@ class CParser(PLYParser): # Then it's a declaration of a struct / enum tag, # without an actual declarator. # - type = spec['type'] - if len(type) > 1: + ty = spec['type'] + if len(ty) > 1: coord = '?' - for t in type: + for t in ty: if hasattr(t, 'coord'): coord = t.coord break - self._parse_error('Multiple type specifiers with a type tag', coord) + self._parse_error('Multiple type specifiers with a type tag', + coord) decl = c_ast.Decl( name=None, quals=spec['qual'], storage=spec['storage'], funcspec=spec['function'], - type=type[0], + type=ty[0], init=None, bitsize=None, - coord=type[0].coord) + coord=ty[0].coord) decls = [decl] else: for decl, init in p[2] or []: @@ -581,7 +586,11 @@ class CParser(PLYParser): | _COMPLEX | SIGNED | UNSIGNED - | typedef_name + """ + p[0] = c_ast.IdentifierType([p[1]], coord=self._coord(p.lineno(1))) + + def p_type_specifier_2(self, p): + """ type_specifier : typedef_name | enum_specifier | struct_or_union_specifier """ @@ -1161,7 +1170,7 @@ class CParser(PLYParser): def p_typedef_name(self, p): """ typedef_name : TYPEID """ - p[0] = p[1] + p[0] = c_ast.IdentifierType([p[1]], coord=self._coord(p.lineno(1))) def p_assignment_expression(self, p): """ assignment_expression : conditional_expression |