program -> statement* EOF ; statement -> exprStmt | printStmt | declaration | block ; exprStmt -> expression ";" ; printStmt -> "print" expression ";" ; declaration -> "var" IDENTIFIER ( "=" expression )? ";" ; block -> "{" statement* "}" ; expression -> assignment assignment -> IDENTIFIER "=" assignment | equality ; equality -> comparison ( ( "==" | "!=" ) comparison )* ; comparison -> term ( ">" | ">=" | "<" | "<=" term )* ; term -> factor ( ( "+" | "-" ) factor )* factor -> unary ( ( "*" | "/" ) unary )* ; unary -> ( "!" | "-" ) unary | primary ; primary -> "(" expression ")" | IDENTIFIER | NUMBER | STRING | "true" | "false" | "nil" ;