e.ASAIL ::= t.Func | e.ASAIL t.Func t.Func ::= (FUNC t.name (e.params) (e.params) e.body) t.name ::= (e.QualifiedName) e.QualifiedName ::= [Word] | e.QualifiedName [Word] ([Word] - в смысле R+) | e.QualifiedName [Int] e.params ::= [] | t.var e.params t.var ::= (s.var-tag t.name) | (s.var-tag NEW t.name) s.var-tag ::= SVAR | TVAR | VVAR | EVAR e.body ::= [] | t.statement e.body t.statement ::= t.call | t.tailcall | t.assign | t.decl | t.if | t.for | t.continue | t.split | t.split-hard | t.split-ve | RETURN | FATAL | RETFAIL t.call ::= (CALL t.name (e.args) (e.params)) e.args ::= [] | (e.expr) e.args e.expr ::= [] | t.expr-term e.expr t.expr-term ::= [Int] | t.var | (PAREN e.expr) | t.operator | t.iter t.operator ::= (s.oper-tag t.name e.expr) | t.infix-operator s.oper-tag ::= PREFIX | POSTFIX t.infix-operator ::= (INFIX t.name e.args) t.iter ::= (ITER t.var) t.tailcall ::= (TAILCALL t.name (e.args) (e.params)) t.assign ::= (ASSIGN t.var e.expr) t.decl ::= (DECL t.var) t.if ::= (IF e.cond (e.body)) e.cond ::= t.cond-term | t.cond-term e.cond t.cond-term ::= t.call | t.expr-term | t.can-split? | t.can-split-hard? t.can-split? ::= (s.can-split-tag e.expr) t.can-split-tag ::= CANSPLITLS | CANSPLITLT | CANSPLITRS | CANSPLITRT t.can-split-hard? ::= (s.can-split-hard-tag e.args) t.can-split-hard-tag ::= CANSPLITLH | CANSPLITRH t.for ::= (FOR t.label (e.init) (e.cond) (e.expr) e.body) t.label ::= t.name e.init ::= e.body t.continue ::= (CONTINUE t.label) t.split ::= (s.split-tag e.expr t.split-left t.split-right) s.split-tag ::= SPLITLS | SPLITLT | SPLITRS | SPLITRT t.split-left ::= t.var t.split-right ::= t.var t.split-hard ::= (s.split-hard-tag e.args) s.split-hard-tag ::= SPLITLH | SPLITRH t.split-ve ::= (s.split-ve-tag t.var t.split-left t.split-right [Int]) s.split-ve-tag ::= SPLITLE | SPLITLV | SPLITRE | SPLITRV