Skip to content

Commit cde1128

Browse files
WIP
1 parent 910ebea commit cde1128

File tree

2 files changed

+61
-88
lines changed

2 files changed

+61
-88
lines changed

pycparserext/ext_c_parser.py

Lines changed: 56 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import division
22

3+
import itertools
4+
35
import pycparser.c_parser
46
import pycparser.c_ast as c_ast
57
try:
@@ -290,21 +292,40 @@ class UnionExt(_StructUnionEnumMixin, c_ast.Union):
290292
# {{{ attributes
291293

292294
class _AttributesMixin(object):
295+
296+
def _merge_attributes(self, p, attrs):
297+
print(999,attrs)
298+
attrs = [
299+
attr
300+
for attr in attrs
301+
if attr is not None
302+
]
303+
if attrs:
304+
fst, *others = attrs
305+
fst.exprs.extend(itertools.chain.from_iterable(
306+
attr.exprs
307+
for attr in others
308+
))
309+
return fst
310+
else:
311+
return c_ast.ExprList([], self._coord(p.lineno(1)))
312+
293313
def p_attributes_opt_1(self, p):
294314
""" attributes_opt : attribute_decl attributes_opt
295315
"""
296-
p[1].exprs.extend(p[2].exprs)
297-
p[0] = p[1]
316+
print(991)
317+
p[0] = self._merge_attributes(p, (p[1], p[2]))
298318

299319
def p_attributes_opt_2(self, p):
300320
""" attributes_opt : empty
301321
"""
302-
p[0] = c_ast.ExprList([], self._coord(p.lineno(1)))
322+
p[0] = self._merge_attributes(p, [])
303323

304324
def p_attribute_decl(self, p):
305325
""" attribute_decl : __ATTRIBUTE__ LPAREN LPAREN attribute_list RPAREN RPAREN
306326
| __ATTRIBUTE LPAREN LPAREN attribute_list RPAREN RPAREN
307327
"""
328+
print(992)
308329
p[0] = p[4]
309330

310331
def p_attribute_list_1(self, p):
@@ -315,8 +336,7 @@ def p_attribute_list_1(self, p):
315336
def p_attribute_list_2(self, p):
316337
""" attribute_list : attribute_list COMMA attribute
317338
"""
318-
p[1].exprs.append(p[3])
319-
p[0] = p[1]
339+
p[0] = self._merge_attributes(p, (p[1], p[3]))
320340

321341
def p_attribute_1(self, p):
322342
""" attribute : CONST
@@ -331,6 +351,7 @@ def p_attribute_3(self, p):
331351
def p_function_specifier_attr(self, p):
332352
""" function_specifier : attribute_decl
333353
"""
354+
print(993)
334355
p[0] = AttributeSpecifier(p[1])
335356

336357
# }}}
@@ -421,6 +442,7 @@ class _AsmAndAttributesMixin(_AsmMixin, _AttributesMixin):
421442
def p_xxx_declarator_1(self, p):
422443
""" xxx_declarator : direct_xxx_declarator asm_label_opt attributes_opt
423444
"""
445+
print(555, p[3])
424446
if p[2] or p[3].exprs:
425447
if isinstance(p[1], (c_ast.ArrayDecl, c_ast.FuncDecl)):
426448
decl_ext = to_decl_ext(p[1].type)
@@ -450,6 +472,7 @@ def p_xxx_declarator_2(self, p):
450472
| pointer attributes_opt direct_xxx_declarator \
451473
asm_label_opt
452474
"""
475+
print(666)
453476
if hasattr(p[4], "exprs"):
454477
attr_decl = p[4]
455478
asm_label = p[3]
@@ -490,6 +513,7 @@ def p_direct_xxx_declarator_6(self, p):
490513
LPAREN identifier_list_opt RPAREN \
491514
asm_label_opt attributes_opt
492515
"""
516+
print(777)
493517
func = FuncDeclExt(
494518
args=p[3],
495519
type=None,
@@ -503,6 +527,7 @@ def p_direct_abstract_declarator_6(self, p):
503527
""" direct_abstract_declarator : direct_abstract_declarator \
504528
LPAREN parameter_type_list_opt RPAREN asm_label_opt attributes_opt
505529
"""
530+
print(888)
506531
func = FuncDeclExt(
507532
args=p[3],
508533
type=None,
@@ -520,149 +545,92 @@ def _select_struct_union_class(self, token):
520545
}[klass]
521546

522547
def p_struct_or_union_specifier_with_attr_1(self, p):
523-
""" struct_or_union_specifier : struct_or_union ID brace_open brace_close attributes_opt
524-
| struct_or_union TYPEID brace_open brace_close attributes_opt
525-
"""
526-
klass = self._select_struct_union_class(p[1])
527-
p[0] = klass(
528-
name=p[2],
529-
decls=[],
530-
attributes=p[5],
531-
coord=self._token_coord(p, 2))
532-
533-
def p_struct_or_union_specifier_with_attr_2(self, p):
534-
""" struct_or_union_specifier : struct_or_union attributes_opt ID brace_open brace_close
535-
| struct_or_union attributes_opt TYPEID brace_open brace_close
548+
""" struct_or_union_specifier : struct_or_union attributes_opt ID brace_open brace_close attributes_opt
549+
| struct_or_union attributes_opt TYPEID brace_open brace_close attributes_opt
536550
"""
551+
print(111)
537552
klass = self._select_struct_union_class(p[1])
538-
p[0] = klass(
539-
name=p[3],
540-
decls=[],
541-
attributes=p[2],
542-
coord=self._token_coord(p, 3))
553+
attrs = self._merge_attributes(p, (p[2], p[6]))
543554

