bool CanParse(Precedence context, int li, out Precedence prec) { var opTok = LT(li); if (opTok.Type() == TokenType.Id) { var opTok2 = LT(li + 1); if (opTok2.Type() == TokenType.NormalOp && opTok.EndIndex == opTok2.StartIndex) { prec = _prec.Find(OperatorShape.Infix, opTok2.Value); } else { // Oops, LesPrecedenceMap doesn't yet support non-single-quote ops // (bacause it's shared with LESv2 which doesn't have them) // TODO: improve performance by avoiding this concat prec = _prec.Find(OperatorShape.Infix, (Symbol)("'" + opTok.Value.ToString())); } } else { prec = _prec.Find(OperatorShape.Infix, opTok.Value); } bool result = context.CanParse(prec); if (!context.CanMixWith(prec)) { Error(li, "Operator \"{0}\" cannot be mixed with the infix operator to its left. Add parentheses to clarify the code's meaning.", LT(li).Value); } return(result); }
// Types of (normal) expressions: // - particles: ids, literals, (parenthesized), {braced} // - ++prefix_operators // - infix + operators // - suffix_operators++ // - Special primary expressions: // method_calls(with arguments), indexers[with indexes], generic!arguments LNode Expr(Precedence context) { TT la0; LNode e = default(LNode); Token lit_excl = default(Token); Token t = default(Token); // line 128 Precedence prec; e = PrefixExpr(context); // Line 132: greedy( &{context.CanParse(prec = InfixPrecedenceOf(LT($LI)))} (TT.Assignment|TT.BQOperator|TT.Dot|TT.NormalOp) Expr | &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{context.CanParse(P.Of)} TT.Not (TT.LParen ExprList TT.RParen / Expr) | &{context.CanParse(SuffixPrecedenceOf(LT($LI)))} TT.PreOrSufOp )* for (;;) { switch ((TT)LA0) { case TT.Assignment: case TT.BQOperator: case TT.Dot: case TT.NormalOp: { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) { // line 133 if ((!prec.CanMixWith(context))) { Error(0, "Operator '{0}' is not allowed in this context. Add parentheses to clarify the code's meaning.", LT0.Value); } t = MatchAny(); var rhs = Expr(prec); // line 138 e = F.Call(t, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, NodeStyle.Operator); } else { goto stop; } } break; case TT.LBrack: case TT.LParen: { if (context.CanParse(P.Primary)) { e = FinishPrimaryExpr(e); } else { goto stop; } } break; case TT.Not: { if (context.CanParse(P.Of)) { lit_excl = MatchAny(); // line 145 var args = new LNodeList { e }; int endIndex; // Line 146: (TT.LParen ExprList TT.RParen / Expr) la0 = (TT)LA0; if (la0 == TT.LParen) { Skip(); args = ExprList(args); var c = Match((int)TT.RParen); // line 146 endIndex = c.EndIndex; } else { var T = Expr(P.Of); // line 147 args.Add(T); endIndex = T.Range.EndIndex; } // line 149 e = F.Call(S.Of, args, e.Range.StartIndex, endIndex, lit_excl.StartIndex, lit_excl.EndIndex, NodeStyle.Operator); } else { goto stop; } } break; case TT.PreOrSufOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) { t = MatchAny(); // line 153 e = F.Call(ToSuffixOpName((Symbol)t.Value), e, e.Range.StartIndex, t.EndIndex, t.StartIndex, t.EndIndex, NodeStyle.Operator); } else { goto stop; } } break; default: goto stop; } } stop :; // line 155 return(e); }
LNode Expr(Precedence context) { TT la0; LNode e = default(LNode); Token lit_excl = default(Token); Token t = default(Token); // Line 153: (KeywordExpression | PrefixExpr greedy( &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{CanParse(context, $LI, out prec)} InfixOperatorName Expr | &{context.CanParse(_prec.Find(OperatorShape.Suffix, LT($LI).Value))} TT.PreOrSufOp | &{context.CanParse(P.Of)} TT.Not (TT.LParen ExprList TT.RParen / Expr) )*) la0 = (TT)LA0; if (la0 == TT.Keyword) { e = KeywordExpression(); } else { // line 154 Precedence prec; e = PrefixExpr(context); // Line 158: greedy( &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{CanParse(context, $LI, out prec)} InfixOperatorName Expr | &{context.CanParse(_prec.Find(OperatorShape.Suffix, LT($LI).Value))} TT.PreOrSufOp | &{context.CanParse(P.Of)} TT.Not (TT.LParen ExprList TT.RParen / Expr) )* for (;;) { switch ((TT)LA0) { case TT.LBrack: case TT.LParen: { if (context.CanParse(P.Primary)) { e = FinishPrimaryExpr(e); } else { goto stop; } } break; case TT.Assignment: case TT.Dot: case TT.NormalOp: { if (CanParse(context, 0, out prec)) { goto match2; } else { goto stop; } } case TT.Colon: { if ((TT)LA(0 + 1) != TT.Newline) { if (CanParse(context, 0, out prec)) { goto match2; } else { goto stop; } } else { goto stop; } } case TT.Id: { if (!IsContinuator(LT(0).Value)) { if (CanParse(context, 0, out prec)) { goto match2; } else { goto stop; } } else { goto stop; } } case TT.PreOrSufOp: { if (context.CanParse(_prec.Find(OperatorShape.Suffix, LT(0).Value))) { t = MatchAny(); // line 168 e = F.Call(_prec.ToSuffixOpName((Symbol)t.Value), e, e.Range.StartIndex, t.EndIndex, t.StartIndex, t.EndIndex, NodeStyle.Operator); } else { goto stop; } } break; case TT.Not: { if (context.CanParse(P.Of)) { lit_excl = MatchAny(); // line 172 var args = new VList <LNode> { e }; int endIndex; // Line 173: (TT.LParen ExprList TT.RParen / Expr) la0 = (TT)LA0; if (la0 == TT.LParen) { Skip(); args = ExprList(args); var c = Match((int)TT.RParen); // line 173 endIndex = c.EndIndex; } else { var T = Expr(P.Of); // line 174 args.Add(T); endIndex = T.Range.EndIndex; } // line 176 e = F.Call(S.Of, args, e.Range.StartIndex, endIndex, lit_excl.StartIndex, lit_excl.EndIndex, NodeStyle.Operator); } else { goto stop; } } break; default: goto stop; } continue; match2: { Token op; var opName = InfixOperatorName(out op); var rhs = Expr(prec); // line 164 e = F.Call(opName, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, op.StartIndex, op.EndIndex, NodeStyle.Operator); } } stop :; } // line 178 return(e); }
LNode Expr(Precedence context) { TokenType la0, la1; Debug.Assert(context.CanParse(EP.Prefix)); Precedence prec; var e = PrefixExpr(); // Line 634: greedy( &{context.CanParse(prec = InfixPrecedenceOf($LA))} (TT.@in|TT.Add|TT.And|TT.AndBits|TT.BQString|TT.CompoundSet|TT.DivMod|TT.DotDot|TT.EqNeq|TT.GT|TT.LambdaArrow|TT.LEGE|TT.LT|TT.Mul|TT.NotBits|TT.NullCoalesce|TT.OrBits|TT.OrXor|TT.Power|TT.Set|TT.Sub|TT.XorBits) Expr | &{context.CanParse(prec = InfixPrecedenceOf($LA))} (TT.@as|TT.@is|TT.@using) DataType | &{context.CanParse(EP.Shift)} &{LT($LI).EndIndex == LT($LI + 1).StartIndex} (TT.LT TT.LT Expr | TT.GT TT.GT Expr) | &{context.CanParse(EP.IfElse)} TT.QuestionMark Expr TT.Colon Expr )* for (;;) { switch (LA0) { case TT.GT: case TT.LT: { la0 = LA0; if (context.CanParse(prec = InfixPrecedenceOf(la0))) { if (LT(0).EndIndex == LT(0 + 1).StartIndex) { if (context.CanParse(EP.Shift)) { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else if (la1 == TT.GT || la1 == TT.LT) goto match3; else goto stop; } else { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else goto stop; } } else { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else goto stop; } } else if (LT(0).EndIndex == LT(0 + 1).StartIndex) { if (context.CanParse(EP.Shift)) { la1 = LA(1); if (la1 == TT.GT || la1 == TT.LT) goto match3; else goto stop; } else goto stop; } else goto stop; } case TT.@in: case TT.Add: case TT.And: case TT.AndBits: case TT.BQString: case TT.CompoundSet: case TT.DivMod: case TT.DotDot: case TT.EqNeq: case TT.LambdaArrow: case TT.LEGE: case TT.Mul: case TT.NotBits: case TT.NullCoalesce: case TT.OrBits: case TT.OrXor: case TT.Power: case TT.Set: case TT.Sub: case TT.XorBits: { la0 = LA0; if (context.CanParse(prec = InfixPrecedenceOf(la0))) { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else goto stop; } else goto stop; } case TT.@as: case TT.@is: case TT.@using: { la0 = LA0; if (context.CanParse(prec = InfixPrecedenceOf(la0))) { switch (LA(1)) { case TT.@operator: case TT.ContextualKeyword: case TT.Id: case TT.Substitute: case TT.TypeKeyword: { var op = MatchAny(); var rhs = DataType(true); var opSym = op.Type() == TT.@using ? S.UsingCast : ((Symbol) op.Value); e = SetOperatorStyle(F.Call(opSym, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex)); } break; default: goto stop; } } else goto stop; } break; case TT.QuestionMark: { if (context.CanParse(EP.IfElse)) { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) { Skip(); var then = Expr(ContinueExpr); Match((int) TT.Colon); var @else = Expr(EP.IfElse); #line 656 "EcsParserGrammar.les" e = SetOperatorStyle(F.Call(S.QuestionMark, e, then, @else, e.Range.StartIndex, @else.Range.EndIndex)); #line default } else goto stop; } else goto stop; } break; default: goto stop; } continue; match1: { var op = MatchAny(); var rhs = Expr(prec); #line 638 "EcsParserGrammar.les" e = SetOperatorStyle(F.Call((Symbol) op.Value, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex)); #line default } continue; match3: { // Line 648: (TT.LT TT.LT Expr | TT.GT TT.GT Expr) la0 = LA0; if (la0 == TT.LT) { Skip(); Match((int) TT.LT); var rhs = Expr(EP.Shift); #line 649 "EcsParserGrammar.les" e = SetOperatorStyle(F.Call(S.Shl, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex)); #line default } else { Match((int) TT.GT); Match((int) TT.GT); var rhs = Expr(EP.Shift); #line 651 "EcsParserGrammar.les" e = SetOperatorStyle(F.Call(S.Shr, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex)); #line default } } } stop:; #line 658 "EcsParserGrammar.les" return e; #line default }
// This rule handles all lower precedence levels, from ** down to assignment // (=). This rule uses the "precedence floor" concept, documented in // Loyc.Syntax.Precedence, to handle different precedence levels. The // traditional approach is to define a separate rule for every precedence // level. By collapsing many precedence levels into a single rule, there are // two benefits: // (1) shorter code. // (2) potentially better performance: using a separate rule per precedence // level causes a new stack frame and prediction step to be created for // each level, regardless of the operators present in the actual // expression being parsed. For example, to parse the simple expression // "Hello" the traditional way requires 20 rules and therefore 20 stack // frames if there are 20 precedence levels. On the other hand, the // "precedence floor" approach requires an extra precedence check, so // it may be slower when there are few levels. Note: EC# has 22 // precedence levels, and this method handles the lower 18 of them. // // The higher levels of the EC# expression parser do not use this trick // because the higher precedence levels have some complications, such as // C-style casts and <type arguments>, that I prefer to deal with // separately. LNode SubExpr(Precedence context) { TokenType la0, la1; Debug.Assert(context.CanParse(EP.Prefix)); Precedence prec; var e = PrefixExpr(); // Line 671: greedy( &{context.CanParse(prec = InfixPrecedenceOf($LA))} (TT.Add|TT.And|TT.AndBits|TT.BQString|TT.CompoundSet|TT.DivMod|TT.DotDot|TT.EqNeq|TT.GT|TT.In|TT.LambdaArrow|TT.LEGE|TT.LT|TT.Mul|TT.NotBits|TT.NullCoalesce|TT.OrBits|TT.OrXor|TT.Power|TT.Set|TT.Sub|TT.XorBits) SubExpr | &{context.CanParse(prec = InfixPrecedenceOf($LA))} (TT.As|TT.Is|TT.Using) DataType FinishPrimaryExpr | &{context.CanParse(EP.Shift)} &{LT($LI).EndIndex == LT($LI + 1).StartIndex} (TT.LT TT.LT SubExpr | TT.GT TT.GT SubExpr) | &{context.CanParse(EP.IfElse)} TT.QuestionMark SubExpr TT.Colon SubExpr )* for (;;) { switch (LA0) { case TT.GT: case TT.LT: { la0 = LA0; if (context.CanParse(prec = InfixPrecedenceOf(la0))) { if (LT(0).EndIndex == LT(0 + 1).StartIndex) { if (context.CanParse(EP.Shift)) { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else if (la1 == TT.GT || la1 == TT.LT) goto match3; else goto stop; } else { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else goto stop; } } else { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else goto stop; } } else if (LT(0).EndIndex == LT(0 + 1).StartIndex) { if (context.CanParse(EP.Shift)) { la1 = LA(1); if (la1 == TT.GT || la1 == TT.LT) goto match3; else goto stop; } else goto stop; } else goto stop; } case TT.Add: case TT.And: case TT.AndBits: case TT.BQString: case TT.CompoundSet: case TT.DivMod: case TT.DotDot: case TT.EqNeq: case TT.In: case TT.LambdaArrow: case TT.LEGE: case TT.Mul: case TT.NotBits: case TT.NullCoalesce: case TT.OrBits: case TT.OrXor: case TT.Power: case TT.Set: case TT.Sub: case TT.XorBits: { la0 = LA0; if (context.CanParse(prec = InfixPrecedenceOf(la0))) { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) goto match1; else goto stop; } else goto stop; } case TT.As: case TT.Is: case TT.Using: { la0 = LA0; if (context.CanParse(prec = InfixPrecedenceOf(la0))) { switch (LA(1)) { case TT.ContextualKeyword: case TT.Id: case TT.Operator: case TT.Substitute: case TT.TypeKeyword: { var op = MatchAny(); var rhs = DataType(true); var opSym = op.Type() == TT.Using ? S.UsingCast : ((Symbol) op.Value); e = F.Call(opSym, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, op.StartIndex, op.EndIndex, NodeStyle.Operator); FinishPrimaryExpr(ref e); } break; default: goto stop; } } else goto stop; } break; case TT.QuestionMark: { if (context.CanParse(EP.IfElse)) { la1 = LA(1); if (PrefixExpr_set0.Contains((int) la1)) { var op = MatchAny(); var then = SubExpr(StartExpr); Match((int) TT.Colon); var @else = SubExpr(EP.IfElse); // line 694 e = F.Call(S.QuestionMark, LNode.List(e, then, @else), e.Range.StartIndex, @else.Range.EndIndex, op.StartIndex, op.EndIndex, NodeStyle.Operator); } else goto stop; } else goto stop; } break; default: goto stop; } continue; match1: { var op = MatchAny(); var rhs = SubExpr(prec); // line 675 e = F.Call((Symbol) op.Value, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, op.StartIndex, op.EndIndex, NodeStyle.Operator); } continue; match3: { // Line 686: (TT.LT TT.LT SubExpr | TT.GT TT.GT SubExpr) la0 = LA0; if (la0 == TT.LT) { var op = MatchAny(); Match((int) TT.LT); var rhs = SubExpr(EP.Shift); // line 687 e = F.Call(S.Shl, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, op.StartIndex, op.EndIndex + 1, NodeStyle.Operator); } else { var op = Match((int) TT.GT); Match((int) TT.GT); var rhs = SubExpr(EP.Shift); // line 689 e = F.Call(S.Shr, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, op.StartIndex, op.EndIndex + 1, NodeStyle.Operator); } } } stop:; // line 697 return e; }
LNode Expr(Precedence context) { LNode e = default(LNode); Token t = default(Token); // line 123 Precedence prec; e = PrefixExpr(context); // Line 127: greedy( &{context.CanParse(prec = InfixPrecedenceOf(LT($LI)))} ((TT.Assignment|TT.BQString|TT.Dot|TT.NormalOp) | &{LA($LI + 1) != TT.Indent->@int} TT.Colon) Expr | &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{context.CanParse(SuffixPrecedenceOf(LT($LI)))} TT.PreOrSufOp )* for (;;) { switch ((TT)LA0) { case TT.Assignment: case TT.BQString: case TT.Dot: case TT.NormalOp: { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) { goto matchExpr; } else { goto stop; } } case TT.Colon: { if (LA(0 + 1) != (int)TT.Indent) { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) { goto matchExpr; } else { goto stop; } } else { goto stop; } } case TT.LBrack: case TT.LParen: case TT.Not: { if (context.CanParse(P.Primary)) { e = FinishPrimaryExpr(e); } else { goto stop; } } break; case TT.PreOrSufOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) { t = MatchAny(); // line 140 e = F.Call(ToSuffixOpName((Symbol)t.Value), e, e.Range.StartIndex, t.EndIndex).SetStyle(NodeStyle.Operator); } else { goto stop; } } break; default: goto stop; } continue; matchExpr: { // line 128 if ((!prec.CanMixWith(context))) { Error(0, "Operator '{0}' is not allowed in this context. Add parentheses to clarify the code's meaning.", LT0.Value); } // Line 131: ((TT.Assignment|TT.BQString|TT.Dot|TT.NormalOp) | &{LA($LI + 1) != TT.Indent->@int} TT.Colon) switch ((TT)LA0) { case TT.Assignment: case TT.BQString: case TT.Dot: case TT.NormalOp: t = MatchAny(); break; default: { Check(LA(0 + 1) != (int)TT.Indent, "LA($LI + 1) != TT.Indent->@int"); t = Match((int)TT.Colon); } break; } var rhs = Expr(prec); // line 133 e = F.Call((Symbol)t.Value, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex).SetStyle(NodeStyle.Operator); } } stop :; // line 142 return(e); }
LNode Atom(Precedence context, ref RWList<LNode> attrs) { TT la0, la1; // line 39 LNode e = MissingExpr; LNode _; // Line 41: ( (TT.Id (&{t.EndIndex == LT($LI).StartIndex && context.CanParse(P.Primary)} TT.LParen TT.RParen / ) | (TT.Number|TT.OtherLit|TT.SQString|TT.String|TT.Symbol) | TT.At TT.LBrack TT.RBrack | (TT.PrefixOp|TT.PreSufOp) Expr) | (TT.Colon TT.Indent TT.Dedent greedy(TT.Colon)? / &{context != P.SuperExpr} (TT.Assignment|TT.BQString|TT.Colon|TT.Dot|TT.NormalOp|TT.Not) Expr) | TT.LBrack TT.RBrack Atom | TT.LParen TT.RParen | TT.LBrace TT.RBrace ) do { switch ((TT) LA0) { case TT.Id: { var t = MatchAny(); // Line 42: (&{t.EndIndex == LT($LI).StartIndex && context.CanParse(P.Primary)} TT.LParen TT.RParen / ) la0 = (TT) LA0; if (la0 == TT.LParen) { if (t.EndIndex == LT(0).StartIndex && context.CanParse(P.Primary)) { la1 = (TT) LA(1); if (la1 == TT.RParen) { var p = MatchAny(); var rp = MatchAny(); // line 44 e = ParseCall(t, p, rp.EndIndex); } else // line 45 e = F.Id((Symbol) t.Value, t.StartIndex, t.EndIndex); } else // line 45 e = F.Id((Symbol) t.Value, t.StartIndex, t.EndIndex); } else // line 45 e = F.Id((Symbol) t.Value, t.StartIndex, t.EndIndex); } break; case TT.Number: case TT.OtherLit: case TT.SQString: case TT.String: case TT.Symbol: { var t = MatchAny(); // line 49 e = F.Literal(t.Value, t.StartIndex, t.EndIndex); } break; case TT.At: { Skip(); var t = Match((int) TT.LBrack); var rb = Match((int) TT.RBrack); // line 52 e = F.Literal(t.Children, t.StartIndex, rb.EndIndex); } break; case TT.PrefixOp: case TT.PreSufOp: { var t = MatchAny(); e = Expr(PrefixPrecedenceOf(t), out _); e = F.Call((Symbol) t.Value, e, t.StartIndex, e.Range.EndIndex); e.BaseStyle = NodeStyle.Operator; } break; case TT.Colon: { if (context != P.SuperExpr) { switch ((TT) LA(1)) { case TT.Indent: goto match5; case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match6; default: goto error; } } else goto match5; } case TT.Assignment: case TT.BQString: case TT.Dot: case TT.NormalOp: case TT.Not: goto match6; case TT.LBrack: { var t = MatchAny(); Match((int) TT.RBrack); // line 69 attrs = AppendExprsInside(t, attrs); e = Atom(context, ref attrs); } break; case TT.LParen: { var t = MatchAny(); var rp = Match((int) TT.RParen); // line 72 e = ParseParens(t, rp.EndIndex); } break; case TT.LBrace: { var t = MatchAny(); var rb = Match((int) TT.RBrace); // line 74 e = ParseBraces(t, rb.EndIndex); } break; default: goto error; } break; match5: { Skip(); var t = Match((int) TT.Indent); var rb = Match((int) TT.Dedent); // Line 59: greedy(TT.Colon)? la0 = (TT) LA0; if (la0 == TT.Colon) Skip(); // line 60 e = ParseBraces(t, rb.EndIndex); } break; match6: { Check(context != P.SuperExpr, "context != P.SuperExpr"); var t = MatchAny(); e = Expr(PrefixPrecedenceOf(t), out _); e = F.Call((Symbol) t.Value, e, t.StartIndex, e.Range.EndIndex); e.BaseStyle = NodeStyle.Operator; } break; error: { // line 76 e = F.Id(S.Missing, LT0.StartIndex, LT0.StartIndex); Error(0, "Expected an expression here"); } } while (false); // line 80 return e; }
LNode Expr(Precedence context) { TT la0; LNode e = default(LNode); Token lit_excl = default(Token); Token t = default(Token); // Line 156: (KeywordExpression | PrefixExpr greedy( &{CanParse(context, $LI, out prec)} InfixOperatorName Expr | &{context.CanParse(P.Add)} TT.NegativeLiteral | &{context.CanParse(_prec.Find(OperatorShape.Suffix, LT($LI).Value))} TT.PreOrSufOp | &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{context.CanParse(P.Of)} TT.Not (TT.LParen ExprList TT.RParen / Expr) )*) la0 = (TT) LA0; if (la0 == TT.Keyword) e = KeywordExpression(); else { // line 157 Precedence prec; e = PrefixExpr(context); // Line 161: greedy( &{CanParse(context, $LI, out prec)} InfixOperatorName Expr | &{context.CanParse(P.Add)} TT.NegativeLiteral | &{context.CanParse(_prec.Find(OperatorShape.Suffix, LT($LI).Value))} TT.PreOrSufOp | &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{context.CanParse(P.Of)} TT.Not (TT.LParen ExprList TT.RParen / Expr) )* for (;;) { switch ((TT) LA0) { case TT.Assignment: case TT.Dot: case TT.NormalOp: { if (CanParse(context, 0, out prec)) goto match1; else goto stop; } case TT.Colon: { if ((TT) LA(0 + 1) != TT.Newline) { if (CanParse(context, 0, out prec)) goto match1; else goto stop; } else goto stop; } case TT.Id: { if (CanParse(context, 0, out prec)) { if (!Continuators.ContainsKey(LT(0).Value)) goto match1; else goto stop; } else goto stop; } case TT.NegativeLiteral: { if (context.CanParse(P.Add)) { var rhs = MatchAny(); // line 167 e = F.Call(S.Sub, e, ToPositiveLiteral(rhs), e.Range.StartIndex, rhs.EndIndex, rhs.StartIndex, rhs.StartIndex + 1, NodeStyle.Operator); } else goto stop; } break; case TT.PreOrSufOp: { if (context.CanParse(_prec.Find(OperatorShape.Suffix, LT(0).Value))) { t = MatchAny(); // line 171 e = F.Call(_prec.ToSuffixOpName((Symbol) t.Value), e, e.Range.StartIndex, t.EndIndex, t.StartIndex, t.EndIndex, NodeStyle.Operator); } else goto stop; } break; case TT.LBrack: case TT.LParen: { if (context.CanParse(P.Primary)) e = FinishPrimaryExpr(e); else goto stop; } break; case TT.Not: { if (context.CanParse(P.Of)) { lit_excl = MatchAny(); // line 178 var args = new VList<LNode> { e }; int endIndex; // Line 179: (TT.LParen ExprList TT.RParen / Expr) la0 = (TT) LA0; if (la0 == TT.LParen) { Skip(); args = ExprList(args); var c = Match((int) TT.RParen); // line 179 endIndex = c.EndIndex; } else { var T = Expr(P.Of); // line 180 args.Add(T); endIndex = T.Range.EndIndex; } // line 182 e = F.Call(S.Of, args, e.Range.StartIndex, endIndex, lit_excl.StartIndex, lit_excl.EndIndex, NodeStyle.Operator); } else goto stop; } break; default: goto stop; } continue; match1: { Token op; var opName = InfixOperatorName(out op); var rhs = Expr(prec); // line 164 e = F.Call(opName, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, op.StartIndex, op.EndIndex, NodeStyle.Operator); } } stop:; } // line 184 return e; }
LNode Expr(Precedence context, out LNode primary) { TT la1; // line 91 LNode e; LNode _; Precedence prec; RWList<LNode> attrs = null; e = Atom(context, ref attrs); // line 93 primary = e; // Line 96: greedy( (&{context.CanParse(prec = InfixPrecedenceOf(LT($LI)))} (TT.Assignment|TT.BQString|TT.Colon|TT.Dot|TT.NormalOp) Expr | &{context.CanParse(P.Primary)} TT.Not Expr | &{context.CanParse(SuffixPrecedenceOf(LT($LI)))} (TT.PreSufOp|TT.SuffixOp) | &{e.Range.EndIndex == LT($LI).StartIndex && context.CanParse(P.Primary)} TT.LParen TT.RParen) | (&{context.CanParse(P.Primary)} TT.LBrack TT.RBrack / &{context.CanParse(P.SuperExpr)} Expr greedy(Expr)*) )* for (;;) { switch ((TT) LA0) { case TT.Colon: { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) { if (context.CanParse(P.SuperExpr)) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match1; case TT.Indent: goto matchExpr; default: goto stop2; } } else { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match1; default: goto stop2; } } } else if (context.CanParse(P.SuperExpr)) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.Indent: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto matchExpr; default: goto stop2; } } else goto stop2; } case TT.Assignment: case TT.BQString: case TT.Dot: case TT.NormalOp: { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match1; default: goto stop2; } } else if (context.CanParse(P.SuperExpr)) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto matchExpr; default: goto stop2; } } else goto stop2; } case TT.Not: { if (context.CanParse(P.Primary)) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: { Skip(); var rhs = Expr(P.Primary, out primary); // line 108 RVList<LNode> args; if ((rhs.Calls(S.Tuple))) { args = new RVList<LNode>(e).AddRange(rhs.Args); } else { int i = rhs.Attrs.IndexWithName(S.TriviaInParens); if ((i > -1)) rhs = rhs.WithAttrs(rhs.Attrs.RemoveAt(i)); args = new RVList<LNode>(e, rhs); } e = primary = F.Call(S.Of, args, e.Range.StartIndex, rhs.Range.EndIndex); e.BaseStyle = NodeStyle.Operator; } break; default: goto stop2; } } else if (context.CanParse(P.SuperExpr)) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto matchExpr; default: goto stop2; } } else goto stop2; } break; case TT.PreSufOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) goto match3; else if (context.CanParse(P.SuperExpr)) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto matchExpr; default: goto stop2; } } else goto stop2; } case TT.SuffixOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) goto match3; else goto stop2; } case TT.LParen: { if (e.Range.EndIndex == LT(0).StartIndex && context.CanParse(P.Primary)) { la1 = (TT) LA(1); if (la1 == TT.RParen) { var p = MatchAny(); var rp = MatchAny(); e = primary = ParseCall(e, p, rp.EndIndex); e.BaseStyle = NodeStyle.PrefixNotation; } else goto stop2; } else if (context.CanParse(P.SuperExpr)) { la1 = (TT) LA(1); if (la1 == TT.RParen) goto matchExpr; else goto stop2; } else goto stop2; } break; case TT.LBrack: { if (context.CanParse(P.Primary)) { la1 = (TT) LA(1); if (la1 == TT.RBrack) { var t = MatchAny(); var rb = MatchAny(); // line 134 var args = new RWList<LNode> { e }; AppendExprsInside(t, args); e = primary = F.Call(S.Bracks, args.ToRVList(), e.Range.StartIndex, rb.EndIndex); e.BaseStyle = NodeStyle.Expression; } else goto stop2; } else if (context.CanParse(P.SuperExpr)) { la1 = (TT) LA(1); if (la1 == TT.RBrack) goto matchExpr; else goto stop2; } else goto stop2; } break; case TT.Id: case TT.Number: case TT.OtherLit: case TT.SQString: case TT.String: case TT.Symbol: { if (context.CanParse(P.SuperExpr)) goto matchExpr; else goto stop2; } case TT.At: { if (context.CanParse(P.SuperExpr)) { la1 = (TT) LA(1); if (la1 == TT.LBrack) goto matchExpr; else goto stop2; } else goto stop2; } case TT.PrefixOp: { if (context.CanParse(P.SuperExpr)) { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto matchExpr; default: goto stop2; } } else goto stop2; } case TT.LBrace: { if (context.CanParse(P.SuperExpr)) { la1 = (TT) LA(1); if (la1 == TT.RBrace) goto matchExpr; else goto stop2; } else goto stop2; } default: goto stop2; } continue; match1: { var t = MatchAny(); var rhs = Expr(prec, out primary); e = F.Call((Symbol) t.Value, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex); e.BaseStyle = NodeStyle.Operator; if ((!prec.CanParse(P.NullDot))) primary = e; } continue; match3: { var t = MatchAny(); e = F.Call(ToSuffixOpName((Symbol) t.Value), e, e.Range.StartIndex, t.EndIndex); e.BaseStyle = NodeStyle.Operator; if ((t.Type() == TT.PreSufOp)) primary = null; } continue; matchExpr: { // line 144 var rhs = RVList<LNode>.Empty; rhs.Add(Expr(P.SuperExpr, out _)); // Line 145: greedy(Expr)* for (;;) { switch ((TT) LA0) { case TT.Id: case TT.Number: case TT.OtherLit: case TT.SQString: case TT.String: case TT.Symbol: rhs.Add(Expr(P.SuperExpr, out _)); break; case TT.At: { la1 = (TT) LA(1); if (la1 == TT.LBrack) rhs.Add(Expr(P.SuperExpr, out _)); else goto stop; } break; case TT.PrefixOp: case TT.PreSufOp: { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: rhs.Add(Expr(P.SuperExpr, out _)); break; default: goto stop; } } break; case TT.Colon: { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.Indent: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: rhs.Add(Expr(P.SuperExpr, out _)); break; default: goto stop; } } break; case TT.Assignment: case TT.BQString: case TT.Dot: case TT.NormalOp: case TT.Not: { switch ((TT) LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: rhs.Add(Expr(P.SuperExpr, out _)); break; default: goto stop; } } break; case TT.LBrack: { la1 = (TT) LA(1); if (la1 == TT.RBrack) rhs.Add(Expr(P.SuperExpr, out _)); else goto stop; } break; case TT.LParen: { la1 = (TT) LA(1); if (la1 == TT.RParen) rhs.Add(Expr(P.SuperExpr, out _)); else goto stop; } break; case TT.LBrace: { la1 = (TT) LA(1); if (la1 == TT.RBrace) rhs.Add(Expr(P.SuperExpr, out _)); else goto stop; } break; default: goto stop; } } stop:; // line 146 e = MakeSuperExpr(e, ref primary, rhs); } } stop2:; // line 148 return attrs == null ? e : e.WithAttrs(attrs.ToRVList()); }
// Types of (normal) expressions: // - particles: ids, literals, (parenthesized), {braced} // - ++prefix_operators // - infix + operators // - suffix_operators++ // - Special primary expressions: // method_calls(with arguments), indexers[with indexes], generic!arguments LNode Expr(Precedence context) { TT la0; LNode e = default(LNode); Token lit_excl = default(Token); Token t = default(Token); // line 127 Precedence prec; e = PrefixExpr(context); // Line 131: greedy( &{context.CanParse(prec = InfixPrecedenceOf(LT($LI)))} (TT.Assignment|TT.BQOperator|TT.Dot|TT.NormalOp) Expr | &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{context.CanParse(P.Of)} TT.Not (TT.LParen ExprList TT.RParen / Expr) | &{context.CanParse(SuffixPrecedenceOf(LT($LI)))} TT.PreOrSufOp )* for (;;) { switch ((TT) LA0) { case TT.Assignment: case TT.BQOperator: case TT.Dot: case TT.NormalOp: { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) { // line 132 if ((!prec.CanMixWith(context))) { Error(0, "Operator '{0}' is not allowed in this context. Add parentheses to clarify the code's meaning.", LT0.Value); } t = MatchAny(); var rhs = Expr(prec); // line 137 e = F.Call(t, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex, NodeStyle.Operator); } else goto stop; } break; case TT.LBrack: case TT.LParen: { if (context.CanParse(P.Primary)) e = FinishPrimaryExpr(e); else goto stop; } break; case TT.Not: { if (context.CanParse(P.Of)) { lit_excl = MatchAny(); // line 144 var args = new VList<LNode> { e }; int endIndex; // Line 145: (TT.LParen ExprList TT.RParen / Expr) la0 = (TT) LA0; if (la0 == TT.LParen) { Skip(); args = ExprList(args); var c = Match((int) TT.RParen); // line 145 endIndex = c.EndIndex; } else { var T = Expr(P.Of); // line 146 args.Add(T); endIndex = T.Range.EndIndex; } // line 148 e = F.Call(S.Of, args, e.Range.StartIndex, endIndex, lit_excl.StartIndex, lit_excl.EndIndex, NodeStyle.Operator); } else goto stop; } break; case TT.PreOrSufOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) { t = MatchAny(); // line 152 e = F.Call(ToSuffixOpName((Symbol) t.Value), e, e.Range.StartIndex, t.EndIndex, t.StartIndex, t.EndIndex, NodeStyle.Operator); } else goto stop; } break; default: goto stop; } } stop:; // line 154 return e; }
LNode Atom(Precedence context, ref RWList <LNode> attrs) { TT la0, la1; LNode e = MissingExpr; LNode _; // Line 39: ( TT.Id (&{t.EndIndex == LT($LI).StartIndex && context.CanParse(P.Primary)} TT.LParen TT.RParen / ) | (TT.Symbol|TT.Number|TT.String|TT.SQString|TT.OtherLit) | TT.At TT.LBrack TT.RBrack | (TT.PrefixOp|TT.PreSufOp) Expr | &{context != P.SuperExpr} (TT.Colon|TT.NormalOp|TT.Not|TT.BQString|TT.Dot|TT.Assignment) Expr | TT.LBrack TT.RBrack Atom | TT.LParen TT.RParen | TT.LBrace TT.RBrace ) switch (LA0) { case TT.Id: { var t = MatchAny(); // Line 40: (&{t.EndIndex == LT($LI).StartIndex && context.CanParse(P.Primary)} TT.LParen TT.RParen / ) la0 = LA0; if (la0 == TT.LParen) { if (t.EndIndex == LT(0).StartIndex&& context.CanParse(P.Primary)) { la1 = LA(1); if (la1 == TT.RParen) { var p = MatchAny(); var rp = MatchAny(); e = ParseCall(t, p, rp.EndIndex); } else { e = F.Id((Symbol)t.Value, t.StartIndex, t.EndIndex); } } else { e = F.Id((Symbol)t.Value, t.StartIndex, t.EndIndex); } } else { e = F.Id((Symbol)t.Value, t.StartIndex, t.EndIndex); } } break; case TT.Number: case TT.OtherLit: case TT.SQString: case TT.String: case TT.Symbol: { var t = MatchAny(); e = F.Literal(t.Value, t.StartIndex, t.EndIndex); } break; case TT.At: { Skip(); var t = Match((int)TT.LBrack); var rb = Match((int)TT.RBrack); e = F.Literal(t.Children, t.StartIndex, rb.EndIndex); } break; case TT.PrefixOp: case TT.PreSufOp: { var t = MatchAny(); e = Expr(PrefixPrecedenceOf(t), out _); e = F.Call((Symbol)t.Value, e, t.StartIndex, e.Range.EndIndex); } break; case TT.Assignment: case TT.BQString: case TT.Colon: case TT.Dot: case TT.NormalOp: case TT.Not: { Check(context != P.SuperExpr, "context != P.SuperExpr"); var t = MatchAny(); e = Expr(PrefixPrecedenceOf(t), out _); e = F.Call((Symbol)t.Value, e, t.StartIndex, e.Range.EndIndex); } break; case TT.LBrack: { var t = MatchAny(); Match((int)TT.RBrack); attrs = AppendExprsInside(t, attrs); e = Atom(context, ref attrs); } break; case TT.LParen: { var t = MatchAny(); var rp = Match((int)TT.RParen); e = ParseParens(t, rp.EndIndex); } break; case TT.LBrace: { var t = MatchAny(); var rb = Match((int)TT.RBrace); e = ParseBraces(t, rb.EndIndex); } break; default: { e = F.Id(S.Missing, LT0.StartIndex, LT0.StartIndex); Error(0, "Expected an expression here"); } break; } return(e); }
LNode Expr(Precedence context, out LNode primary) { TT la1; LNode e; LNode _; Precedence prec; RWList <LNode> attrs = null; e = Atom(context, ref attrs); primary = e; // Line 89: greedy( (&{context.CanParse(prec = InfixPrecedenceOf(LT($LI)))} (TT.Colon|TT.NormalOp|TT.BQString|TT.Dot|TT.Assignment) Expr | &{context.CanParse(P.Primary)} TT.Not Expr | &{context.CanParse(SuffixPrecedenceOf(LT($LI)))} (TT.SuffixOp|TT.PreSufOp) | &{e.Range.EndIndex == LT($LI).StartIndex && context.CanParse(P.Primary)} TT.LParen TT.RParen) | (&{context.CanParse(P.Primary)} TT.LBrack TT.RBrack / &{context.CanParse(P.SuperExpr)} Expr greedy(Expr)*) )* for (;;) { switch (LA0) { case TT.Assignment: case TT.BQString: case TT.Colon: case TT.Dot: case TT.NormalOp: { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) { switch (LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: { var t = MatchAny(); var rhs = Expr(prec, out primary); e = F.Call((Symbol)t.Value, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex); e.BaseStyle = NodeStyle.Operator; if ((!prec.CanParse(P.NullDot))) { primary = e; } } break; default: goto stop2; } } else if (context.CanParse(P.SuperExpr)) { switch (LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match6; default: goto stop2; } } else { goto stop2; } } break; case TT.Not: { if (context.CanParse(P.Primary)) { switch (LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: { Skip(); var rhs = Expr(P.Primary, out primary); RVList <LNode> args; if ((rhs.Calls(S.Tuple))) { args = new RVList <LNode>(e).AddRange(rhs.Args); } else { int i = rhs.Attrs.IndexWithName(S.TriviaInParens); if ((i > -1)) { rhs = rhs.WithAttrs(rhs.Attrs.RemoveAt(i)); } args = new RVList <LNode>(e, rhs); } e = primary = F.Call(S.Of, args, e.Range.StartIndex, rhs.Range.EndIndex); e.BaseStyle = NodeStyle.Operator; } break; default: goto stop2; } } else if (context.CanParse(P.SuperExpr)) { switch (LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match6; default: goto stop2; } } else { goto stop2; } } break; case TT.PreSufOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) { goto match3; } else if (context.CanParse(P.SuperExpr)) { switch (LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match6; default: goto stop2; } } else { goto stop2; } } case TT.SuffixOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) { goto match3; } else { goto stop2; } } case TT.LParen: { if (e.Range.EndIndex == LT(0).StartIndex&& context.CanParse(P.Primary)) { la1 = LA(1); if (la1 == TT.RParen) { var p = MatchAny(); var rp = MatchAny(); e = primary = ParseCall(e, p, rp.EndIndex); e.BaseStyle = NodeStyle.PrefixNotation; } else { goto stop2; } } else if (context.CanParse(P.SuperExpr)) { la1 = LA(1); if (la1 == TT.RParen) { goto match6; } else { goto stop2; } } else { goto stop2; } } break; case TT.LBrack: { if (context.CanParse(P.Primary)) { la1 = LA(1); if (la1 == TT.RBrack) { var t = MatchAny(); var rb = MatchAny(); var args = new RWList <LNode> { e }; AppendExprsInside(t, args); e = primary = F.Call(S.Bracks, args.ToRVList(), e.Range.StartIndex, rb.EndIndex); e.BaseStyle = NodeStyle.Expression; } else { goto stop2; } } else if (context.CanParse(P.SuperExpr)) { la1 = LA(1); if (la1 == TT.RBrack) { goto match6; } else { goto stop2; } } else { goto stop2; } } break; case TT.Id: case TT.Number: case TT.OtherLit: case TT.SQString: case TT.String: case TT.Symbol: { if (context.CanParse(P.SuperExpr)) { goto match6; } else { goto stop2; } } case TT.At: { if (context.CanParse(P.SuperExpr)) { la1 = LA(1); if (la1 == TT.LBrack) { goto match6; } else { goto stop2; } } else { goto stop2; } } case TT.PrefixOp: { if (context.CanParse(P.SuperExpr)) { switch (LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: goto match6; default: goto stop2; } } else { goto stop2; } } case TT.LBrace: { if (context.CanParse(P.SuperExpr)) { la1 = LA(1); if (la1 == TT.RBrace) { goto match6; } else { goto stop2; } } else { goto stop2; } } default: goto stop2; } continue; match3: { var t = MatchAny(); e = F.Call(ToSuffixOpName((Symbol)t.Value), e, e.Range.StartIndex, t.EndIndex); e.BaseStyle = NodeStyle.Operator; if ((t.Type() == TT.PreSufOp)) { primary = null; } } continue; match6: { var rhs = RVList <LNode> .Empty; rhs.Add(Expr(P.SuperExpr, out _)); // Line 138: greedy(Expr)* for (;;) { switch (LA0) { case TT.Id: case TT.Number: case TT.OtherLit: case TT.SQString: case TT.String: case TT.Symbol: rhs.Add(Expr(P.SuperExpr, out _)); break; case TT.At: { la1 = LA(1); if (la1 == TT.LBrack) { rhs.Add(Expr(P.SuperExpr, out _)); } else { goto stop; } } break; case TT.Assignment: case TT.BQString: case TT.Colon: case TT.Dot: case TT.NormalOp: case TT.Not: case TT.PrefixOp: case TT.PreSufOp: { switch (LA(1)) { case TT.Assignment: case TT.At: case TT.BQString: case TT.Colon: case TT.Dot: case TT.Id: case TT.LBrace: case TT.LBrack: case TT.LParen: case TT.NormalOp: case TT.Not: case TT.Number: case TT.OtherLit: case TT.PrefixOp: case TT.PreSufOp: case TT.SQString: case TT.String: case TT.Symbol: rhs.Add(Expr(P.SuperExpr, out _)); break; default: goto stop; } } break; case TT.LBrack: { la1 = LA(1); if (la1 == TT.RBrack) { rhs.Add(Expr(P.SuperExpr, out _)); } else { goto stop; } } break; case TT.LParen: { la1 = LA(1); if (la1 == TT.RParen) { rhs.Add(Expr(P.SuperExpr, out _)); } else { goto stop; } } break; case TT.LBrace: { la1 = LA(1); if (la1 == TT.RBrace) { rhs.Add(Expr(P.SuperExpr, out _)); } else { goto stop; } } break; default: goto stop; } } stop :; e = MakeSuperExpr(e, ref primary, rhs); } } stop2 :; return(attrs == null ? e : e.WithAttrs(attrs.ToRVList())); }
LNode Expr(Precedence context) { LNode e = default(LNode); Token t = default(Token); // line 123 Precedence prec; e = PrefixExpr(context); // Line 127: greedy( &{context.CanParse(prec = InfixPrecedenceOf(LT($LI)))} ((TT.Assignment|TT.BQString|TT.Dot|TT.NormalOp) | &{LA($LI + 1) != TT.Indent->@int} TT.Colon) Expr | &{context.CanParse(P.Primary)} FinishPrimaryExpr | &{context.CanParse(SuffixPrecedenceOf(LT($LI)))} TT.PreOrSufOp )* for (;;) { switch ((TT) LA0) { case TT.Assignment: case TT.BQString: case TT.Dot: case TT.NormalOp: { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) goto matchExpr; else goto stop; } case TT.Colon: { if (LA(0 + 1) != (int) TT.Indent) { if (context.CanParse(prec = InfixPrecedenceOf(LT(0)))) goto matchExpr; else goto stop; } else goto stop; } case TT.LBrack: case TT.LParen: case TT.Not: { if (context.CanParse(P.Primary)) e = FinishPrimaryExpr(e); else goto stop; } break; case TT.PreOrSufOp: { if (context.CanParse(SuffixPrecedenceOf(LT(0)))) { t = MatchAny(); // line 140 e = F.Call(ToSuffixOpName((Symbol) t.Value), e, e.Range.StartIndex, t.EndIndex).SetStyle(NodeStyle.Operator); } else goto stop; } break; default: goto stop; } continue; matchExpr: { // line 128 if ((!prec.CanMixWith(context))) { Error(0, "Operator '{0}' is not allowed in this context. Add parentheses to clarify the code's meaning.", LT0.Value); } // Line 131: ((TT.Assignment|TT.BQString|TT.Dot|TT.NormalOp) | &{LA($LI + 1) != TT.Indent->@int} TT.Colon) switch ((TT) LA0) { case TT.Assignment: case TT.BQString: case TT.Dot: case TT.NormalOp: t = MatchAny(); break; default: { Check(LA(0 + 1) != (int) TT.Indent, "LA($LI + 1) != TT.Indent->@int"); t = Match((int) TT.Colon); } break; } var rhs = Expr(prec); // line 133 e = F.Call((Symbol) t.Value, e, rhs, e.Range.StartIndex, rhs.Range.EndIndex).SetStyle(NodeStyle.Operator); } } stop:; // line 142 return e; }