program -> declaration* EOF; declaration -> proc_decl | var_decl | statement; proc_decl -> "proc" IDENTIFIER block; var_decl -> "var" IDENTIFIER ("=" expression)? ";"; statement -> expression_statement | for_statement | if_statement | block; expression_statement -> expression ";"; for_statement -> "for" "(" (var_decl|expression_statement|";") expression? ";" expression? ")" statement; if_statement -> "if" "(" expression ")" statement ("else" statement)?; block -> "{" declaration* "}"; expression -> assignment; assignment -> (call ".")? IDENTIFIER "=" assignment | logic_or; logic_or -> logic_and ("or" logic_and)*; logic_and -> equality ("and" equality)*; equality -> comparison (("!=" | "==") comparison)*; comparison -> term ((">" | ">=" < "<" | "<=") term)*; term -> factor (("-" | "+") factor)*; factor -> unary (("/" | "*") unary)*; unary -> ("!" | "-") unary | call; call -> primary "(" arguments? ")"; primary -> "true" | "false" | NUMBER | STRING | IDENTIFIER | "(" expression ")";