544-
def p_struct_or_union_specifier_with_attr_3(self, p):
545-
""" struct_or_union_specifier : attributes_opt struct_or_union ID brace_open brace_close
546-
| attributes_opt struct_or_union TYPEID brace_open brace_close
547-
"""
548-
klass = self._select_struct_union_class(p[2])
549555
p[0] = klass(
550556
name=p[3],
551557
decls=[],
552-
attributes=p[1],
558+
attributes=attrs,
553559
coord=self._token_coord(p, 3))
554560

555-
def p_struct_or_union_specifier_with_attr_4(self, p):
556-
""" struct_or_union_specifier : struct_or_union ID brace_open struct_declaration_list brace_close attributes_opt
557-
| struct_or_union TYPEID brace_open struct_declaration_list brace_close attributes_opt
558-
"""
559-
klass = self._select_struct_union_class(p[1])
560-
p[0] = klass(
561-
name=p[2],
562-
decls=p[4],
563-
attributes=p[6],
564-
coord=self._token_coord(p, 2))
565-
566561
def p_struct_or_union_specifier_with_attr_5(self, p):
567-
""" struct_or_union_specifier : struct_or_union attributes_opt ID brace_open struct_declaration_list brace_close
568-
| struct_or_union attributes_opt TYPEID brace_open struct_declaration_list brace_close
562+
""" struct_or_union_specifier : struct_or_union attributes_opt ID brace_open struct_declaration_list brace_close attributes_opt
563+
| struct_or_union attributes_opt TYPEID brace_open struct_declaration_list brace_close attributes_opt
569564
"""
565+
print(222)
570566
klass = self._select_struct_union_class(p[1])
571-
p[0] = klass(
572-
name=p[3],
573-
decls=p[5],
574-
attributes=p[2],
575-
coord=self._token_coord(p, 3))
567+
attrs = self._merge_attributes(p, (p[2], p[7]))
576568

577-
def p_struct_or_union_specifier_with_attr_6(self, p):
578-
""" struct_or_union_specifier : attributes_opt struct_or_union ID brace_open struct_declaration_list brace_close
579-
| attributes_opt struct_or_union TYPEID brace_open struct_declaration_list brace_close
580-
"""
581-
klass = self._select_struct_union_class(p[2])
582569
p[0] = klass(
583570
name=p[3],
584571
decls=p[5],
585-
attributes=p[1],
572+
attributes=attrs,
586573
coord=self._token_coord(p, 3))
587574

588575
def p_struct_or_union_specifier_with_attr_7(self, p):
589-
""" struct_or_union_specifier : struct_or_union attributes_opt ID
590-
| struct_or_union attributes_opt TYPEID
576+
""" struct_or_union_specifier : struct_or_union attributes_opt ID attributes_opt
577+
| struct_or_union attributes_opt TYPEID attributes_opt
591578
"""
579+
print(333)
592580
klass = self._select_struct_union_class(p[1])
581+
attrs = self._merge_attributes(p, (p[2], p[4]))
582+
593583
# None means no list of members
594584
p[0] = klass(
595585
name=p[3],
596586
decls=None,
597-
attributes=p[2],
587+
attributes=attrs,
598588
coord=self._token_coord(p, 3))
599589

