The syntax is specified below using XML's Extended BNF Notation. The diagrams do not attempt to convey operator precedence within a rule (see Reserved Tokens for that information.
/* Statements */
program ::= stmts
stmts ::= (( if_stmt | match_stmt | while_stmt | break_stmt | cont_stmt | each_stmt | return_stmt | wait_stmt | do_stmt | exp_stmt )? ';' )*
block ::= '{' stmts '}'
wait_stmt ::= 'wait' block
do_stmt ::= 'do' exp? block
if_stmt ::= 'if' logic_exp block ( 'elif' logic_exp block )* ( 'else' block )?
match_stmt ::= 'match' exp ('using' exp)? ('into' var_list)? ('with' exp ('into' var_list)? block)+ ('else' block)?
while_stmt ::= 'while' logic_exp block
each_stmt ::= 'each' (name_token ':')? var_list 'in' (exp|'...') block
break_stmt ::= 'break' clause
cont_stmt ::= 'continue' clause
return_stmt ::= 'return' this_exp? clause
exp_stmt ::= this_exp clause
this_exp ::= exp (('using' exp)? block)?
clause ::= ('if' logic_exp | 'while' logic_exp | 'each' (name_token ':')? var_list 'in' (exp|'...'))*
/* Variable definitions */
var_list ::= name_token ( ',' name_token )*
var_defs ::= name_token ( '=' append_exp ) (',' name_token ('=' append_exp))*
/* General Use Expressions (with possible assignments) */
exp ::= async_exp
async_exp ::= (('^' | 'async') ( assgn_exp | block)) | assgn_exp
assgn_exp ::= ( 'local'? lvar (',' lvar)* '=' | ('local')? lvar ('+='|'-='|'*='|'/=') | property (':'|':=') )* append_exp (',' append_exp)*
lvar ::= (suffix | name_token) suffix*
/* Expressions without any assignments */
append_exp ::= ('<<' | '>>' | (ternary_exp ('<<' | '>>')))? ternary_exp
ternary_exp ::= logic_exp ('?' exp 'else' exp)?
logic_exp ::= not_exp (('||'|'&&'|'and'|'or') not_exp)*
not_exp ::= ('!'|'not')* eval_exp
eval_exp ::= range_exp (('=='|'!='|'==='|'~~'|'<=>'|'<'|'<='|'>'|'>=') range_exp)?
range_exp ::= arith_exp ('..' arith_exp)? ('..' arith_exp)?
arith_exp ::= prefix_exp (('+'|'-'|'*'|'/'|'%'|'**') prefix_exp)*
prefix_exp ::= ('-'*|'@')? term
term ::= (value | suffix | ('+' value (text_token|symbol_token)?)) suffix*
suffix ::= (('.'|'.:'|'::') property)? ('(' (if_exp (',' if_exp)*)? ')' | '[' (append_exp (',' append_exp)*)? ']')?
property ::= name_token | symbol_token | integer_token | '(' exp ')'
value ::= literal | name_token | pseudo | '(' exp ')' | meth_val | 'yield' this_exp?
pseudo ::= 'self' | 'this' | 'context' | 'selfmethod' | 'baseurl' | '...'
/* Methods */
meth_val ::= method | closure
method ::= '*'? '[' var_defs (',' '...')? ']' block
closure ::= '<' var_defs '>' (value | '{' exp ';' exp ';' '}')
/* Literals */
literal ::= float_token | integer_token | text_token | symbol_token | url_token | 'true' | 'false' | 'null'
float_token ::= (('0'-'9') ('0'-'9')*) '.' ('0'-'9')* (('e'|'E') ('-'|'+')? ('0'-'9')+)?
integer_token ::= (('0'-'9') ('0'-'9')*) | '0x' (('0'-'9')|('a'-'f')|('A'-'F'))+
text_token ::= '"' any_char '"'
symbol_token ::= "'" any_char "'"
url_token ::= "@" any_char (space | tab | lf | cr)
name_token ::= ('$' | '_' | alpha_char) (alpha_char | ('0'-'9') | '$' | '_')* ('?')?
Railroad diagrams courtesy of the Railroad Diagram Generator.