statement = b:block { b; }
|
|
| e:expression SEMI { e; }
|
|
|
|
expression = p:primary
|
|
( DOT i:id ASSIGN e:expression # { $$ = newSetProp(p, i, e) }
|
|
| LBRAK i:expression RBRAK ASSIGN e:expression { SetArray.new(object: p, index: i, value: e); }
|
|
)
|
|
| i:id ASSIGN e:expression { SetVar.new(name: i, value: e); }
|
|
| pf:postfix { pf; }
|
|
|
|
postfix = p:primary
|
|
( DOT i:id a:args !ASSIGN !LBRACE { p = Invoke.new(self: p, method: i, arguments: a); }
|
|
| DOT i:id !ASSIGN { p = GetProp.new(object: p, key: i); }
|
|
| a:args !ASSIGN !LBRACE { p = Call.new(function: p, arguments: a); }
|
|
) * { p; }
|
|
|
|
args = LPAREN a:mklist
|
|
(
|
|
( k:id COLON e:expression { a[k] = e; }
|
|
| e:expression { a.push(e); }
|
|
)
|
|
( COMMA
|
|
( k:id COLON e:expression { a[k] = e; }
|
|
| e:expression { a.push(e); }
|
|
)
|
|
) *
|
|
) ? RPAREN { a; }
|
|
|
|
mklist = { Object.new(); }
|
|
|
|
primary = nil | number | var | subExpr
|
|
|
|
subExpr = LPAREN e:expression RPAREN { e; }
|
|
|
|
block = LBRACE b:mklist
|
|
( e:statement { b.push(e); }
|
|
) * RBRACE { Block.new(body: b); }
|
|
|
|
nil = NIL { nil; }
|
|
|
|
number = "-" n:unsign { Unyop.new(operation: __opNeg).push(n) }
|
|
| "+" n:number { n }
|
|
| n:unsign { n }
|
|
|
|
unsign = < DIGIT+ > - { yytext.asInteger(10); }
|
|
|
|
var = i:id { GetVar.new(name: i); }
|
|
|
|
id = < LETTER ALNUM* > - { intern(yytext); }
|
|
|
|
DIGIT = [0-9]
|
|
LETTER = [A-Za-z_]
|
|
ALNUM = LETTER | DIGIT
|
|
|
|
NIL = "nil" !ALNUM -
|
|
|
|
SEMI = ";" -
|
|
COMMA = "," -
|
|
LPAREN = "(" -
|
|
RPAREN = ")" -
|
|
LBRAK = "[" -
|
|
RBRAK = "]" -
|
|
LBRACE = "{" -
|
|
RBRACE = "}" -
|
|
COLON = ":" ![:] -
|
|
ASSIGN = "=" ![=] -
|
|
DOT = "." ![.] -
|
|
|
|
- = ( space | comment )*
|
|
space = ' ' | '\t' | end-of-line
|
|
comment = '//' ( !end-of-line . )* end-of-line
|
|
end-of-line = '\r\n' | '\n' | '\r'
|
|
end-of-file = !.
|