(* ================================================================ *)
(* Mathic Grammar *)
(* ================================================================ *)
(* *)
(* Notation: *)
(* [ A ] -- optional (zero or one) *)
(* { A } -- repetition (zero or more) *)
(* UPPER -- terminal token class (IDENT, INT, etc.) *)
(* lower -- nonterminal *)
(* *)
(* LL(1) grammar *)
(* ================================================================ *)
(* ================================================================ *)
(* Program *)
(* ================================================================ *)
program = top_decl { top_decl } ;
top_decl = func_decl | struct_decl ;
func_decl = 'df' IDENT '(' [ param_list ] ')' [ type ] block ;
struct_decl = 'struct' IDENT '{' [ struct_fields ] '}' ;
(* ================================================================ *)
(* Declarations *)
(* ================================================================ *)
declaration = func_decl
| struct_decl
| var_decl
| sym_decl
;
var_decl = 'let' IDENT ':' IDENT '=' expr ';' ;
sym_decl = 'sym' IDENT ':' type ';' ;
(* ================================================================ *)
(* Statements *)
(* ================================================================ *)
stmt = declaration
| for_stmt
| while_stmt
| if_stmt
| return_stmt
| expr_stmt
| block
;
for_stmt = 'for' IDENT 'in' expr_no_init '..' expr_no_init block
| 'for' IDENT 'in' expr_no_init block ;
while_stmt = 'while' expr_no_init block ;
if_stmt = 'if' expr_no_init block [ 'else' block ] ;
return_stmt = 'return' expr ';' ;
expr_stmt = expr ';' ;
block = '{' { stmt } '}' ;
(* ================================================================ *)
(* Expressions *)
(* ================================================================ *)
(* Precedence (lowest to highest): *)
(* 1. or *)
(* 2. and *)
(* 3. == != *)
(* 4. < > <= >= *)
(* 5. + - *)
(* 6. * / *)
(* 7. unary (! -) *)
(* 8. call (() [] .) *)
expr = assignment ;
assignment = IDENT { '.' IDENT } '=' expr
| initializer
;
initializer = expr_no_init [ struct_init ] ;
expr_no_init = logical_or ;
logical_or = logical_and { 'or' logical_and } ;
logical_and = equality { 'and' equality } ;
equality = comparison { ( '==' | '!=' ) comparison } ;
comparison = term { ( '>' | '>=' | '<' | '<=' ) term } ;
term = factor { ( '+' | '-' ) factor } ;
factor = unary { ( '*' | '/' ) unary } ;
unary = ( '!' | '-' ) unary
| call
;
call = primary { '(' [ arg_list ] ')' | '[' expr ']' | '.' IDENT } ;
struct_init = '{' IDENT ':' expr { ',' IDENT ':' expr } '}' ;
primary = 'true' | 'false' | IDENT | INT | FLOAT | STRING | '(' expr ')' ;
(* ================================================================ *)
(* Utilities *)
(* ================================================================ *)
param_list = ( IDENT ':' type ) { ',' ( IDENT ':' type ) } ;
struct_fields = [ 'pub' ] IDENT ':' type { ',' [ 'pub' ] IDENT ':' type } ;
arg_list = expr { ',' expr } ;
type = IDENT { '<' IDENT '>' } ;
(* ---- Terminal token classes ---- *)
(* IDENT : [a-zA-Z_][a-zA-Z0-9_]* *)
(* INT : '0' | [1-9] [0-9]* *)
(* FLOAT : [0-9]+ '.' [0-9]+ *)
(* STRING : '"' [^"]* '"' *)