The main structure of lox's grammar is described as follows:
program → (declaration)* EOF
declaration → classDecl | funDecl | varDecl | statement
classDecl → "class" IDENTIFIER ("<" IDENTIFIER)?
"{" ( ("static")? function)* "}"
funDecl → "fun" function
function → IDENTIFIER "(" parameters? ")" block
parameters → IDENTIFIER ("," IDENTIFIER)*
varDecl → "var" IDENTIFIER ( "=" expression )? ";"
statement → exprStmt | forStmt | ifStmt | printStmt | returnStmt | whileStmt | breakStmt | block ;
exprStmt → expression ";"
forStmt → "for" "(" ( varDecl | exprStmt | ";" ) expression? ";" expression? ")" statement
ifStmt → "if" "(" expression ")" statement
( "else" statement )?
printStmt → "print" expression ";"
returnStmt → "return" expression? ";"
whileStmt → "while" "(" expression ")" statement
breakStmt → "break" ";"
block → "{" declaration* "}"
expression → assignment ;
assignment → ( call "." )? IDENTIFIER "=" assignment | ternary
ternary → logic_or ("?" logic_or ":" ternary)
logic_or → logic_and ( "or" logic_and )*
logic_and → equality ( "and" equality )*
anonymous_func → "FUN" function ";" | equality
equality → comparison ( ( "!=" | "==" ) comparison )*
comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )*
term → factor ( ( "-" | "+" ) factor )*
factor → unary ( ( "/" | "*" ) unary )*
unary → ( "!" | "-" ) unary | call
call → primary ( "(" arguments? ")" | "." IDENTIFIER )*
primary → "true" | "false" | "nil" | "this"
| NUMBER | STRING | IDENTIFIER | "(" expression ")"
| "super" "." IDENTIFIER | "[" elements? "]"
arguments → expression ("," expression)*
elements → expression ("," expression)*