diff --git a/tools/cc.ebnf b/tools/cc.ebnf index ce235e3..6e6b7bb 100644 --- a/tools/cc.ebnf +++ b/tools/cc.ebnf @@ -55,7 +55,7 @@ initializer_list: "{" [init_list_field ("," init_list_field)* ","? ] "}" ?prec14_expr: prec13_expr | prec2_expr "=" prec14_expr -> assignment - | prec2_expr "+=" prec14_expr + | prec2_expr "+=" prec14_expr -> add_ass | prec2_expr "-=" prec14_expr | prec2_expr "*=" prec14_expr | prec2_expr "/=" prec14_expr @@ -104,7 +104,7 @@ initializer_list: "{" [init_list_field ("," init_list_field)* ","? ] "}" | "-" prec2_expr | "!" prec2_expr -> bool_not | "~" prec2_expr - | "(" type ")" prec2_expr -> cast + | "(" (type | funptr_type) ")" prec2_expr -> cast | "*" prec2_expr -> dereference | "&" prec2_expr -> address_of | "sizeof" prec2_expr -> sizeof @@ -131,6 +131,7 @@ type: type_qualifier* IDENTIFIER | struct_type | type "*" -> pointer ?array_size: INT +funptr_type: type "(" "*" ")" "(" [fun_param ("," fun_param)*] ")" ?type_qualifier: "volatile" -> volatile | "const" -> const diff --git a/tools/cc.py b/tools/cc.py index e058631..8c18f8c 100644 --- a/tools/cc.py +++ b/tools/cc.py @@ -376,6 +376,10 @@ class CcTransform(lark.visitors.Transformer): pointed = children[-1] return PointerType(volatile=volat, pointed=pointed) + def funptr_type(self, children): + ret, *params = children + return FunType(ret=ret, params=params) + def comma_expr(self, children): c1, c2 = children if c1.data == 'comma_expr': @@ -1279,6 +1283,7 @@ class CcInterp(lark.visitors.Interpreter): return f or_ass = _assign_op('_or') + add_ass = _assign_op('add') def _forward_op(self, tree): self.visit_children(tree)