Expr IlriExpr()

in MySQL.Data/src/X/Protocol/X/ExprParser.cs [1128:1204]


    Expr IlriExpr()
    {
      Expr lhs = CompExpr();
      List<TokenType> expected = new List<TokenType>(new TokenType[] { TokenType.IS, TokenType.IN, TokenType.LIKE, TokenType.BETWEEN, TokenType.REGEXP, TokenType.NOT, TokenType.OVERLAPS });
      while (this.tokenPos < this.tokens.Count && expected.Contains(this.tokens[this.tokenPos].type))
      {
        bool isNot = false;
        if (CurrentTokenTypeEquals(TokenType.NOT))
        {
          ConsumeToken(TokenType.NOT);
          isNot = true;
        }
        if (this.tokenPos < this.tokens.Count)
        {
          List<Expr> parameters = new List<Expr>();
          parameters.Add(lhs);
          string opName = this.tokens[this.tokenPos].value.ToLowerInvariant();
          switch (this.tokens[this.tokenPos].type)
          {
            case TokenType.IS: // for IS, NOT comes AFTER
              ConsumeToken(TokenType.IS);
              if (CurrentTokenTypeEquals(TokenType.NOT))
              {
                ConsumeToken(TokenType.NOT);
                opName = "is_not";
              }
              parameters.Add(CompExpr());
              break;
            case TokenType.IN:
              ConsumeToken(TokenType.IN);
              if (CurrentTokenTypeEquals(TokenType.LPAREN)) parameters.AddRange(ParenExprList());
              else
              {
                opName = "cont_in";
                parameters.Add(CompExpr());
              }
              break;
            case TokenType.LIKE:
              ConsumeToken(TokenType.LIKE);
              parameters.Add(CompExpr());
              if (CurrentTokenTypeEquals(TokenType.ESCAPE))
              {
                ConsumeToken(TokenType.ESCAPE);
                // add as a third (optional) param
                parameters.Add(CompExpr());
              }
              break;
            case TokenType.BETWEEN:
              ConsumeToken(TokenType.BETWEEN);
              parameters.Add(CompExpr());
              AssertTokenAt(this.tokenPos, TokenType.AND);
              ConsumeToken(TokenType.AND);
              parameters.Add(CompExpr());
              break;
            case TokenType.REGEXP:
              ConsumeToken(TokenType.REGEXP);
              parameters.Add(CompExpr());
              break;
            case TokenType.OVERLAPS:
              ConsumeToken(TokenType.OVERLAPS);
              parameters.Add(CompExpr());
              break;
            default:
              throw new ArgumentException("Unknown token after NOT at pos: " + this.tokenPos);
          }
          if (isNot)
          {
            opName = "not_" + opName;
          }
          Operator builder = new Operator();
          builder.Name = opName;
          builder.Param.Add(parameters);
          lhs = new Expr() { Type = Expr.Types.Type.Operator, Operator = builder };
        }
      }
      return lhs;
    }