From 95e3b761d93ce95f42edccd15b1b2e81f75193a2 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sat, 19 Mar 2016 05:21:59 -0700 Subject: Fix parsing of extra semi-colons inside structure declarations. Fixes #117 --- pycparser/c_parser.py | 10 +++++++++- tests/test_c_parser.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py index c5a9e68..5c17a74 100644 --- a/pycparser/c_parser.py +++ b/pycparser/c_parser.py @@ -836,7 +836,10 @@ class CParser(PLYParser): """ struct_declaration_list : struct_declaration | struct_declaration_list struct_declaration """ - p[0] = p[1] if len(p) == 2 else p[1] + p[2] + if len(p) == 2: + p[0] = p[1] or [] + else: + p[0] = p[1] + (p[2] or []) def p_struct_declaration_1(self, p): """ struct_declaration : specifier_qualifier_list struct_declarator_list_opt SEMI @@ -890,6 +893,11 @@ class CParser(PLYParser): spec=p[1], decls=[dict(decl=p[2], init=None)]) + def p_struct_declaration_3(self, p): + """ struct_declaration : SEMI + """ + p[0] = None + def p_struct_declarator_list(self, p): """ struct_declarator_list : struct_declarator | struct_declarator_list COMMA struct_declarator diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py index 521f77f..277c750 100755 --- a/tests/test_c_parser.py +++ b/tests/test_c_parser.py @@ -763,6 +763,37 @@ class TestCParser_fundamentals(TestCParser_base): ['Decl', 'heads', ['PtrDecl', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['Node']]]]]]]]]]) + def test_struct_with_extra_semis_inside(self): + s1 = """ + struct { + int a;; + } foo; + """ + s1_ast = self.parse(s1) + self.assertEqual(expand_decl(s1_ast.ext[0]), + ['Decl', 'foo', + ['TypeDecl', ['Struct', None, + [['Decl', 'a', + ['TypeDecl', ['IdentifierType', ['int']]]]]]]]) + + s2 = """ + struct { + int a;;;; + float b, c; + ;; + char d; + } foo; + """ + s2_ast = self.parse(s2) + self.assertEqual(expand_decl(s2_ast.ext[0]), + ['Decl', 'foo', + ['TypeDecl', ['Struct', None, + [['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]], + ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['float']]]], + ['Decl', 'c', ['TypeDecl', ['IdentifierType', ['float']]]], + ['Decl', 'd', + ['TypeDecl', ['IdentifierType', ['char']]]]]]]]) + def test_anonymous_struct_union(self): s1 = """ union -- cgit v1.2.1