blob: 50b8746049e1677a884e90e51a13d460c6e57bd3 [file] [log] [blame]
-----------------------------------------------------------------------------------
-- Copyright (c) 2006, 2010 IBM Corporation and others.
-- This program and the accompanying materials
-- are made available under the terms of the Eclipse Public License 2.0
-- which accompanies this distribution, and is available at
-- https://www.eclipse.org/legal/epl-2.0/
--
-- SPDX-License-Identifier: EPL-2.0
--
-- Contributors:
-- IBM Corporation - initial API and implementation
-----------------------------------------------------------------------------------
$Terminals
-- Keywords
auto break case char const continue default do
double else enum extern float for goto if
inline int long register restrict return short signed
sizeof static struct switch typedef union unsigned void
volatile while _Bool _Complex _Imaginary
-- Literals
integer floating charconst stringlit
-- identifiers
identifier
-- Special tokens used in content assist
Completion
EndOfCompletion
-- Unrecognized token
Invalid
-- Punctuation (with aliases to make grammar more readable)
LeftBracket ::= '['
LeftParen ::= '('
LeftBrace ::= '{'
Dot ::= '.'
Arrow ::= '->'
PlusPlus ::= '++'
MinusMinus ::= '--'
And ::= '&'
Star ::= '*'
Plus ::= '+'
Minus ::= '-'
Tilde ::= '~'
Bang ::= '!'
Slash ::= '/'
Percent ::= '%'
RightShift ::= '>>'
LeftShift ::= '<<'
LT ::= '<'
GT ::= '>'
LE ::= '<='
GE ::= '>='
EQ ::= '=='
NE ::= '!='
Caret ::= '^'
Or ::= '|'
AndAnd ::= '&&'
OrOr ::= '||'
Question ::= '?'
Colon ::= ':'
DotDotDot ::= '...'
Assign ::= '='
StarAssign ::= '*='
SlashAssign ::= '/='
PercentAssign ::= '%='
PlusAssign ::= '+='
MinusAssign ::= '-='
RightShiftAssign ::= '>>='
LeftShiftAssign ::= '<<='
AndAssign ::= '&='
CaretAssign ::= '^='
OrAssign ::= '|='
Comma ::= ','
RightBracket -- these four have special rules for content assist
RightParen
RightBrace
SemiColon
$End
$Globals
/.
import org.eclipse.cdt.internal.core.dom.parser.c.CNodeFactory;
import org.eclipse.cdt.core.dom.lrparser.action.c99.C99BuildASTParserAction;
import org.eclipse.cdt.core.dom.lrparser.action.c99.C99SecondaryParserFactory;
./
$End
-- TODO move this code into a common template
$Define
$build_action_class /. C99BuildASTParserAction ./
$node_factory_create_expression /. CNodeFactory.getDefault() ./
$parser_factory_create_expression /. C99SecondaryParserFactory.getDefault() ./
$End
$Rules
-------------------------------------------------------------------------------------------
-- AST scopes
-------------------------------------------------------------------------------------------
<openscope-ast>
::= $empty
/. $Build openASTScope(); $EndBuild ./
<empty>
::= $empty
/. $Build consumeEmpty(); $EndBuild ./
-------------------------------------------------------------------------------------------
-- Content assist
-------------------------------------------------------------------------------------------
-- The EndOfCompletion token is a special token that matches some punctuation.
-- These tokens allow the parse to complete successfully after a Completion token
-- is encountered.
']' ::=? 'RightBracket'
| 'EndOfCompletion'
')' ::=? 'RightParen'
| 'EndOfCompletion'
'}' ::=? 'RightBrace'
| 'EndOfCompletion'
';' ::=? 'SemiColon'
| 'EndOfCompletion'
-------------------------------------------------------------------------------------------
-- Expressions
-------------------------------------------------------------------------------------------
identifier_token
::= 'identifier'
| 'Completion'
literal
::= 'integer'
/. $Build consumeExpressionLiteral(IASTLiteralExpression.lk_integer_constant); $EndBuild ./
| 'floating'
/. $Build consumeExpressionLiteral(IASTLiteralExpression.lk_float_constant); $EndBuild ./
| 'charconst'
/. $Build consumeExpressionLiteral(IASTLiteralExpression.lk_char_constant); $EndBuild ./
| 'stringlit'
/. $Build consumeExpressionLiteral(IASTLiteralExpression.lk_string_literal); $EndBuild ./
primary_expression
::= literal
| primary_expression_id
/. $Build consumeExpressionID(); $EndBuild ./
| '(' expression ')'
/. $Build consumeExpressionBracketed(); $EndBuild ./
primary_expression_id
::= identifier_token
postfix_expression
::= primary_expression
| postfix_expression '[' expression ']'
/. $Build consumeExpressionArraySubscript(); $EndBuild ./
| postfix_expression '(' expression_list_opt ')'
/. $Build consumeExpressionFunctionCall(); $EndBuild ./
| postfix_expression '.' member_name
/. $Build consumeExpressionFieldReference(false); $EndBuild ./
| postfix_expression '->' member_name
/. $Build consumeExpressionFieldReference(true); $EndBuild ./
| postfix_expression '++'
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_postFixIncr); $EndBuild ./
| postfix_expression '--'
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_postFixDecr); $EndBuild ./
| '(' type_id ')' initializer_list
/. $Build consumeExpressionTypeIdInitializer(); $EndBuild ./
comma_opt
::= ',' | $empty
member_name
::= identifier_token
unary_expression
::= postfix_expression
| '++' unary_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_prefixIncr); $EndBuild ./
| '--' unary_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_prefixDecr); $EndBuild ./
| '&' cast_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_amper); $EndBuild ./
| '*' cast_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_star); $EndBuild ./
| '+' cast_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_plus); $EndBuild ./
| '-' cast_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_minus); $EndBuild ./
| '~' cast_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_tilde); $EndBuild ./
| '!' cast_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_not); $EndBuild ./
| 'sizeof' unary_expression
/. $Build consumeExpressionUnaryOperator(IASTUnaryExpression.op_sizeof); $EndBuild ./
| 'sizeof' '(' type_id ')'
/. $Build consumeExpressionTypeId(IASTTypeIdExpression.op_sizeof); $EndBuild ./
cast_expression
::= unary_expression
| '(' type_id ')' cast_expression
/. $Build consumeExpressionCast(IASTCastExpression.op_cast); $EndBuild ./
multiplicative_expression
::= cast_expression
| multiplicative_expression '*' cast_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_multiply); $EndBuild ./
| multiplicative_expression '/' cast_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_divide); $EndBuild ./
| multiplicative_expression '%' cast_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_modulo); $EndBuild ./
additive_expression
::= multiplicative_expression
| additive_expression '+' multiplicative_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_plus); $EndBuild ./
| additive_expression '-' multiplicative_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_minus); $EndBuild ./
shift_expression
::= additive_expression
| shift_expression '<<' additive_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_shiftLeft); $EndBuild ./
| shift_expression '>>' additive_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_shiftRight); $EndBuild ./
relational_expression
::= shift_expression
| relational_expression '<' shift_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_lessThan); $EndBuild ./
| relational_expression '>' shift_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_greaterThan); $EndBuild ./
| relational_expression '<=' shift_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_lessEqual); $EndBuild ./
| relational_expression '>=' shift_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_greaterEqual); $EndBuild ./
equality_expression
::= relational_expression
| equality_expression '==' relational_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_equals); $EndBuild ./
| equality_expression '!=' relational_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_notequals); $EndBuild ./
and_expression
::= equality_expression
| and_expression '&' equality_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_binaryAnd); $EndBuild ./
exclusive_or_expression
::= and_expression
| exclusive_or_expression '^' and_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_binaryXor); $EndBuild ./
inclusive_or_expression
::= exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_binaryOr); $EndBuild ./
logical_and_expression
::= inclusive_or_expression
| logical_and_expression '&&' inclusive_or_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_logicalAnd); $EndBuild ./
logical_or_expression
::= logical_and_expression
| logical_or_expression '||' logical_and_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_logicalOr); $EndBuild ./
conditional_expression
::= logical_or_expression
| logical_or_expression '?' expression ':' assignment_expression
/. $Build consumeExpressionConditional(); $EndBuild ./
assignment_expression
::= conditional_expression
| unary_expression '=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_assign); $EndBuild ./
| unary_expression '*=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_multiplyAssign); $EndBuild ./
| unary_expression '/=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_divideAssign); $EndBuild ./
| unary_expression '%=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_moduloAssign); $EndBuild ./
| unary_expression '+=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_plusAssign); $EndBuild ./
| unary_expression '-=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_minusAssign); $EndBuild ./
| unary_expression '<<=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_shiftLeftAssign); $EndBuild ./
| unary_expression '>>=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_shiftRightAssign); $EndBuild ./
| unary_expression '&=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_binaryAndAssign); $EndBuild ./
| unary_expression '^=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_binaryXorAssign); $EndBuild ./
| unary_expression '|=' assignment_expression
/. $Build consumeExpressionBinaryOperator(IASTBinaryExpression.op_binaryOrAssign); $EndBuild ./
-- special rule to avoid conflict between problem statements and problem expressions
expression_in_statement
::= expression_list
expression
::= expression_list
expression_list
::= <openscope-ast> expression_list_actual
/. $Build consumeExpressionList(); $EndBuild ./
expression_list_opt
::= expression_list
| $empty
/. $Build consumeEmpty(); $EndBuild ./
expression_list_actual
::= assignment_expression
| expression_list_actual ',' assignment_expression
constant_expression
::= conditional_expression
-------------------------------------------------------------------------------------------
-- Statements
-------------------------------------------------------------------------------------------
statement
::= labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
| ERROR_TOKEN
/. $Build consumeStatementProblem(); $EndBuild ./
labeled_statement
::= identifier_token ':' statement
/. $Build consumeStatementLabeled(); $EndBuild ./
| 'case' constant_expression ':' statement
/. $Build consumeStatementCase(); $EndBuild ./
| 'default' ':' statement
/. $Build consumeStatementDefault(); $EndBuild ./
compound_statement
::= '{' '}'
/. $Build consumeStatementCompoundStatement(false); $EndBuild ./
| '{' <openscope-ast> block_item_list '}'
/. $Build consumeStatementCompoundStatement(true); $EndBuild ./
block_item_list
::= block_item
| block_item_list block_item
block_item
::= statement
| declaration
/. $Build consumeStatementDeclarationWithDisambiguation(); $EndBuild ./
expression_statement
::= ';'
/. $Build consumeStatementNull(); $EndBuild ./
| expression_in_statement ';'
/. $Build consumeStatementExpression(); $EndBuild ./
selection_statement
::= 'if' '(' expression ')' statement
/. $Build consumeStatementIf(false); $EndBuild ./
| 'if' '(' expression ')' statement 'else' statement
/. $Build consumeStatementIf(true); $EndBuild ./
| 'switch' '(' expression ')' statement
/. $Build consumeStatementSwitch(); $EndBuild ./
expression_opt
::= expression
| $empty
/. $Build consumeEmpty(); $EndBuild ./
iteration_statement
::= 'do' statement 'while' '(' expression ')' ';'
/. $Build consumeStatementDoLoop(true); $EndBuild ./
| 'do' statement
/. $Build consumeStatementDoLoop(false); $EndBuild ./
| 'while' '(' expression ')' statement
/. $Build consumeStatementWhileLoop(); $EndBuild ./
| 'for' '(' expression_opt ';' expression_opt ';' expression_opt ')' statement
/. $Build consumeStatementForLoop(); $EndBuild ./
| 'for' '(' declaration expression_opt ';' expression_opt ')' statement
/. $Build consumeStatementForLoop(); $EndBuild ./
jump_statement
::= 'goto' identifier_token ';'
/. $Build consumeStatementGoto(); $EndBuild ./
| 'continue' ';'
/. $Build consumeStatementContinue(); $EndBuild ./
| 'break' ';'
/. $Build consumeStatementBreak(); $EndBuild ./
| 'return' ';'
/. $Build consumeStatementReturn(false); $EndBuild ./
| 'return' expression ';'
/. $Build consumeStatementReturn(true); $EndBuild ./
-------------------------------------------------------------------------------------------
-- Declarations
-------------------------------------------------------------------------------------------
declaration
::= declaration_specifiers ';'
/. $Build consumeDeclarationSimple(false); $EndBuild ./
| declaration_specifiers <openscope-ast> init_declarator_list ';'
/. $Build consumeDeclarationSimple(true); $EndBuild ./
declaration_specifiers
::= <openscope-ast> simple_declaration_specifiers
/. $Build consumeDeclarationSpecifiersSimple(); $EndBuild ./
| <openscope-ast> struct_or_union_declaration_specifiers
/. $Build consumeDeclarationSpecifiersStructUnionEnum(); $EndBuild ./
| <openscope-ast> elaborated_declaration_specifiers
/. $Build consumeDeclarationSpecifiersStructUnionEnum(); $EndBuild ./
| <openscope-ast> enum_declaration_specifiers
/. $Build consumeDeclarationSpecifiersStructUnionEnum(); $EndBuild ./
| <openscope-ast> typdef_name_declaration_specifiers
/. $Build consumeDeclarationSpecifiersTypedefName(); $EndBuild ./
no_type_declaration_specifier
::= storage_class_specifier
| type_qualifier
| function_specifier
no_type_declaration_specifiers
::= no_type_declaration_specifier
| no_type_declaration_specifiers no_type_declaration_specifier
simple_declaration_specifiers
::= simple_type_specifier
| no_type_declaration_specifiers simple_type_specifier
| simple_declaration_specifiers simple_type_specifier
| simple_declaration_specifiers no_type_declaration_specifier
struct_or_union_declaration_specifiers
::= struct_or_union_specifier
| no_type_declaration_specifiers struct_or_union_specifier
| struct_or_union_declaration_specifiers no_type_declaration_specifier
elaborated_declaration_specifiers
::= elaborated_specifier
| no_type_declaration_specifiers elaborated_specifier
| elaborated_declaration_specifiers no_type_declaration_specifier
enum_declaration_specifiers
::= enum_specifier
| no_type_declaration_specifiers enum_specifier
| enum_declaration_specifiers no_type_declaration_specifier
typdef_name_declaration_specifiers
::= type_name_specifier
| no_type_declaration_specifiers type_name_specifier
| typdef_name_declaration_specifiers no_type_declaration_specifier
init_declarator_list
::= init_declarator
| init_declarator_list ',' init_declarator
init_declarator
::= complete_declarator
| complete_declarator '=' initializer
/. $Build consumeDeclaratorWithInitializer(true); $EndBuild ./
complete_declarator
::= declarator
storage_class_specifier
::= storage_class_specifier_token
/. $Build consumeToken(); $EndBuild ./
storage_class_specifier_token
::= 'typedef'
| 'extern'
| 'static'
| 'auto'
| 'register'
simple_type_specifier
::= simple_type_specifier_token
/. $Build consumeToken(); $EndBuild ./
simple_type_specifier_token
::= 'void'
| 'char'
| 'short'
| 'int'
| 'long'
| 'float'
| 'double'
| 'signed'
| 'unsigned'
| '_Bool'
| '_Complex'
| '_Imaginary'
type_name_specifier
::= identifier_token
/. $Build consumeToken(); $EndBuild ./
struct_or_union_specifier
::= struct_or_union struct_or_union_specifier_hook '{' <openscope-ast> struct_declaration_list_opt '}'
/. $Build consumeTypeSpecifierComposite(false); $EndBuild ./
| struct_or_union struct_or_union_specifier_hook identifier_token struct_or_union_specifier_suffix_hook '{' <openscope-ast> struct_declaration_list_opt '}'
/. $Build consumeTypeSpecifierComposite(true); $EndBuild ./
struct_or_union_specifier_hook
::= $empty
struct_or_union_specifier_suffix_hook
::= $empty
struct_or_union
::= 'struct'
| 'union'
elaborated_specifier
::= 'struct' elaborated_specifier_hook identifier_token
/. $Build consumeTypeSpecifierElaborated(IASTCompositeTypeSpecifier.k_struct); $EndBuild ./
| 'union' elaborated_specifier_hook identifier_token
/. $Build consumeTypeSpecifierElaborated(IASTCompositeTypeSpecifier.k_union); $EndBuild ./
| 'enum' elaborated_specifier_hook identifier_token
/. $Build consumeTypeSpecifierElaborated(IASTElaboratedTypeSpecifier.k_enum); $EndBuild ./
elaborated_specifier_hook
::= $empty
struct_declaration_list_opt
::= struct_declaration_list
| $empty
struct_declaration_list
::= struct_declaration
| struct_declaration_list struct_declaration
struct_declaration
::= specifier_qualifier_list <openscope-ast> struct_declarator_list ';' -- regular declarators plus bit fields
/. $Build consumeStructDeclaration(true); $EndBuild ./
| specifier_qualifier_list ';'
/. $Build consumeStructDeclaration(false); $EndBuild ./
| ERROR_TOKEN
/. $Build consumeDeclarationProblem(); $EndBuild ./
-- just reuse declaration_specifiers, makes grammar a bit more lenient but thats OK
specifier_qualifier_list
::= declaration_specifiers
struct_declarator_list
::= complete_struct_declarator
| struct_declarator_list ',' complete_struct_declarator
complete_struct_declarator
::= struct_declarator
struct_declarator
::= declarator
| ':' constant_expression
/. $Build consumeBitField(false); $EndBuild ./
| declarator ':' constant_expression
/. $Build consumeBitField(true); $EndBuild ./
enum_specifier
::= 'enum' enum_specifier_hook '{' <openscope-ast> enumerator_list_opt comma_opt '}'
/. $Build consumeTypeSpecifierEnumeration(false); $EndBuild ./
| 'enum' enum_specifier_hook identifier_token '{' <openscope-ast> enumerator_list_opt comma_opt '}'
/. $Build consumeTypeSpecifierEnumeration(true); $EndBuild ./
enum_specifier_hook
::= $empty
enumerator_list_opt
::= enumerator_list
| $empty
enumerator_list
::= enumerator
| enumerator_list ',' enumerator
enumerator
::= identifier_token
/. $Build consumeEnumerator(false); $EndBuild ./
| identifier_token '=' constant_expression
/. $Build consumeEnumerator(true); $EndBuild ./
type_qualifier
::= type_qualifier_token
/. $Build consumeToken(); $EndBuild ./
type_qualifier_token
::= 'const'
| 'restrict'
| 'volatile'
function_specifier
::= 'inline'
/. $Build consumeToken(); $EndBuild ./
declarator
::= direct_declarator
| <openscope-ast> pointer_seq direct_declarator
/. $Build consumeDeclaratorWithPointer(true); $EndBuild ./
direct_declarator
::= array_direct_declarator
| function_prototype_direct_declarator
| basic_direct_declarator
| knr_direct_declarator
basic_direct_declarator
::= declarator_id_name
/. $Build consumeDirectDeclaratorIdentifier(); $EndBuild ./
| '(' declarator ')'
/. $Build consumeDirectDeclaratorBracketed(); $EndBuild ./
declarator_id_name
::= 'identifier'
/. $Build consumeIdentifierName(); $EndBuild ./
array_direct_declarator
::= basic_direct_declarator array_modifier
/. $Build consumeDirectDeclaratorArrayDeclarator(true); $EndBuild ./
| array_direct_declarator array_modifier
/. $Build consumeDirectDeclaratorArrayDeclarator(true); $EndBuild ./
function_prototype_direct_declarator
::= function_direct_declarator
function_direct_declarator
::= basic_direct_declarator '(' <openscope-ast> parameter_type_list ')'
/. $Build consumeDirectDeclaratorFunctionDeclarator(true, true); $EndBuild ./
| basic_direct_declarator '(' ')'
/. $Build consumeDirectDeclaratorFunctionDeclarator(true, false); $EndBuild ./
function_declarator
::= function_direct_declarator
| <openscope-ast> pointer_seq function_direct_declarator
/. $Build consumeDeclaratorWithPointer(true); $EndBuild ./
-- This is a hack because the parser cannot tell the difference between
-- plain identifiers and types. Because of this an identifier_list would
-- always be parsed as a parameter_type_list instead. In a KnR funciton
-- definition we can use the extra list of declarators to disambiguate.
-- This rule should be merged back into direct_declarator if type info is
-- added to the parser.
knr_direct_declarator
::= basic_direct_declarator '(' <openscope-ast> identifier_list ')'
/. $Build consumeDirectDeclaratorFunctionDeclaratorKnR(); $EndBuild ./
knr_function_declarator
::= knr_direct_declarator
| <openscope-ast> pointer_seq knr_direct_declarator
/. $Build consumeDeclaratorWithPointer(true); $EndBuild ./
identifier_list
::= 'identifier'
/. $Build consumeIdentifierKnR(); $EndBuild ./
| identifier_list ',' 'identifier'
/. $Build consumeIdentifierKnR(); $EndBuild ./
array_modifier
::= '[' ']'
/. $Build consumeDirectDeclaratorArrayModifier(false); $EndBuild ./
| '[' <openscope-ast> array_modifier_type_qualifiers ']'
/. $Build consumeDirectDeclaratorModifiedArrayModifier(false, false, true, false); $EndBuild ./
| '[' assignment_expression ']'
/. $Build consumeDirectDeclaratorArrayModifier(true); $EndBuild ./
| '[' <openscope-ast> array_modifier_type_qualifiers assignment_expression ']'
/. $Build consumeDirectDeclaratorModifiedArrayModifier(false, false, true, true); $EndBuild ./
| '[' 'static' assignment_expression ']'
/. $Build consumeDirectDeclaratorModifiedArrayModifier(true, false, false, true); $EndBuild ./
| '[' 'static' <openscope-ast> array_modifier_type_qualifiers assignment_expression ']'
/. $Build consumeDirectDeclaratorModifiedArrayModifier(true, false, true, true); $EndBuild ./
| '[' <openscope-ast> array_modifier_type_qualifiers 'static' assignment_expression ']'
/. $Build consumeDirectDeclaratorModifiedArrayModifier(true, false, true, true); $EndBuild ./
| '[' '*' ']'
/. $Build consumeDirectDeclaratorModifiedArrayModifier(false, true, false, false); $EndBuild ./
| '[' <openscope-ast> array_modifier_type_qualifiers '*' ']'
/. $Build consumeDirectDeclaratorModifiedArrayModifier(false, true, true, false); $EndBuild ./
array_modifier_type_qualifiers
::= type_qualifier_list
pointer_seq
::= pointer_hook '*' pointer_hook
/. $Build consumePointer(); $EndBuild ./
| pointer_seq pointer_hook '*' pointer_hook
/. $Build consumePointer(); $EndBuild ./
| pointer_hook '*' pointer_hook <openscope-ast> type_qualifier_list
/. $Build consumePointerTypeQualifierList(); $EndBuild ./
| pointer_seq pointer_hook '*' pointer_hook <openscope-ast> type_qualifier_list
/. $Build consumePointerTypeQualifierList(); $EndBuild ./
pointer_hook
::= $empty
type_qualifier_list
::= type_qualifier
| type_qualifier_list type_qualifier
parameter_type_list
::= parameter_list
/. $Build consumeEmpty(); $EndBuild ./
| parameter_list ',' '...'
/. $Build consumePlaceHolder(); $EndBuild ./
| '...' -- not spec
/. $Build consumePlaceHolder(); $EndBuild ./
parameter_list
::= parameter_declaration
| parameter_list ',' parameter_declaration
parameter_declaration
::= declaration_specifiers complete_parameter_declarator
/. $Build consumeParameterDeclaration(); $EndBuild ./
| declaration_specifiers
/. $Build consumeParameterDeclarationWithoutDeclarator(); $EndBuild ./
complete_parameter_declarator
::= declarator
| abstract_declarator
-- only used in expressions, eg) sizeof, casts etc...
type_id
::= specifier_qualifier_list
/. $Build consumeTypeId(false); $EndBuild ./
| specifier_qualifier_list abstract_declarator
/. $Build consumeTypeId(true); $EndBuild ./
abstract_declarator -- a declarator that does not include an identifier
::= direct_abstract_declarator
| <openscope-ast> pointer_seq
/. $Build consumeDeclaratorWithPointer(false); $EndBuild ./
| <openscope-ast> pointer_seq direct_abstract_declarator
/. $Build consumeDeclaratorWithPointer(true); $EndBuild ./
direct_abstract_declarator
::= basic_direct_abstract_declarator
| array_direct_abstract_declarator
| function_direct_abstract_declarator
basic_direct_abstract_declarator
::= '(' abstract_declarator ')'
/. $Build consumeDirectDeclaratorBracketed(); $EndBuild ./
array_direct_abstract_declarator
::= array_modifier
/. $Build consumeDirectDeclaratorArrayDeclarator(false); $EndBuild ./
| array_direct_abstract_declarator array_modifier
/. $Build consumeDirectDeclaratorArrayDeclarator(true); $EndBuild ./
| basic_direct_abstract_declarator array_modifier
/. $Build consumeDirectDeclaratorArrayDeclarator(true); $EndBuild ./
function_direct_abstract_declarator
::= '(' ')'
/. $Build consumeDirectDeclaratorFunctionDeclarator(false, false); $EndBuild ./
| basic_direct_abstract_declarator '(' ')'
/. $Build consumeDirectDeclaratorFunctionDeclarator(true, false); $EndBuild ./
| '(' <openscope-ast> parameter_type_list ')'
/. $Build consumeDirectDeclaratorFunctionDeclarator(false, true); $EndBuild ./
| basic_direct_abstract_declarator '(' <openscope-ast> parameter_type_list ')'
/. $Build consumeDirectDeclaratorFunctionDeclarator(true, true); $EndBuild ./
initializer
::= assignment_expression
/. $Build consumeInitializer(); $EndBuild ./
| initializer_list
--CDT_70_FIX_FROM_50-#4
/. $Build consumeInitializer(); $EndBuild ./
initializer_list
::= start_initializer_list '{' <openscope-ast> initializer_seq comma_opt '}' end_initializer_list
/. $Build consumeInitializerList(); $EndBuild ./
| '{' <openscope-ast> '}'
/. $Build consumeInitializerList(); $EndBuild ./
start_initializer_list
::= $empty
/. $Build initializerListStart(); $EndBuild ./
end_initializer_list
::= $empty
/. $Build initializerListEnd(); $EndBuild ./
initializer_seq
::= initializer
| designated_initializer
| initializer_seq ',' initializer
| initializer_seq ',' designated_initializer
designated_initializer
::= <openscope-ast> designation '=' initializer
/. $Build consumeInitializerDesignated(); $EndBuild ./
designation
::= designator_list
designator_list
::= designator_base
| designator_list designator
designator_base
::= '[' constant_expression ']'
/. $Build consumeDesignatorArray(); $EndBuild ./
| '.' identifier_token
/. $Build consumeDesignatorField(); $EndBuild ./
designator
::= '[' constant_expression ']'
/. $Build consumeDesignatorArray(); $EndBuild ./
| '.' identifier_token
/. $Build consumeDesignatorField(); $EndBuild ./
-------------------------------------------------------------------------------------------
-- External Definitions
-------------------------------------------------------------------------------------------
translation_unit
::= external_declaration_list
/. $Build consumeTranslationUnit(); $EndBuild ./
| $empty
/. $Build consumeTranslationUnit(); $EndBuild ./
external_declaration_list
::= external_declaration
| external_declaration_list external_declaration
external_declaration
::= function_definition
| declaration
| ';'
/. $Build consumeDeclarationEmpty(); $EndBuild ./
| ERROR_TOKEN
/. $Build consumeDeclarationProblem(); $EndBuild ./
-- Used by KnR
declaration_list
::= declaration
| declaration_list declaration
-- The extra <openscope-ast> nonterminal before declarator in this rule is only there
-- to avoid a shift/reduce error with the rule for declaration.
-- The symbol table scoped is opened in the rule for function_direct_declarator
function_definition
::= normal_function_definition
-- this rule is here as a special case (its not C99 spec) just to support implicit int in function definitions
| <openscope-ast> function_declarator function_body
/. $Build consumeFunctionDefinition(false); $EndBuild ./
| declaration_specifiers <openscope-ast> knr_function_declarator <openscope-ast> declaration_list compound_statement
/. $Build consumeFunctionDefinitionKnR(); $EndBuild ./
normal_function_definition
::= declaration_specifiers <openscope-ast> function_declarator function_body
/. $Build consumeFunctionDefinition(true); $EndBuild ./
-- same syntax as compound_statement but a symbol table scope isn't opened
function_body
::= '{' '}'
/. $Build consumeStatementCompoundStatement(false); $EndBuild ./
| '{' <openscope-ast> block_item_list '}'
/. $Build consumeStatementCompoundStatement(true); $EndBuild ./
$End