-expr_final/*B3*//*B2*//*B*/ {-> expr}
- = expr/*B3*//*B*/ {-> expr/*B3*//*B*/.expr}
- | {closure_call} recv/*B*/ id args closure_defs/*B2*/ {-> New expr.call(recv/*B*/.expr, id, [args.expr], [closure_defs/*B2*/.closure_def])}
-/*N*//*N3*/ | {closure_bra} expr_atom braargs closure_defs/*B2*/ {-> New expr.bra(expr_atom.expr, [braargs.expr], [closure_defs/*B2*/.closure_def])}
- ;
-
-expr/*B3*//*B*/ {-> expr}
- = expr_and/*B3*//*B*/ {-> expr_and/*B3*//*B*/.expr}
- | {ifexpr} kwif [n1]:no expr [n2]:no kwthen [n3]:no [then]:expr [n4]:no kwelse [n5]:no [else]:expr/*B3*//*B*/ {-> New expr.ifexpr(kwif, expr, kwthen, then, kwelse, else.expr)}
- ;
-
-expr_and/*B3*//*B*/ {-> expr}
- = expr_not/*B3*//*B*/ {-> expr_not/*B3*//*B*/.expr}
- | {or} expr_and/*B3*//*B*/ kwor no expr_not/*B3*//*B*/ {-> New expr.or(expr_and/*B3*//*B*/.expr, expr_not/*B3*//*B*/.expr)}
- | {and} expr_and/*B3*//*B*/ kwand no expr_not/*B3*//*B*/ {-> New expr.and(expr_and/*B3*//*B*/.expr, expr_not/*B3*//*B*/.expr)}
- ;
-
-expr_not/*B3*//*B*/ {-> expr}
- = expr_eq/*B3*//*B*/ {-> expr_eq/*B3*//*B*/.expr}
- | {not} kwnot no expr_not/*B3*//*B*/ {-> New expr.not(kwnot, expr_not/*B3*//*B*/.expr)}
- ;
-
-expr_eq/*B3*//*B*/ {-> expr}
- = expr_add/*B3*//*B*/ {-> expr_add/*B3*//*B*/.expr}
- | {eq} expr_add/*B3*//*B*/ eq no [expr2]:expr_add/*B3*//*B*/ {-> New expr.eq(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {ee} expr_add/*B3*//*B*/ kwis no [expr2]:expr_add/*B3*//*B*/ {-> New expr.ee(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {ne} expr_add/*B3*//*B*/ ne no [expr2]:expr_add/*B3*//*B*/ {-> New expr.ne(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {lt} expr_add/*B3*//*B*/ lt no [expr2]:expr_add/*B3*//*B*/ {-> New expr.lt(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {le} expr_add/*B3*//*B*/ le no [expr2]:expr_add/*B3*//*B*/ {-> New expr.le(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {gt} expr_add/*B3*//*B*/ gt no [expr2]:expr_add/*B3*//*B*/ {-> New expr.gt(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {ge} expr_add/*B3*//*B*/ ge no [expr2]:expr_add/*B3*//*B*/ {-> New expr.ge(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {starship} expr_add/*B3*//*B*/ starship no [expr2]:expr_add/*B3*//*B*/ {-> New expr.starship(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {isa} expr_add/*B3*//*B*/ kwisa no type/*B3*//*B*/ {-> New expr.isa(expr_add/*B3*//*B*/.expr, type/*B3*//*B*/.type)}
- ;
-
-expr_add/*B3*//*B*/ {-> expr}
- = expr_mul/*B3*//*B*/ {-> expr_mul/*B3*//*B*/.expr}
- | {plus} expr_add/*B3*//*B*/ plus no [expr2]:expr_mul/*B3*//*B*/ {-> New expr.plus(expr_add/*B3*//*B*/.expr, expr2.expr)}
- | {minus} expr_add/*B3*//*B*/ minus no [expr2]:expr_mul/*B3*//*B*/ {-> New expr.minus(expr_add/*B3*//*B*/.expr, expr2.expr)}
- ;
-
-expr_mul/*B3*//*B*/ {-> expr}
- = expr_minus/*B3*//*B*/ {-> expr_minus/*B3*//*B*/.expr}
- | {star} expr_mul/*B3*//*B*/ star no [expr2]:expr_minus/*B3*//*B*/ {-> New expr.star(expr_mul/*B3*//*B*/.expr, expr2.expr)}
- | {slash} expr_mul/*B3*//*B*/ slash no [expr2]:expr_minus/*B3*//*B*/ {-> New expr.slash(expr_mul/*B3*//*B*/.expr, expr2.expr)}
- | {percent} expr_mul/*B3*//*B*/ percent no [expr2]:expr_minus/*B3*//*B*/ {-> New expr.percent(expr_mul/*B3*//*B*/.expr, expr2.expr)}
- ;
-
-expr_minus/*B3*//*B*/ {-> expr}
- = expr_new/*B3*//*B*/ {-> expr_new/*B3*//*B*/.expr}
- | {minus} minus no expr_minus/*B3*//*B*/ {-> New expr.uminus(minus, expr_minus/*B3*//*B*/.expr)}
- | {once} kwonce no expr_minus/*B3*//*B*/ {-> New expr.once(kwonce, expr_minus/*B3*//*B*/.expr)}
- ;
-
-expr_new/*B3*//*B*/ {-> expr}
- = expr_atom/*B3*//*B*/ {-> expr_atom/*B3*//*B*/.expr}
- | {new} kwnew no type/*B3*//*B*/ args {-> New expr.new(kwnew, type/*B3*//*B*/.type, Null, [args.expr])}
- ;
-
-expr_atom/*B3*//*B*/ {-> expr}
- = {attr} recv/*B3*//*B*/ attrid {-> New expr.attr(recv/*B3*//*B*/.expr, attrid)}
- | {call} recv/*B3*//*B*/ id args {-> New expr.call(recv/*B3*//*B*/.expr, id, [args.expr], [])}
- | {super} qualified? kwsuper args {-> New expr.super(qualified, kwsuper, [args.expr])}
- | {init} recv/*B3*//*B*/ kwinit args {-> New expr.init(recv/*B3*//*B*/.expr, kwinit, [args.expr])}
-/*N*//*N3*/ | {bra} expr_atom braargs {-> New expr.bra(expr_atom.expr, [braargs.expr], [])}
- | {new} kwnew no type/*B3*//*B*/ dot [n2]:no id args {-> New expr.new(kwnew, type/*B3*//*B*/.type, id, [args.expr])}
-/*N*//*N3*/ | {range} obra no expr [n2]:no dotdot [n3]:no [expr2]:expr_nobra [n4]:no cbra {-> New expr.crange(expr, expr2.expr)}
-/*N*//*N3*/ | {orange} obra no expr [n2]:no dotdot [n3]:no [expr2]:expr_nobra [n4]:no [cbra]:obra {-> New expr.orange(expr, expr2.expr)}
-/*N*//*N3*/ | {array} braargs {-> New expr.array([braargs.expr])}
- | {self} kwself {-> New expr.self(kwself)}
- | {true} kwtrue {-> New expr.true(kwtrue)}
- | {false} kwfalse {-> New expr.false(kwfalse)}
- | {null} kwnull {-> New expr.null(kwnull)}
- | {int} number {-> New expr.int(number)}
- | {float} float {-> New expr.float(float)}
- | {char} char {-> New expr.char(char)}
- | {string} string {-> New expr.string(string)}
+expr_final~nopar~withelse~nobra {-> expr}
+ = expr~nopar~nobra {-> expr~nopar~nobra.expr}
+ ;
+
+expr~nopar~nobra {-> expr}
+ = expr_and~nopar~nobra {-> expr_and~nopar~nobra.expr}
+ | {ifexpr} kwif [n1]:no expr [n2]:no kwthen [n3]:no [then]:expr [n4]:no kwelse [n5]:no [else]:expr~nopar~nobra {-> New expr.ifexpr(kwif, expr, kwthen, then, kwelse, else.expr)}
+ ;
+
+expr_and~nopar~nobra {-> expr}
+ = expr_not~nopar~nobra {-> expr_not~nopar~nobra.expr}
+ | {:or} expr_and~nopar~nobra :kwor :no expr_not~nopar~nobra
+ | {:and} expr_and~nopar~nobra :kwand :no expr_not~nopar~nobra
+ | {:or_else} expr_and~nopar~nobra :kwor :kwelse :no expr_not~nopar~nobra
+ | {:implies} expr_and~nopar~nobra :kwimplies :no expr_not~nopar~nobra
+ ;
+
+expr_not~nopar~nobra {-> expr}
+ = expr_eq~nopar~nobra {-> expr_eq~nopar~nobra.expr}
+ | {not} kwnot no expr_not~nopar~nobra {-> New expr.not(kwnot, expr_not~nopar~nobra.expr)}
+ ;
+
+expr_eq~nopar~nobra {-> expr}
+ = expr_add~nopar~nobra {-> expr_add~nopar~nobra.expr}
+ | {:eq} expr_add~nopar~nobra :eq :no [expr2]:expr_add~nopar~nobra
+ | {:ne} expr_add~nopar~nobra :ne :no [expr2]:expr_add~nopar~nobra
+ | {:lt} expr_add~nopar~nobra :lt :no [expr2]:expr_add~nopar~nobra
+ | {:le} expr_add~nopar~nobra :le :no [expr2]:expr_add~nopar~nobra
+ | {:ll} expr_eq~nopar~nobra :ll :no [expr2]:expr_add~nopar~nobra
+ | {:gt} expr_add~nopar~nobra :gt :no [expr2]:expr_add~nopar~nobra
+ | {:ge} expr_add~nopar~nobra :ge :no [expr2]:expr_add~nopar~nobra
+ | {:gg} expr_eq~nopar~nobra :gg :no [expr2]:expr_add~nopar~nobra
+ | {:starship} expr_add~nopar~nobra :starship :no [expr2]:expr_add~nopar~nobra
+ | {:isa} expr_add~nopar~nobra :kwisa :no type~nobra
+ ;
+
+expr_add~nopar~nobra {-> expr}
+ = expr_mul~nopar~nobra {-> expr_mul~nopar~nobra.expr}
+ | {:plus} expr_add~nopar~nobra :plus :no [expr2]:expr_mul~nopar~nobra
+ | {:minus} expr_add~nopar~nobra :minus :no [expr2]:expr_mul~nopar~nobra
+ ;
+
+expr_mul~nopar~nobra {-> expr}
+ = expr_minus~nopar~nobra {-> expr_minus~nopar~nobra.expr}
+ | {:star} expr_mul~nopar~nobra :star :no [expr2]:expr_minus~nopar~nobra
+ | {:slash} expr_mul~nopar~nobra :slash :no [expr2]:expr_minus~nopar~nobra
+ | {:percent} expr_mul~nopar~nobra :percent :no [expr2]:expr_minus~nopar~nobra
+ ;
+
+expr_minus~nopar~nobra {-> expr}
+ = expr_new~nopar~nobra {-> expr_new~nopar~nobra.expr}
+ | {:uminus} minus :no expr_minus~nopar~nobra
+ | {:once} kwonce :no expr_minus~nopar~nobra
+ ;
+
+expr_new~nopar~nobra {-> expr}
+ = expr_atom~nopar~nobra {-> expr_atom~nopar~nobra.expr}
+ | {new} kwnew no type~nobra_nopar args {-> New expr.new(kwnew, type~nobra_nopar.type, Null, args.exprs)}
+ | {isset_attr} kwisset recv~nopar~nobra qualified_o attrid {-> New expr.isset_attr(kwisset, recv~nopar~nobra.expr, attrid)}
+ ;
+
+expr_atom~nopar~nobra {-> expr}
+ = {attr} recv~nopar~nobra qualified_o attrid {-> New expr.attr(recv~nopar~nobra.expr, attrid)}
+ | {call} recv~nopar~nobra qid args {-> New expr.call(recv~nopar~nobra.expr, qid.id, args.exprs)}
+ | {super} qualified_o kwsuper args {-> New expr.super(qualified_o.qualified, kwsuper, args.exprs)}
+ | {init} recv~nopar~nobra kwinit args {-> New expr.init(recv~nopar~nobra.expr, kwinit, args.exprs)}
+!nobra | {bra} expr_atom~nopar braargs {-> New expr.bra(expr_atom~nopar.expr, braargs.exprs)}
+ | {new} kwnew no type~nobra_nopar dot [n2]:no qid args {-> New expr.new(kwnew, type~nobra_nopar.type, qid.id, args.exprs)}
+// !nopar to unambiguise 'foo[5].bar' between '(foo[5]).bar' and 'foo([5].bar),
+!nobra!nopar | {range} obra no expr [n2]:no dotdot [n3]:no [expr2]:expr_nobra [n4]:no cbra annotations_o {-> New expr.crange(obra, expr, expr2.expr, cbra, annotations_o.annotations)}
+!nobra!nopar | {orange} obra no expr [n2]:no dotdot [n3]:no [expr2]:expr_nobra [n4]:no [cbra]:obra annotations_o {-> New expr.orange(obra, expr, expr2.expr, cbra, annotations_o.annotations)}
+!nobra!nopar | {array} braargs annotations_o {-> New expr.array(braargs.exprs, annotations_o.annotations)}
+ | {self} kwself annotations_o {-> New expr.self(kwself, annotations_o.annotations)}
+ | {true} kwtrue annotations_o {-> New expr.true(kwtrue, annotations_o.annotations)}
+ | {false} kwfalse annotations_o {-> New expr.false(kwfalse, annotations_o.annotations)}
+ | {null} kwnull annotations_o {-> New expr.null(kwnull, annotations_o.annotations)}
+ | {int} number annotations_o {-> New expr.dec_int(number, annotations_o.annotations)}
+ | {hex_int} hex_number annotations_o {-> New expr.hex_int(hex_number, annotations_o.annotations)}
+ | {float} float annotations_o {-> New expr.float(float, annotations_o.annotations)}
+ | {char} char annotations_o {-> New expr.char(char, annotations_o.annotations)}
+ | {string} string annotations_o {-> New expr.string(string, annotations_o.annotations)}