file ::= fileelem | [ file ]
fileelem ::= func | class | constant
func ::= FuncName funcbody
class ::= Class '<' Class '{' classbody '}'
classbody := classelem | [ classbody ]
classelem := func | Constant | var
funcbody ::= '(' [ parlist ] ')' block
expr ::= while expr block |
for Name in expr ')' block |
let letlist block |
funcliteral |
if expr block { else if expr block } [ else block ]
expr | '(' |
nil | false | true | Number | String |
expr binop expr |
unop expr |
hash | array
expr '[' expr ']' |
expr '[' expr ']' '=' |
expr '(' [ arglist ] ')' [ funcliteral ] |
Class '(' [ arglist ] ')' [ funcliteral ] |
var |
ret [ expr ]
funcliteral ::= func Name funcbody
hash ::= '{' [ hashbody ] '}'
hashbody ::= hashelem [ ',' hashbody ]
hashelem ::= expr ':' 'expr'
array := '{' [ arraybody ] '}'
arraybody ::= expr [ ',' arraybody ]
varlist ::= var [ ',' varlist ]
var ::= Name [ Type ] [ '=' expr ]
parlist ::= formal [ ',' parlist ]
par ::= Name [ Type ]
arglist ::= expr [ ',' arglist ]
block ::= '{' exprlist '}'
exprlist ::= expr [ '\n' exprlist ]
binop ::= '+' | '-' | '*' | '/' | '^' | '%' | '<' | '>' | '=='
'<=' | '>=' | and | or
unop ::= '--' | '++' | not | '-'
FuncName @?[a-z][a-zA-Z0-9_]*[!?]?
Name = [a-z][a-zA-Z0-9_]*
Type = [A-Z][a-zA-Z0-9_]*
Constant = [A-Z0-9_]+