Expand description
Grammar parser.
This module parses the following grammar (minus comments, which are ignored):
program -> item* EOF;
item -> function | global | extern_fn | struct_def; // TODO types.
extern_fn -> 'extern' 'fn' identifier '(' function_argument ( ',' function_argument )* ','? ')' return_decl? ;
global -> 'var' identifier ':' type '=' static_initializer ';' ;
struct_def -> 'struct' identifier '{' ( struct_field ( ',' struct_field )* ','? )? '}' ;
struct_field -> identifier ':' type ;
static_initializer -> right_hand_expression ; // The language does not currently support function calls.
function -> 'fn' identifier '(' function_argument ( ',' function_argument )* ','? ')' return_decl? body ;
function_argument -> identifier ':' '&'? type ;
return_decl -> '->' type ;
type -> identifier ;
body -> '{' statement '}' ;
statement -> 'var' identifier (':' type)? '=' right_hand_expression ';' (statement)?
| 'return' right_hand_expression? ';' (statement)?
| 'break' ';' (statement)?
| 'continue' ';' (statement)?
| 'if' condition body ( 'else' body )? (statement)?
| 'loop' body (statement)?
| 'while' condition body (statement)?
| 'for' identifier ( ':' type )? 'in' condition body (statement)?
| body (statement)?
| expression ';' (statement)?
| right_hand_expression // implicit return statmenet
expression -> (left_hand_expression '=')? right_hand_expression ;
// A place: a variable, a whole-value dereference, or a path of field accesses.
left_hand_expression -> '*' identifier
| identifier ( '.' identifier )* ; // Should be a valid expression, too.
// `condition` (used by `if`/`while`/`for`) is identical to `right_hand_expression`
// except a *top-level* struct literal is not allowed, so a `{` unambiguously begins
// the following block. Struct literals remain reachable inside parentheses.
right_hand_expression -> binary2 ( '||' binary2 )* ;
condition -> right_hand_expression ; // minus a top-level struct_literal in `primary`
binary2 -> binary3 ( '&&' binary3 )* ;
binary3 -> binary4 ( ( '<' | '<=' | '>' | '>=' | '==' | '!=' ) binary4 )* ;
binary4 -> binary5 ( '|' binary5 )* ;
binary5 -> binary6 ( '^' binary6 )* ;
binary6 -> binary7 ( '&' binary7 )* ;
binary7 -> binary8 ( ( '<<' | '>>' ) binary8 )* ;
binary8 -> binary9 ( ( '+' | '-' ) binary9 )* ;
binary9 -> unary ( ( '*' | '/', '%' ) unary )* ;
unary -> ('!' | '-' | '&' | '*' )* postfix ;
postfix -> primary ( '.' identifier )* ; // field access binds tighter than any unary prefix
primary -> literal
| identifier struct_literal // only where struct literals are allowed (see `condition`)
| identifier ( '(' call_arguments ')' )?
| '(' right_hand_expression ')' ;
struct_literal -> '{' ( struct_literal_field ( ',' struct_literal_field )* ','? )? '}' ;
struct_literal_field -> identifier ':' right_hand_expression ;
call_arguments -> right_hand_expression ( ',' right_hand_expression )* ','? ;
literal -> NUMBER | STRING | 'true' | 'false' ;NUMBER: Non-negative integers (binary, decimal, hexadecimal) and floats.
STRING: Double-quoted strings with escape sequences.
Structs§
- Default
Type Set - Use 64-bit integers and 64-bit floats (default).
- Type
Set32 - Use 32-bit integers and floats.
- Type
Set128 - Use 128-bit integers and 64-bit floats.
Traits§
- Float
Parser - Parse literals into Somni floats.
- IntParser
- Parse literals into Somni integers.
- TypeSet
- Defines the numeric types used in the parser.