Here is the complete grammar in EBNF form. It differs slighlty in factoring from the syntax forms given in this online reference, so that all precedence is explicit in the rules.
<program> ::= <expr>
<expr> ::= <simple_expr>
<assignment>
<if_expr>
<while_loop>
<do_loop>
<for_loop>
<loop_exit>
<variable_decls>
<function_def>
<function_return>
<context_expr>
<on_change>
<max_command>
<utility>
<variable_decls> ::= ( local | global ) <decl> { , <decl> }
<decl> ::= <name> [ = <expr> ]
<assignment> ::= <destination> = <expr>
<destination> += <expr>
<destination> -= <expr>
<destination> *= <expr>
<destination> /= <expr>
<destination> ::= <name>
<property>
<index>
<if_expr> ::= if <expr> then <expr> [ else <expr> ]
if <expr> do <expr>
<while_loop> ::= while <expr> do <expr>
<do_loop> ::= do <expr> while <expr>
<loop-exit> ::= exit [ with <expr> ]
<for_loop> ::= for <name> ( in | = ) <source> (do | collect) <expr>
<source> ::= <expr> to <expr> [ by <expr> ] [ where <expr> ]
<expr> [ where <expr> ]
<function_def> ::= (function | fn) <name> { <argument> } = <expr>
<argument> ::= <name>
<name>: [<operand>]
-- keyword arg with optional default value
<function_return> ::= return <expr>
<context_expr> ::= <context> { , <context> } <expr>
<context> ::= [ with ] animate <boolean_expr>
with redraw <boolean_expr>
with pivot <boolean_expr>
at level <operand>
at time <operand>
in <operand>
[ in ] coordys ( local | world | parent | <operand> )
about ( pivot | selection | coordsys | <operand> )
undo <boolean_expr>
<utility> ::= utility <name> <string> ( { <utility_clause> } )
<utility_clause> ::= local <decl> { , <decl> }
<rollout_item>
<rollout_handler>
<rollout_handler> ::= on <name> <name> { <name> } do <expr>
<rollout_item> ::= label <name> [ <string> ] { <name>: <operand> }
button <name> [ <string> ] { <name>: <operand> }
spinner <name> [ <string> ] { <name>: <operand> }
pickbutton <name> [ <string> ] { <name>: <operand> }
radiobuttons <name> [ <string> ] { <name>: <operand>}
checkbox <name> [ <string> ] { <name>: <operand> }
<simple_expr> ::= <and> { or <and> }
<and> ::= <not> { and <not> }
<not> ::= [ not ] <compare>
<compare> ::= <plus> { == <plus> }
<plus> { != <plus> }
<plus> { > <plus> }
<plus> { < <plus> }
<plus> { >= <plus> }
<plus> { <= <plus> }
<plus> ::= <term> { + <term> }
<term> { - <term> }
<term> ::= <power> { * <power> }
<power> { / <power> }
<power> ::= <conversion> { ^ <conversion> } -- right-associative
<conversion> ::= <function_call> as <factor>
<function_call> ::= <operand> ()
<operand> { <parameter> }+ -- up to an end of line or lower
-- precedence token
<parameter> ::= <operand>
<name>: <operand>
<operand> ::= <factor>
<property>
<index>
<property>
::=
<operand> . <name>
-- properties and indexes left associate
<index> ::= <operand> [ <expr> ]
<factor> ::= <number>
<string>
<path_name>
<name>
<array_literal>
on
off
-<expr> -- unary minus
( <expr> ) -- nested expression
<expr_seq>
? -- last Listener result
'<factor>
<expr_seq> ::= ( <expr> { (; | <eol>) <expr> } )
<point3_literal> ::= [ <expr>, <expr>, <expr> ]
<array_literal> ::= #()
#( <expr> { , <expr> } )
<name_literal> ::= #<name>
<path_name> ::= $<path>
<path> ::= [ / ] [ <levels> ] <level_name>
<levels> ::= <level> { / <level> }
<level> ::= <level_name>
...
'<any_characters>'
<level_name> ::= { <alphanumeric > | _ | * | ? | \ }