treerack/examples/mml.treerack

267 lines
10 KiB
Plaintext
Raw Normal View History

2017-10-29 02:16:59 +02:00
ws:ws = " " | "\b" | "\f" | "\r" | "\t" | "\v";
wsc:ws = comment;
nl:alias = "\n";
2017-06-25 17:51:08 +02:00
2017-10-29 02:16:59 +02:00
line-comment-content:nows = [^\n]*;
line-comment:alias:nows = "//" line-comment-content;
2018-08-19 19:36:23 +02:00
block-comment-content:nows = ([^*] | "*" [^/])*;
2017-10-29 02:16:59 +02:00
block-comment:alias:nows = "/*" block-comment-content "*/";
comment-part:alias = line-comment | block-comment;
comment:alias = comment-part ("\n"? comment-part)*;
2017-06-25 17:51:08 +02:00
decimal-digit:alias = [0-9];
octal-digit:alias = [0-7];
hexa-digit:alias = [0-9a-fA-F];
2017-10-29 02:16:59 +02:00
decimal:alias:nows = [1-9] decimal-digit*;
octal:alias:nows = "0" octal-digit*;
hexa:alias:nows = "0" [xX] hexa-digit+;
int = decimal | octal | hexa;
2017-06-25 17:51:08 +02:00
2017-10-29 02:16:59 +02:00
exponent:alias:nows = [eE] [+\-]? decimal-digit+;
float:nows = decimal-digit+ "." decimal-digit* exponent?
| "." decimal-digit+ exponent?
| decimal-digit+ exponent;
2017-06-25 17:51:08 +02:00
2017-10-29 02:16:59 +02:00
string:nows = "\"" ([^\\"] | "\\" .)* "\"";
2017-06-25 17:51:08 +02:00
true = "true";
false = "false";
bool:alias = true | false;
2018-08-19 19:36:23 +02:00
symbol:nows = [a-zA-Z_][a-zA-Z_0-9]*;
2017-10-29 02:16:59 +02:00
spread-expression = primary-expression "...";
2018-08-19 19:36:23 +02:00
list-sep:alias = (nl | ",")+;
2017-06-25 17:51:08 +02:00
list-item:alias = expression | spread-expression;
expression-list:alias = list-item (list-sep list-item)*;
2018-08-19 19:36:23 +02:00
list-fact:alias = "[" list-sep? expression-list? list-sep? "]";
2017-06-25 17:51:08 +02:00
list = list-fact;
2017-10-29 02:16:59 +02:00
mutable-list = "~" nl* list-fact;
2017-06-25 17:51:08 +02:00
2018-08-19 19:36:23 +02:00
expression-key = "[" nl* expression nl* "]";
entry = (symbol | string | expression-key) nl* ":" nl* expression;
entry-list:alias = (entry | spread-expression) (list-sep (entry | spread-expression))*;
struct-fact:alias = "{" list-sep? entry-list? list-sep? "}";
struct = struct-fact;
mutable-struct = "~" nl* struct-fact;
channel = "<>" | "<" nl* expression nl* ">";
parameter-list:alias = symbol (list-sep symbol)*;
collect-parameter = "..." nl* symbol;
return = "return" (nl* expression)?;
block = "{" sep? statement-list? sep? "}";
function-fact:alias = "(" list-sep?
parameter-list?
(list-sep collect-parameter)?
list-sep? ")" nl*
(simple-statement | block);
function = "fn" nl* function-fact;
effect = "fn" nl* "~" nl* function-fact;
range-from = expression;
range-to = expression;
range:alias = range-from? nl* ":" nl* range-to?;
simple-indexer:alias = primary-expression "[" nl* expression nl* "]";
range-indexer:alias = primary-expression "[" nl* range nl* "]";
expression-indexer = simple-indexer | range-indexer;
symbol-indexer = primary-expression nl* "." nl* symbol;
function-application = primary-expression "(" list-sep? expression-list? list-sep? ")";
expression-group:alias = "(" nl* expression nl* ")";
2017-06-25 17:51:08 +02:00
primary-expression:alias = int
| float
| string
| bool
| symbol
| list
| mutable-list
| struct
| mutable-struct
| channel
| function
| effect
2018-08-19 19:36:23 +02:00
| expression-indexer
| symbol-indexer
| function-application
| receive
2017-06-25 17:51:08 +02:00
| expression-group;
2018-08-19 19:36:23 +02:00
binary-not = "^";
2017-06-25 17:51:08 +02:00
binary-and = "&";
2018-08-19 19:36:23 +02:00
binary-or = "|";
xor = "^";
2017-06-25 17:51:08 +02:00
and-not = "&^";
2018-08-19 19:36:23 +02:00
lshift = "<<";
rshift = ">>";
2017-06-25 17:51:08 +02:00
2018-08-19 19:36:23 +02:00
plus = "+";
minus = "-";
mul = "*";
div = "/";
mod = "%";
add = "+";
sub = "-";
2017-06-25 17:51:08 +02:00
2018-08-19 19:36:23 +02:00
logical-not = "!";
2017-06-25 17:51:08 +02:00
eq = "==";
not-eq = "!=";
less = "<";
less-or-eq = "<=";
greater = ">";
greater-or-eq = ">=";
2018-08-19 19:36:23 +02:00
logical-and = "&&";
logical-or = "||";
2017-06-25 17:51:08 +02:00
2018-08-19 19:36:23 +02:00
chain:alias = "->";
2017-06-25 17:51:08 +02:00
2018-08-19 19:36:23 +02:00
unary-operator:alias = plus | minus | binary-not | logical-not;
unary-expression = unary-operator primary-expression;
2017-06-25 17:51:08 +02:00
2018-08-19 19:36:23 +02:00
binary-op0:alias = binary-and | and-not | lshift | rshift | mul | div | mod;
binary-op1:alias = binary-or | xor | add | sub;
2017-06-25 17:51:08 +02:00
binary-op2:alias = eq | not-eq | less | less-or-eq | greater | greater-or-eq;
binary-op3:alias = logical-and;
binary-op4:alias = logical-or;
operand0:alias = primary-expression | unary-expression;
operand1:alias = operand0 | binary0;
operand2:alias = operand1 | binary1;
operand3:alias = operand2 | binary2;
operand4:alias = operand3 | binary3;
operand5:alias = operand4 | binary4;
2018-08-19 19:36:23 +02:00
binary0 = operand0 (binary-op0 operand0)+;
binary1 = operand1 (binary-op1 operand1)+;
binary2 = operand2 (binary-op2 operand2)+;
binary3 = operand3 (binary-op3 operand3)+;
binary4 = operand4 (binary-op4 operand4)+;
chaining = operand5 (nl* chain nl* operand5)+;
2017-06-25 17:51:08 +02:00
2018-08-19 19:36:23 +02:00
binary-expression:alias = binary0
| binary1
| binary2
| binary3
| binary4
| chaining;
2017-06-25 17:51:08 +02:00
2017-10-29 02:16:59 +02:00
ternary-expression = expression nl* "?" nl* expression nl* ":" nl* expression;
2017-06-25 17:51:08 +02:00
expression:alias = primary-expression
| unary-expression
| binary-expression
| ternary-expression;
2018-08-19 19:36:23 +02:00
if = "if" nl* expression nl* block
(nl* "else" nl* "if" nl* expression nl* block)*
(nl* "else" nl* block)?;
default = "default" nl* ":";
default-line:alias = default ";"* statement?;
case = "case" nl* expression nl* ":";
case-line:alias = case ";"* statement?;
switch = "switch" nl* expression? nl* "{" sep?
((case-line | default-line) (sep (case-line | default-line | statement))*)?
sep? "}";
receive = "<<>" primary-expression;
receive-definition = "let" nl* symbol nl* receive;
receive-assignment = "set" nl* symbol nl* receive;
receive-statement:alias = receive-definition
| receive-assignment;
send = primary-expression "<<>" primary-expression;
communication:alias = receive | receive-statement | send;
select-case = "case" nl* communication nl* ":";
select-case-line:alias = select-case ";"* statement?;
select = "select" nl* "{" sep?
((select-case-line | default-line)
(sep (select-case-line | default-line | statement))*)?
sep? "}";
go = "go" nl* function-application;
defer = "defer" nl* function-application;
range-over-expression = symbol nl* "in" nl* (expression | range) | range;
loop-expression:alias = expression | range-over-expression;
loop = "for" ((nl* loop-expression)? nl* block | nl* block);
2018-08-19 22:40:01 +02:00
assign-capture:alias = primary-expression (nl* "=")? nl* expression;
2018-08-19 19:36:23 +02:00
assign-capture-list:alias = assign-capture (list-sep assign-capture)*;
assign-set:alias = "set" nl* assign-capture;
2018-08-19 22:40:01 +02:00
assign-eq:alias = primary-expression nl* "=" nl* expression;
assign-group:alias = "set" nl* "(" (list-sep assign-capture-list)? list-sep? ")";
assignment = assign-set | assign-eq | assign-group;
2018-08-19 19:36:23 +02:00
value-capture-fact:alias = symbol (nl* "=")? nl* expression;
2017-06-25 17:51:08 +02:00
value-capture = value-capture-fact;
2017-10-29 02:16:59 +02:00
mutable-capture = "~" nl* value-capture-fact;
value-definition = "let" nl* (value-capture | mutable-capture);
2018-08-19 19:36:23 +02:00
mixed-capture-list:alias = (value-capture | mutable-capture) (list-sep (value-capture | mutable-capture))*;
value-capture-list:alias = value-capture (list-sep value-capture)*;
value-definition-group = "let" nl* "(" list-sep? mixed-capture-list? list-sep? ")";
mutable-definition-group = "let" nl* "~" nl* "(" list-sep? value-capture-list? list-sep? ")";
function-definition-fact:alias = symbol nl* function-fact;
function-capture = function-definition-fact;
effect-capture = "~" nl* function-definition-fact;
function-definition = "fn" nl* (function-capture | effect-capture);
function-capture-list:alias = function-capture (list-sep function-capture)*;
mixed-function-capture-list:alias = (function-capture | effect-capture)
(list-sep (function-capture | effect-capture))*;
function-definition-group = "fn" nl* "(" list-sep?
mixed-function-capture-list?
list-sep? ")";
effect-definition-group = "fn" nl* "~" nl* "(" list-sep?
function-capture-list?
list-sep? ")";
2017-06-25 17:51:08 +02:00
definition:alias = value-definition
| value-definition-group
| mutable-definition-group
| function-definition
| function-definition-group
| effect-definition-group;
2018-08-19 19:36:23 +02:00
require-inline = ".";
require-fact = string
| (symbol | require-inline) (nl* "=")? nl* string;
require-fact-list:alias = require-fact (list-sep require-fact)*;
require-statement:alias = "require" nl* require-fact;
require-statement-group:alias = "require" nl* "(" list-sep?
require-fact-list?
list-sep? ")";
require = require-statement | require-statement-group;
export = "export" nl* definition;
simple-statement:alias = expression
| send
| go
| defer
| assignment
| simple-statement-group;
simple-statement-group:alias = "(" nl* simple-statement nl* ")";
statement:alias = simple-statement
| return
| if
| switch
| select
| loop
| definition
| require
| export
| statement-group;
statement-group:alias = "(" nl* statement nl* ")";
sep:alias = (";" | nl)+;
statement-list:alias = statement (sep statement)*;
shebang-command = [^\n]*;
shebang = "#!" shebang-command "\n";
mml:root = shebang? sep? statement-list? sep?;