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 ::= dcl_stmt*
dcl_stmt ::= var_stmt | fn_stmt
var_stmt ::= perm_ident ident_token type? (',' ident_token type?)* ('=' append_exp (',' append_exp)*)? ';'
fn_stmt ::= fn_type block
block ::= '{' stmt* '}'
stmt ::= if_stmt | match_stmt | block | while_stmt | break_stmt | cont_stmt | each_stmt | return_stmt | do_stmt | exp_stmt | ';'
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' (ident_token ':')? var_list 'in' (exp|'...') block
break_stmt ::= 'break' ';'
cont_stmt ::= 'continue' ';'
return_stmt ::= 'return' this_exp? ';'
do_stmt ::= 'do' exp? block
exp_stmt ::= this_exp ';'
this_exp ::= exp (('using' exp)? block)?
var_list ::= perm_ident? ident_token type (',' perm_ident? ident_token type)*
/* Type declarations */
type ::= genqualname | nbrtype | arraytype | optiontype | ptrtype | reftype | fntype | structtype
nbrtype ::= 'Bool' | 'i8' | 'i16' | 'i32' | 'i64' | 'isize' | 'u8' | 'u16' | 'u32' | 'u64' | 'usize' | 'f32' | 'f64'
arraytype ::= '[' integer_token? ']' type
optiontype ::= '?' type
ptrtype ::= '*' type
lifetype ::= lifetime_token type
reftype ::= '&' region-type? lifetime_token? perm_type? type
perm_ident ::= 'mut' | 'imm' | 'uni' | 'ro' | 'mutx' | 'id' | genqualname
region_type ::= genqualname
fntype ::= 'fn' (ident_token)? '(' fnparm (',' fnparm)* ')' (type (',' type)*)?
fnparm ::= perm_ident? ident_token type? ('=' (literal | ident))?
structtype ::= 'struct' ident_token? ('{' structstmt (',' structstmt)* '}')?
structstmt ::= var_stmt | fn_stmt | 'mixin' genqualname
/* General Use Expressions (with possible assignments) */
exp ::= assgn_exp
assgn_exp ::= tuple_exp ('=' | '+='|'-='|'*='|'/='|'%='|'&='|'|='|'^='|'<<='|'>>='|'<-') exp
tuple_exp ::= simple_exp (',' simple_exp)*
/* Expressions without any assignments */
simple_exp ::= if_exp | match_exp | while_exp | each_exp | loop_exp | or_exp
or_exp ::= and_exp ('or' and_exp)?
and_exp ::= not_exp ('and' not_exp)?
not_exp ::= '!'* compare_exp
compare_exp ::= range_exp (('=='|'!='|'~~'|'<=>'|'<'|'<='|'>'|'>=') range_exp)?
range_exp ::= bit_exp ('..' bit_exp)? ('..' bit_exp)?
bit_exp ::= shift_exp (('|'|'&'|'^') shift_exp)*
shift_exp ::= arith_exp (('<<' | '>>') arith_exp)?
arith_exp ::= cast_exp (('+'|'-'|'*'|'/'|'%') cast_exp)*
as_exp ::= prefix_exp (('as'|'into') type)?
prefix_exp ::= ('.'|'<-'|'-'|'~'|'*'|'++'|'--')* term | addr
addr ::= ('&'|'&<'|'&[]') ((region_type perm_type? suffix_exp) | (perm_type? (fn_stmt | (term suffix*))))
suffix_exp ::= term suffix*
suffix ::= '++'|'--'| ('.' property) | ('(' (simple_exp (',' simple_exp)*)? ')') | ('[' (simple_exp (',' simple_exp)*)? ']')
property ::= ident_token | symbol_token | integer_token
term ::= literal | genqualname | pseudo | '(' exp ')'
genqualname ::= (ident_token '::')* ident_token ('[' type (',' type)* ']')?
pseudo ::= 'self' | 'this'
/* Literals and other tokens */
literal ::= float_token | integer_token | text_token | symbol_token | 'true' | 'false' | array_lit
array_lit ::= '[' (simple_exp (',' simple_exp) ';')? simple_exp (',' simple_exp) ']'
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'))+
lifetime_token ::= '\'' ident_token
text_token ::= '"' any_char '"'
symbol_token ::= "'" any_char "'"
ident_token ::= '`' any_char* '`' | ('@' | '#' | '_' | alpha_char) (alpha_char | ('0'-'9') | '$' | '_')*
Railroad diagrams courtesy of the Railroad Diagram Generator.