ROOT ::= INSTR* INSTR ::= | LEXPR semicolon | BEXPR EXPR ::= LEXPR | BEXPR LEXPR ::= | OR | ASSERT EXPR | VARDECL | CONSTDECL | ASSIGN BEXPR ::= | BLOCK | IF IF ::= | if EXPR BLOCK | if EXPR BLOCK else BLOCK | if EXPR BLOCK else IF BLOCK ::= obrace INSTR* cbrace VARDECL ::= var ident colon type? assign EXPR CONSTDECL ::= ident colon type? assign EXPR ASSIGN ::= ident assign EXPR OR ::= AND (or AND)* AND ::= EQNE (and EQNE)* EQNE ::= CMP ((eq|ne) CMP)? CMP ::= TERM ((lt|le|gt|ge) TERM)? TERM ::= FACTOR ((add|sub) FACTOR)* FACTOR ::= POW ((mul|div|mod) POW)* POW ::= NOT (pow NOT)? NOT ::= not* LITERAL LITERAL ::= ident | BUILTIN | opar EXPR cpar BUILTIN ::= bool | int | float | string