CSE 3341: Context-Free Grammar for simpleC, Project 4
<program> ::= <ne-func-def-list> // non-empty list of function definitions
<ne-func-def-list> ::= <func-def> | <func-def> <ne-func-def-list>
<func-def> ::= int id ( <formal-param-list> ) { <decl-list> <stmt-list> }
<formal-param-list> ::= ε | <ne-formal-param-list>
<ne-formal-param-list> ::= int id | int id , <ne-formal-param-list>
<decl-list> ::= ε | <decl> <decl-list>
<decl> ::= int id ; | int id = <expr>;
<stmt-list> ::= ε | <stmt> <stmt-list>
<stmt> ::= <expr> ; | ε ; | read id ; | print <expr> ; | if ( <expr> ) <stmt> | if ( <expr> ) <stmt> else <stmt> | { <stmt-list> }
| while ( <expr> ) <stmt> | return <expr> ;
<actual-param-list> ::= ε | <ne-actual-param-list>
<ne-actual-param-list> ::= <expr> | <expr> , <ne-actual-param-list>
<expr> ::= const | id | ( <expr> ) | <binary-expr> | <unary-expr> | id ( <actual-param-list> )
<binary-expr> ::= <expr> + <expr> | <expr> - <expr> | <expr> * <expr> | <expr> / <expr> | <expr> % <expr> | id = <expr>
| <expr> < <expr> | <expr> <= <expr> | <expr> > <expr> | <expr> >= <expr> | <expr> == <expr> | <expr> != <expr>
| <expr> && <expr> | <expr> || <expr>
<unary-expr> ::= - <expr> | ! <expr>
For simplicity, this grammar is ambiguous. The parser implementation should ensure that the precedence and associativity of these operators match those of the corresponding C operators.