600590
def p_struct_or_union_specifier_with_attr_8(self, p):
601-
""" struct_or_union_specifier : struct_or_union brace_open brace_close attributes_opt
591+
""" struct_or_union_specifier : struct_or_union attributes_opt brace_open brace_close attributes_opt
602592
"""
593+
print(444)
603594
klass = self._select_struct_union_class(p[1])
604-
p[0] = klass(
605-
name=None,
606-
decls=[],
607-
attributes=p[4],
608-
coord=self._token_coord(p, 2))
595+
attrs = self._merge_attributes(p, (p[2], p[5]))
609596

610-
def p_struct_or_union_specifier_with_attr_9(self, p):
611-
""" struct_or_union_specifier : struct_or_union attributes_opt brace_open brace_close
612-
"""
613-
klass = self._select_struct_union_class(p[1])
614597
p[0] = klass(
615598
name=None,
616599
decls=[],
617-
attributes=p[2],
618-
coord=self._token_coord(p, 3))
619-
620-
def p_struct_or_union_specifier_with_attr_10(self, p):
621-
""" struct_or_union_specifier : struct_or_union brace_open struct_declaration_list brace_close attributes_opt
622-
"""
623-
klass = self._select_struct_union_class(p[1])
624-
p[0] = klass(
625-
name=None,
626-
decls=p[3],
627-
attributes=p[5],
628-
coord=self._token_coord(p, 2))
629-
630-
def p_struct_or_union_specifier_with_attr_11(self, p):
631-
""" struct_or_union_specifier : struct_or_union attributes_opt brace_open struct_declaration_list brace_close
632-
"""
633-
klass = self._select_struct_union_class(p[1])
634-
p[0] = klass(
635-
name=None,
636-
decls=p[4],
637-
attributes=p[2],
600+
attributes=attrs,
638601
coord=self._token_coord(p, 3))
639602

640603
def p_enum_specifier_with_attr_1(self, p):
641604
""" enum_specifier : ENUM attributes_opt ID
642605
| ENUM attributes_opt TYPEID
643606
"""
607+
print(991)
644608
p[0] = EnumExt(p[3], None, self._token_coord(p, 1), attributes=p[2])
645609

646610
def p_enum_specifier_with_attr_2(self, p):
647611
""" enum_specifier : ENUM attributes_opt brace_open enumerator_list brace_close
648612
"""
613+
print(992)
649614
p[0] = EnumExt(None, p[4], self._token_coord(p, 1), attributes=p[2])
650615

651616
def p_enum_specifier_with_attr_3(self, p):
652617
""" enum_specifier : ENUM brace_open enumerator_list brace_close attributes_opt
653618
"""
619+
print(993)
654620
p[0] = EnumExt(None, p[3], self._token_coord(p, 1), attributes=p[5])
655621

656622
def p_enum_specifier_with_attr_4(self, p):
657623
""" enum_specifier : ENUM attributes_opt ID brace_open enumerator_list brace_close
658624
| ENUM attributes_opt TYPEID brace_open enumerator_list brace_close
659625
"""
626+
print(994)
660627
p[0] = EnumExt(p[3], p[5], self._token_coord(p, 1), attributes=p[2])
661628

662629
def p_enum_specifier_with_attr_5(self, p):
663630
""" enum_specifier : ENUM ID brace_open enumerator_list brace_close attributes_opt
664631
| ENUM TYPEID brace_open enumerator_list brace_close attributes_opt
665632
"""
633+
print(995)
666634
p[0] = EnumExt(p[2], p[4], self._token_coord(p, 1), attributes=p[6])
667635

668636
def p_enumerator(self, p):
@@ -671,6 +639,7 @@ def p_enumerator(self, p):
671639
| ID attributes_opt
672640
| ID attributes_opt EQUALS constant_expression
673641
"""
642+
print(996)
674643
if len(p) in (2, 4):
675644
super().p_enumerator(p)
676645
else:

test/test_pycparserext.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,14 @@ def test_empty_struct_declaration_attr_2():
386386
typedef struct Foo {
387387
} __attribute__((packed)) Foo_t;
388388
"""
389+
src = """
390+
typedef struct __attribute__((packed)) Foo {
391+
} Foo_t;
392+
"""
389393

390394
from pycparserext.ext_c_parser import GnuCParser
391395
p = GnuCParser()
392-
ast = p.parse(src)
396+
ast = p.parse(src, debuglevel=1)
393397
ast.show()
394398

395399
from pycparserext.ext_c_generator import GnuCGenerator

0 commit comments

Comments
 (0)