%token IDENTIFIER I_CONSTANT F_CONSTANT STRING_LITERAL FUNC_NAME SIZEOF %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN %token XOR_ASSIGN OR_ASSIGN %token TYPEDEF_NAME ENUMERATION_CONSTANT %token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE %token CONST RESTRICT VOLATILE %token BOOL CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE VOID %token COMPLEX IMAGINARY %token STRUCT UNION ENUM ELLIPSIS %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN %token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL %start translation_unit_opt %expect 2 %{ import t_def %} %% primary_expression : (?E{t_def.AST.ExpressionIdentifier}IDENTIFIER) | constant | string | '(' expression ')' | generic_selection ; constant : I_CONSTANT | F_CONSTANT | ENUMERATION_CONSTANT ; enumeration_constant : IDENTIFIER ; string : STRING_LITERAL | (?E{t_def.AST.ExpressionFunctionName}FUNC_NAME) ; generic_selection : (?E{t_def.AST.GenericSelection}GENERIC '(' assignment_expression ',' (?E{t_def.AST.GenericAssociationList}generic_association_list) ')') ; generic_association_list : generic_association | generic_association_list ',' generic_association ; generic_association : (?E{t_def.AST.GenericAssociation}type_name_or_default ':' assignment_expression) ; type_name_or_default : type_name | (?E{t_def.AST.DefaultTypeName}DEFAULT) ; postfix_expression : primary_expression | (?E{t_def.AST.ExpressionIndex}postfix_expression '[' expression ']') | (?E{t_def.AST.ExpressionCall}postfix_expression '(' (?E{t_def.AST.ArgumentExpressionList}argument_expression_list_opt) ')') | (?E{t_def.AST.ExpressionField}postfix_expression '.' IDENTIFIER) | (?E{t_def.AST.ExpressionFieldDereference}postfix_expression PTR_OP IDENTIFIER) | (?E{t_def.AST.ExpressionPostIncrement, unary_operator = '++', postfix = True}postfix_expression INC_OP) | (?E{t_def.AST.ExpressionPostDecrement, unary_operator = '--', postfix = True}postfix_expression DEC_OP) | (?E{t_def.AST.ExpressionArray}'(' type_name ')' '{' (?E{t_def.AST.DesignatorInitializerList}designator_initializer_list_comma_opt) '}') ; argument_expression_list_opt : | argument_expression_list ; argument_expression_list : assignment_expression | argument_expression_list ',' assignment_expression ; unary_expression : postfix_expression | (?E{t_def.AST.ExpressionPreIncrement, unary_operator = '++'}INC_OP unary_expression) | (?E{t_def.AST.ExpressionPreDecrement, unary_operator = '--'}DEC_OP unary_expression) | (?E{t_def.AST.ExpressionAddressOf, unary_operator = '&'}'&' cast_expression) | (?E{t_def.AST.ExpressionDereference, unary_operator = '*'}'*' cast_expression) | (?E{t_def.AST.ExpressionPlus, unary_operator = '+'}'+' cast_expression) | (?E{t_def.AST.ExpressionMinus, unary_operator = '-'}'-' cast_expression) | (?E{t_def.AST.ExpressionBitwiseNot, unary_operator = '~'}'~' cast_expression) | (?E{t_def.AST.ExpressionLogicalNot, unary_operator = 'not '}'!' cast_expression) | (?E{t_def.AST.ExpressionSizeOfExpression, unary_operator = 'sizeof '}SIZEOF unary_expression) | (?E{t_def.AST.ExpressionSizeOfType}SIZEOF '(' type_name ')') | (?E{t_def.AST.ExpressionAlignOfType}ALIGNOF '(' type_name ')') ; cast_expression : unary_expression | (?E{t_def.AST.ExpressionCast}'(' type_name ')' cast_expression) ; multiplicative_expression : cast_expression | (?E{t_def.AST.ExpressionMultiply, binary_operator = ' * ', precedence = 12}multiplicative_expression '*' cast_expression) | (?E{t_def.AST.ExpressionDivide, binary_operator = ' / ', precedence = 12}multiplicative_expression '/' cast_expression) | (?E{t_def.AST.ExpressionModulo, binary_operator = ' % ', precedence = 12}multiplicative_expression '%' cast_expression) ; additive_expression : multiplicative_expression | (?E{t_def.AST.ExpressionAdd, binary_operator = ' + ', precedence = 11}additive_expression '+' multiplicative_expression) | (?E{t_def.AST.ExpressionSubtract, binary_operator = ' - ', precedence = 11}additive_expression '-' multiplicative_expression) ; shift_expression : additive_expression | (?E{t_def.AST.ExpressionShiftLeft, binary_operator = ' << ', precedence = 10}shift_expression LEFT_OP additive_expression) | (?E{t_def.AST.ExpressionShiftRight, binary_operator = ' >> ', precedence = 10}shift_expression RIGHT_OP additive_expression) ; relational_expression : shift_expression | (?E{t_def.AST.ExpressionLessThan, binary_operator = ' < ', precedence = 9}relational_expression '<' shift_expression) | (?E{t_def.AST.ExpressionGreaterThan, binary_operator = ' > ', precedence = 9}relational_expression '>' shift_expression) | (?E{t_def.AST.ExpressionLessThanOrEqual, binary_operator = ' <= ', precedence = 9}relational_expression LE_OP shift_expression) | (?E{t_def.AST.ExpressionGreaterThanOrEqual, binary_operator = ' >= ', precedence = 9}relational_expression GE_OP shift_expression) ; equality_expression : relational_expression | (?E{t_def.AST.ExpressionEqual, binary_operator = ' == ', precedence = 8}equality_expression EQ_OP relational_expression) | (?E{t_def.AST.ExpressionNotEqual, binary_operator = ' != ', precedence = 8}equality_expression NE_OP relational_expression) ; and_expression : equality_expression | (?E{t_def.AST.ExpressionBitwiseAnd, binary_operator = ' & ', precedence = 7}and_expression '&' equality_expression) ; exclusive_or_expression : and_expression | (?E{t_def.AST.ExpressionExclusiveOr, binary_operator = ' ^ ', precedence = 6}exclusive_or_expression '^' and_expression) ; inclusive_or_expression : exclusive_or_expression | (?E{t_def.AST.ExpressionBitwiseOr, binary_operator = ' | ', precedence = 5}inclusive_or_expression '|' exclusive_or_expression) ; logical_and_expression : inclusive_or_expression | (?E{t_def.AST.ExpressionLogicalAnd, binary_operator = ' and ', precedence = 4}logical_and_expression AND_OP inclusive_or_expression) ; logical_or_expression : logical_and_expression | (?E{t_def.AST.ExpressionLogicalOr, binary_operator = ' or ', precedence = 3}logical_or_expression OR_OP logical_and_expression) ; conditional_expression : logical_or_expression | (?E{t_def.AST.ExpressionConditional}logical_or_expression '?' expression ':' conditional_expression) ; assignment_expression_or_asterisk_opt : (?E{t_def.AST.ExpressionEmpty}) | (?E{t_def.AST.ExpressionAsterisk}'*') | assignment_expression ; assignment_expression : conditional_expression | (?E{t_def.AST.ExpressionAssignment, binary_operator = ' = ', precedence = 1, right_to_left = True}unary_expression '=' assignment_expression) | (?E{t_def.AST.ExpressionMultiplyAssignment, binary_operator = ' *= ', precedence = 1, right_to_left = True}unary_expression MUL_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionDivideAssignment, binary_operator = ' /= ', precedence = 1, right_to_left = True}unary_expression DIV_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionModuloAssignment, binary_operator = ' %= ', precedence = 1, right_to_left = True}unary_expression MOD_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionAddAssignment, binary_operator = ' += ', precedence = 1, right_to_left = True}unary_expression ADD_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionSubtractAssignment, binary_operator = ' -= ', precedence = 1, right_to_left = True}unary_expression SUB_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionLeftShiftAssignment, binary_operator = ' <<= ', precedence = 1, right_to_left = True}unary_expression LEFT_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionRightShiftAssignment, binary_operator = ' >>= ', precedence = 1, right_to_left = True}unary_expression RIGHT_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionBitwiseAndAssignment, binary_operator = ' &= ', precedence = 1, right_to_left = True}unary_expression AND_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionExclusiveOrAssignment, binary_operator = ' ^= ', precedence = 1, right_to_left = True}unary_expression XOR_ASSIGN assignment_expression) | (?E{t_def.AST.ExpressionBitwiseOrAssignment, binary_operator = ' |= ', precedence = 1, right_to_left = True}unary_expression OR_ASSIGN assignment_expression) ; expression_opt : (?E{t_def.AST.ExpressionEmpty}) | expression ; expression : assignment_expression | (?E{t_def.AST.ExpressionComma, binary_operator = ', ', precedence = 0}expression ',' assignment_expression) ; equals_constant_expression_opt : (?E{t_def.AST.ExpressionEmpty}) | '=' constant_expression ; constant_expression : conditional_expression ; declaration : (?E{t_def.AST.Declaration}(?E{t_def.AST.DeclarationSpecifierList}declaration_specifier_list) (?E{t_def.AST.InitDeclaratorList}init_declarator_list_opt) ';') | static_assert_declaration ; declaration_specifier_list : declaration_specifier | declaration_specifier_list declaration_specifier ; declaration_specifier : storage_class_specifier | type_specifier | type_qualifier | function_specifier | alignment_specifier ; init_declarator_list_opt : | init_declarator_list ; init_declarator_list : init_declarator | init_declarator_list ',' init_declarator ; init_declarator : (?E{t_def.AST.InitDeclarator}declarator equals_initializer_opt) ; storage_class_specifier : (?E{t_def.AST.StorageClassSpecifier, n = 0}TYPEDEF) | (?E{t_def.AST.StorageClassSpecifier, n = 1}EXTERN) | (?E{t_def.AST.StorageClassSpecifier, n = 2}STATIC) | (?E{t_def.AST.StorageClassSpecifier, n = 3}THREAD_LOCAL) | (?E{t_def.AST.StorageClassSpecifier, n = 4}AUTO) | (?E{t_def.AST.StorageClassSpecifier, n = 5}REGISTER) ; type_specifier : (?E{t_def.AST.TypeSpecifier, n = 0}VOID) | (?E{t_def.AST.TypeSpecifier, n = 1}CHAR) | (?E{t_def.AST.TypeSpecifier, n = 2}SHORT) | (?E{t_def.AST.TypeSpecifier, n = 3}INT) | (?E{t_def.AST.TypeSpecifier, n = 4}LONG) | (?E{t_def.AST.TypeSpecifier, n = 5}FLOAT) | (?E{t_def.AST.TypeSpecifier, n = 6}DOUBLE) | (?E{t_def.AST.TypeSpecifier, n = 7}SIGNED) | (?E{t_def.AST.TypeSpecifier, n = 8}UNSIGNED) | (?E{t_def.AST.TypeSpecifier, n = 9}BOOL) | (?E{t_def.AST.TypeSpecifier, n = 10}COMPLEX) | (?E{t_def.AST.TypeSpecifier, n = 11}IMAGINARY) | atomic_type_specifier | struct_specifier | union_specifier | enum_specifier | TYPEDEF_NAME ; struct_specifier : (?E{t_def.AST.StructSpecifier}STRUCT identifier_opt '{' (?E{t_def.AST.StructDeclarationList}struct_declaration_list_opt) '}') | (?E{t_def.AST.StructSpecifier}STRUCT IDENTIFIER) ; union_specifier : (?E{t_def.AST.UnionSpecifier}UNION identifier_opt '{' (?E{t_def.AST.StructDeclarationList}struct_declaration_list_opt) '}') | (?E{t_def.AST.UnionSpecifier}UNION IDENTIFIER) ; struct_declaration_list_opt : | struct_declaration_list ; struct_declaration_list : struct_declaration | struct_declaration_list struct_declaration ; struct_declaration : (?E{t_def.AST.StructDeclaration}(?E{t_def.AST.SpecifierQualifierList}specifier_qualifier_list) (?E{t_def.AST.StructDeclaratorList}struct_declarator_list_opt) ';') | static_assert_declaration ; specifier_qualifier_list : specifier_qualifier | specifier_qualifier_list specifier_qualifier ; specifier_qualifier : type_specifier | type_qualifier ; struct_declarator_list_opt : | struct_declarator_list ; struct_declarator_list : struct_declarator | struct_declarator_list ',' struct_declarator ; struct_declarator : (?E{t_def.AST.StructDeclarator}declarator_opt ':' constant_expression) | declarator ; enum_specifier : (?E{t_def.AST.EnumSpecifier}ENUM identifier_opt '{' (?E{t_def.AST.EnumeratorList}enumerator_list_comma_opt) '}') | (?E{t_def.AST.EnumSpecifier}ENUM IDENTIFIER) ; enumerator_list_comma_opt : | enumerator_list | enumerator_list ',' ; enumerator_list : enumerator | enumerator_list ',' enumerator ; enumerator : (?E{t_def.AST.Enumerator}enumeration_constant equals_constant_expression_opt) ; atomic_type_specifier : ATOMIC '(' type_name ')' ; type_qualifier_or_static_list_opt : | type_qualifier_or_static_list ; type_qualifier_or_static_list : type_qualifier_or_static | type_qualifier_or_static_list type_qualifier_or_static ; type_qualifier_or_static : type_qualifier | (?E{t_def.AST.StorageClassSpecifier, n = 2}STATIC) ; type_qualifier : (?E{t_def.AST.TypeQualifier, n = 0}CONST) | (?E{t_def.AST.TypeQualifier, n = 1}RESTRICT) | (?E{t_def.AST.TypeQualifier, n = 2}VOLATILE) | (?E{t_def.AST.TypeQualifier, n = 3}ATOMIC) ; function_specifier : (?E{t_def.AST.FunctionSpecifier, n = 0}INLINE) | (?E{t_def.AST.FunctionSpecifier, n = 1}NORETURN) ; alignment_specifier : (?E{t_def.AST.AlignAsType}ALIGNAS '(' type_name ')') | (?E{t_def.AST.AlignAsExpression}ALIGNAS '(' constant_expression ')') ; declarator_opt : (?E{t_def.AST.DeclaratorEmpty}) | declarator ; declarator : direct_declarator | (?E{t_def.AST.DeclaratorPointer}'*' (?E{t_def.AST.TypeQualifierList}type_qualifier_list_opt) declarator) ; direct_declarator : (?E{t_def.AST.DeclaratorIdentifier}IDENTIFIER) | '(' declarator ')' | (?E{t_def.AST.DeclaratorArray}direct_declarator '[' (?E{t_def.AST.TypeQualifierOrStaticList}type_qualifier_or_static_list_opt) assignment_expression_or_asterisk_opt ']') | (?E{t_def.AST.DeclaratorFunctionOldStyle}direct_declarator '(' (?E{t_def.AST.IdentifierList}identifier_list_opt) ')') | (?E{t_def.AST.DeclaratorFunction, varargs = False}direct_declarator '(' (?E{t_def.AST.ParameterDeclarationList}parameter_declaration_list) ')') | (?E{t_def.AST.DeclaratorFunction, varargs = True}direct_declarator '(' (?E{t_def.AST.ParameterDeclarationList}parameter_declaration_list) ',' ELLIPSIS ')') ; type_qualifier_list_opt : | type_qualifier_list ; type_qualifier_list : type_qualifier | type_qualifier_list type_qualifier ; parameter_declaration_list : parameter_declaration | parameter_declaration_list ',' parameter_declaration ; parameter_declaration : (?E{t_def.AST.ParameterDeclaration}(?E{t_def.AST.DeclarationSpecifierList}declaration_specifier_list) declarator) | (?E{t_def.AST.ParameterDeclaration}(?E{t_def.AST.DeclarationSpecifierList}declaration_specifier_list) abstract_declarator) ; identifier_list_opt : | identifier_list ; identifier_list : IDENTIFIER | identifier_list ',' IDENTIFIER ; type_name : (?E{t_def.AST.TypeName}(?E{t_def.AST.SpecifierQualifierList}specifier_qualifier_list) abstract_declarator) ; abstract_declarator : direct_abstract_declarator_opt | (?E{t_def.AST.DeclaratorPointer}'*' (?E{t_def.AST.TypeQualifierList}type_qualifier_list_opt) abstract_declarator) ; direct_abstract_declarator_opt : (?E{t_def.AST.DeclaratorAbstract}) | direct_abstract_declarator ; /* in the below, ") (" should be ")(", inserted space for now */ direct_abstract_declarator : '(' direct_abstract_declarator ')' | '(' (?E{t_def.AST.DeclaratorPointer}'*' (?E{t_def.AST.TypeQualifierList}type_qualifier_list_opt) abstract_declarator) ')' | (?E{t_def.AST.DeclaratorArray}(?E{t_def.AST.DeclaratorAbstract})'[' (?E{t_def.AST.TypeQualifierOrStaticList}type_qualifier_or_static_list_opt) assignment_expression_or_asterisk_opt ']') | (?E{t_def.AST.DeclaratorFunction, varargs = False}(?E{t_def.AST.DeclaratorAbstract})'('(?E{t_def.AST.ParameterDeclarationList}) ')') | (?E{t_def.AST.DeclaratorFunction, varargs = False}(?E{t_def.AST.DeclaratorAbstract})'(' (?E{t_def.AST.ParameterDeclarationList}parameter_declaration_list) ')') | (?E{t_def.AST.DeclaratorFunction, varargs = True}(?E{t_def.AST.DeclaratorAbstract})'(' (?E{t_def.AST.ParameterDeclarationList}parameter_declaration_list) ',' ELLIPSIS ')') | (?E{t_def.AST.DeclaratorArray}direct_abstract_declarator '[' (?E{t_def.AST.TypeQualifierOrStaticList}type_qualifier_or_static_list_opt) assignment_expression_or_asterisk_opt ']') | (?E{t_def.AST.DeclaratorFunction, varargs = False}direct_abstract_declarator '('(?E{t_def.AST.ParameterDeclarationList}) ')') | (?E{t_def.AST.DeclaratorFunction, varargs = False}direct_abstract_declarator '(' (?E{t_def.AST.ParameterDeclarationList}parameter_declaration_list) ')') | (?E{t_def.AST.DeclaratorFunction, varargs = True}direct_abstract_declarator '(' (?E{t_def.AST.ParameterDeclarationList}parameter_declaration_list) ',' ELLIPSIS ')') ; equals_initializer_opt : (?E{t_def.AST.EqualsInitializerEmpty}) | '=' initializer ; initializer : '{' (?E{t_def.AST.DesignatorInitializerList}designator_initializer_list_comma_opt) '}' | assignment_expression ; designator_initializer_list_comma_opt : | designator_initializer_list | designator_initializer_list ',' ; designator_initializer_list : designator_initializer | designator_initializer_list ',' designator_initializer ; designator_initializer : (?E{t_def.AST.DesignatorInitializer}designator_list_equals_opt initializer) ; designator_list_equals_opt : (?E{t_def.AST.DesignatorListEqualsEmpty}) | (?E{t_def.AST.DesignatorList}designator_list) '=' ; designator_list : designator | designator_list designator ; designator : (?E{t_def.AST.DesignatorIndex}'[' constant_expression ']') | (?E{t_def.AST.DesignatorField}'.' IDENTIFIER) ; static_assert_declaration : (?E{t_def.AST.StaticAssertDeclaration}STATIC_ASSERT '(' constant_expression ',' STRING_LITERAL ')' ';') ; statement : (?E{t_def.AST.StatementLabel}IDENTIFIER ':' statement) | (?E{t_def.AST.StatementCase}CASE constant_expression ':' statement) | (?E{t_def.AST.StatementDefault}DEFAULT ':' statement) | (?E{t_def.AST.StatementBlock}'{' (?E{t_def.AST.BlockItemList}block_item_list_opt) '}') | (?E{t_def.AST.StatementExpression}expression_opt ';') | (?E{t_def.AST.StatementIfElse}IF '(' expression ')' statement ELSE statement) | (?E{t_def.AST.StatementIf}IF '(' expression ')' statement) | (?E{t_def.AST.StatementSwitch}SWITCH '(' expression ')' statement) | (?E{t_def.AST.StatementWhile}WHILE '(' expression ')' statement) | (?E{t_def.AST.StatementDoWhile}DO statement WHILE '(' expression ')' ';') | (?E{t_def.AST.StatementFor}FOR '(' (?E{t_def.AST.StatementExpression}expression_opt) ';' expression_opt ';' expression_opt ')' statement) | (?E{t_def.AST.StatementFor}FOR '(' declaration expression_opt ';' expression_opt ')' statement) | (?E{t_def.AST.StatementGoto}GOTO IDENTIFIER ';') | (?E{t_def.AST.StatementContinue}CONTINUE ';') | (?E{t_def.AST.StatementBreak}BREAK ';') | (?E{t_def.AST.StatementReturn}RETURN expression_opt ';') ; block_item_list_opt : | block_item_list ; block_item_list : block_item | block_item_list block_item ; block_item : declaration | statement ; translation_unit_opt : | translation_unit ; translation_unit : external_declaration | translation_unit external_declaration ; external_declaration : function_definition | declaration ; function_definition : (?E{t_def.AST.FunctionDefinition}(?E{t_def.AST.DeclarationSpecifierList}declaration_specifier_list) declarator (?E{t_def.AST.DeclarationList}declaration_list_opt) '{' (?E{t_def.AST.BlockItemList}block_item_list_opt) '}') ; declaration_list_opt : | declaration_list ; declaration_list : declaration | declaration_list declaration ; identifier_opt : (?E{t_def.AST.IdentifierEmpty}) | IDENTIFIER ;