1root ::= (declaration)*
 2
 3declaration ::= dataType identifier "(" parameter? ")" "{" statement* "}"
 4
 5dataType  ::= "int" ws | "float" ws | "char" ws
 6identifier ::= [a-zA-Z_] [a-zA-Z_0-9]*
 7
 8parameter ::= dataType identifier
 9
10statement ::=
11    ( dataType identifier ws "=" ws expression ";" ) |
12    ( identifier ws "=" ws expression ";" ) |
13    ( identifier ws "(" argList? ")" ";" ) |
14    ( "return" ws expression ";" ) |
15    ( "while" "(" condition ")" "{" statement* "}" ) |
16    ( "for" "(" forInit ";" ws condition ";" ws forUpdate ")" "{" statement* "}" ) |
17    ( "if" "(" condition ")" "{" statement* "}" ("else" "{" statement* "}")? ) |
18    ( singleLineComment ) |
19    ( multiLineComment )
20
21forInit ::= dataType identifier ws "=" ws expression | identifier ws "=" ws expression
22forUpdate ::= identifier ws "=" ws expression
23
24condition ::= expression relationOperator expression
25relationOperator ::= ("<=" | "<" | "==" | "!=" | ">=" | ">")
26
27expression ::= term (("+" | "-") term)*
28term ::= factor(("*" | "/") factor)*
29
30factor ::= identifier | number | unaryTerm | funcCall | parenExpression
31unaryTerm ::= "-" factor
32funcCall ::= identifier "(" argList? ")"
33parenExpression ::= "(" ws expression ws ")"
34
35argList ::= expression ("," ws expression)*
36
37number ::= [0-9]+
38
39singleLineComment ::= "//" [^\n]* "\n"
40multiLineComment ::= "/*" ( [^*] | ("*" [^/]) )* "*/"
41
42ws ::= ([ \t\n]+)