diff options
author | Eli Bendersky <eliben@users.noreply.github.com> | 2015-01-17 06:33:28 -0800 |
---|---|---|
committer | Eli Bendersky <eliben@users.noreply.github.com> | 2015-01-17 06:33:28 -0800 |
commit | b036e36318ea41c1a5a484da8c0218cdafccec99 (patch) | |
tree | 06a1b1f455e7a88a7833ed9b1bb8a908a3195846 | |
parent | 497880550069b2a887c70c18cf45cfcd3eaf934d (diff) | |
parent | 4a6afa0587bfb340dad5838f847e71704ea48ea7 (diff) | |
download | pycparser-b036e36318ea41c1a5a484da8c0218cdafccec99.tar.gz |
Merge pull request #64 from necase/array-restrict
Update array dimension grammar
-rw-r--r-- | pycparser/c_parser.py | 56 | ||||
-rw-r--r-- | tests/test_c_parser.py | 16 |
2 files changed, 49 insertions, 23 deletions
diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py index 8e17f03..643b88c 100644 --- a/pycparser/c_parser.py +++ b/pycparser/c_parser.py @@ -983,41 +983,51 @@ class CParser(PLYParser): p[0] = p[2] def p_direct_declarator_3(self, p): - """ direct_declarator : direct_declarator LBRACKET assignment_expression_opt RBRACKET - | direct_declarator LBRACKET STATIC assignment_expression_opt RBRACKET - | direct_declarator LBRACKET CONST assignment_expression_opt RBRACKET - """ - if len(p) > 5: - # Have dimension qualifiers - # Per C99 6.7.5.3 p7 - arr = c_ast.ArrayDecl( - type=None, - dim=p[4], - dim_quals=[p[3]], - coord=p[1].coord) - else: - arr = c_ast.ArrayDecl( - type=None, - dim=p[3], - dim_quals=[], - coord=p[1].coord) + """ direct_declarator : direct_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET + """ + # Accept dimension qualifiers + # Per C99 6.7.5.3 p7 + arr = c_ast.ArrayDecl( + type=None, + dim=p[4], + dim_quals=p[3] if p[3] != None else [], + coord=p[1].coord) + + p[0] = self._type_modify_decl(decl=p[1], modifier=arr) + + def p_direct_declarator_4(self, p): + """ direct_declarator : direct_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET + | direct_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET + """ + # Using slice notation for PLY objects doesn't work in Python 3 for the + # version of PLY embedded with pycparser; see PLY Google Code issue 30. + # Work around that here by listing the two elements separately. + listed_quals = [item if isinstance(item, list) else [item] + for item in [p[3],p[4]]] + dim_quals = [qual for sublist in listed_quals for qual in sublist + if qual is not None] + arr = c_ast.ArrayDecl( + type=None, + dim=p[5], + dim_quals=dim_quals, + coord=p[1].coord) p[0] = self._type_modify_decl(decl=p[1], modifier=arr) # Special for VLAs # - def p_direct_declarator_4(self, p): - """ direct_declarator : direct_declarator LBRACKET TIMES RBRACKET + def p_direct_declarator_5(self, p): + """ direct_declarator : direct_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET """ arr = c_ast.ArrayDecl( type=None, - dim=c_ast.ID(p[3], self._coord(p.lineno(3))), - dim_quals=[], + dim=c_ast.ID(p[4], self._coord(p.lineno(4))), + dim_quals=p[3] if p[3] != None else [], coord=p[1].coord) p[0] = self._type_modify_decl(decl=p[1], modifier=arr) - def p_direct_declarator_5(self, p): + def p_direct_declarator_6(self, p): """ direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN | direct_declarator LPAREN identifier_list_opt RPAREN """ diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py index d0ef741..5c7d723 100644 --- a/tests/test_c_parser.py +++ b/tests/test_c_parser.py @@ -396,6 +396,22 @@ class TestCParser_fundamentals(TestCParser_base): ['TypeDecl', ['IdentifierType', ['int']]]]]], ['TypeDecl', ['IdentifierType', ['int']]]]]) + self.assertEqual(self.get_decl('int zz(int p[restrict][5]);'), + ['Decl', 'zz', + ['FuncDecl', + [['Decl', 'p', ['ArrayDecl', '', ['restrict'], + ['ArrayDecl', '5', [], + ['TypeDecl', ['IdentifierType', ['int']]]]]]], + ['TypeDecl', ['IdentifierType', ['int']]]]]) + + self.assertEqual(self.get_decl('int zz(int p[const restrict static 10][5]);'), + ['Decl', 'zz', + ['FuncDecl', + [['Decl', 'p', ['ArrayDecl', '10', ['const', 'restrict', 'static'], + ['ArrayDecl', '5', [], + ['TypeDecl', ['IdentifierType', ['int']]]]]]], + ['TypeDecl', ['IdentifierType', ['int']]]]]) + def test_qualifiers_storage_specifiers(self): def assert_qs(txt, index, quals, storage): d = self.parse(txt).ext[index] |