Program   ::= module Id ; Block Id .
Block     ::= { Decl ;} begin StmtList end
Decl      ::= ConstDecl | ProcDecl | VarDecl
ConstDecl ::= const ConstDeclItem { , ConstDeclItem }
ConstDeclItem ::= Id : Type = ConstExpr
ConstExpr ::= Expr
VarDecl   ::= var VarDeclItem { , VarDeclItem }
VarDeclItem ::= Id : Type
ProcDecl  ::= procedure Id ([ FormalDecl {, FormalDecl} ] )[: Type] ; Block Id
FormalDecl::= [var] Id : Type
Type      ::= int | bool | array [ ConstExpr ] of Type
StmtList  ::= { Stmt ; }
Stmt      ::= CallStmt | AssignStmt | OutStmt | IfStmt | WhileStmt | ForStmt | BreakStmt | ReturnStmt
CallStmt  ::= Id ( [ Exprs ] )
AssignStmt::= Lvalue := Expr
Lvalue    ::= Id | LValue [ Expr ]
OutStmt   ::= output := Expr
IfStmt    ::= if Test then StmtList [ else StmtList ] end
WhileStmt ::= while Expr do StmtList end
ForStmt   ::= for Id := Expr to Expr do StmtList end
BreakStmt ::= break
ReturnStmt ::= return [ Expr ]
Relop     ::= <= | <> | < | >= | > | =
Exprs     ::= Expr {, Expr }
Expr      ::= Conjunction { or Conjunction }
Conjunction ::= Test { and Test }
Test      ::= odd Sum | Sum Relop Sum | Sum
Sum       ::= Term { (+ | -) Term }
Term      ::= Factor { (* | /) Factor }
Factor    ::= - Factor | LValue | Id( [ Exprs ] ) | Integer | true | false |
input | ( Expr )