Compiler 2014: Grammar
外观
Top level
program: (declaration | function-definition)+ declaration:'typedef' type-specifier declarators ';'type-specifier init-declarators? ';' function-definition: type-specifier plain-declarator '(' parameters? ')' compound-statement parameters: plain-declaration (',' plain-declaration)*(',' '...')?declarators: declarator (',' declarator)* init-declarators: init-declarator (',' init-declarator)* init-declarator: declarator ('=' initializer)? initializer: assignment-expression | '{' initializer (',' initializer)* '}' type-specifier: 'void' | 'char' | 'int'| typedef-name| struct-or-union identifier? '{' (type-specifier declarators ';')+ '}' | struct-or-union identifier struct-or-union: 'struct' | 'union' plain-declaration: type-specifier declarator declarator: plain-declarator '(' parameters? ')' | plain-declarator ('[' constant-expression ']')* plain-declarator: '*'* identifier
Statements
statement: expression-statement
| compound-statement
| selection-statement
| iteration-statement
| jump-statement
expression-statement: expression? ';'
compound-statement: '{' declaration* statement* '}'
selection-statement: 'if' '(' expression ')' statement ('else' statement)?
iteration-statement: 'while' '(' expression ')' statement
| 'for' '(' expression? ';' expression? ';' expression? ')' statement
jump-statement: 'continue' ';'
| 'break' ';'
| 'return' expression? ';'
Expressions
expression: assignment-expression (',' assignment-expression)*
assignment-expression: logical-or-expression
| unary-expression assignment-operator assignment-expression
assignment-operator: '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
constant-expression: logical-or-expression
logical-or-expression: logical-and-expression ('||' logical-and-expression)*
logical-and-expression: inclusive-or-expression ('&&' inclusive-or-expression)*
inclusive-or-expression: exclusive-or-expression ('|' exclusive-or-expression)*
exclusive-or-expression: and-expression ('^' and-expression)*
and-expression: equality-expression ('&' equality-expression)*
equality-expression: relational-expression (equality-operator relational-expression)*
equality-operator: '==' | '!='
relational-expression: shift-expression (relational-operator shift-expression)*
relational-operator: '<' | '>' | '<=' | '>='
shift-expression: additive-expression (shift-operator additive-expression)*
shift-operator: '<<' | '>>'
additive-expression: multiplicative-expression (additive-operator multiplicative-expression)*
additive-operator: '+' | '-'
multiplicative-expression: cast-expression (multiplicative-operator cast-expression)*
multiplicative-operator: '*' | '/' | '%'
cast-expression: unary-expression
| '(' type-name ')' cast-expression
type-name: type-specifier '*'*
unary-expression: postfix-expression
| '++' unary-expression
| '--' unary-expression
| unary-operator cast-expression
| 'sizeof' unary-expression
| 'sizeof' '(' type-name ')'
unary-operator: '&' | '*' | '+' | '-' | '~' | '!'
postfix-expression: primary-expression postfix*
postfix: '[' expression ']'
| '(' arguments? ')'
| '.' identifier
| '->' identifier
| '++'
| '--'
arguments: assignment-expression (',' assignment-expression)*
primary-expression: identifier
| constant
| string
| '(' expression ')'
constant: integer-constant
| character-constant
Some remarks
- You may feel dizzy about upper contents at first. Try this: pick a simple C program and decompose it by using the grammar.
- You may assume that sizeof() can return a certain value during the compilation stage. Furthermore, the parameters of
sizeof()can only be types or variables. - To simplify the grammar, we will not accept improper initialization. (For example,
int a[3][3]={1,{1,2},{{{{4}}}}};will not be in the testcases although it can be accepted by gcc. However,int a[5][5]={{1},{2,3}};should be accepted.) - Something such like
int a,b,c;c=++b+++a;orint a(int b(int c));will not be tested although it can be accepted by the grammar. - some other keywords like double, static, const will not occur in test-cases.
- Most important: Your answer should ALWAYS be identical to the answer that gcc gives.