跳转到内容

Compiler 2014: Grammar

来自ACM Class Wiki

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; or int 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.