void Lex()

in MySQL.Data/src/X/Protocol/X/ExprParser.cs [258:478]


    void Lex()
    {
      for (int i = 0; i < this.stringValue.Length; ++i)
      {
        int start = i; // for routines that consume more than one char
        char c = this.stringValue[i];
        if (Char.IsWhiteSpace(c))
        {
          // ignore
        }
        else if (Char.IsDigit(c))
        {
          if (i != stringValue.Length - 1)
          {
            if (!Char.IsLetter(stringValue[i + 1]) || NextCharEquals(i, 'e')) i = LexNumber(i);
            else Identifier(ref i, start);
          }
          else i = LexNumber(i);
        }
        else if (!(c == '_' || Char.IsLetter(c)))
        {
          // non-identifier, e.g. operator or quoted literal
          switch (c)
          {
            case ':':
              this.tokens.Add(new Token(TokenType.COLON, c));
              break;
            case '+':
              this.tokens.Add(new Token(TokenType.PLUS, c));
              break;
            case '-':
              if (NextCharEquals(i, '>'))
              {
                i++;
                if (NextCharEquals(i, '>'))
                {
                  i++;
                  this.tokens.Add(new Token(TokenType.DOUBLE_ARROW, "->>"));
                }
                else
                {
                  this.tokens.Add(new Token(TokenType.ARROW, "->"));
                }
              }
              else
              {
                this.tokens.Add(new Token(TokenType.MINUS, c));
              }
              break;
            case '*':
              if (NextCharEquals(i, '*'))
              {
                i++;
                this.tokens.Add(new Token(TokenType.DOUBLESTAR, "**"));
              }
              else
              {
                this.tokens.Add(new Token(TokenType.STAR, c));
              }
              break;
            case '/':
              this.tokens.Add(new Token(TokenType.SLASH, c));
              break;
            case '$':
              this.tokens.Add(new Token(TokenType.AT, c));
              break;
            case '%':
              this.tokens.Add(new Token(TokenType.MOD, c));
              break;
            case '=':
              if (NextCharEquals(i, '='))
              {
                i++;
              }
              this.tokens.Add(new Token(TokenType.EQ, "=="));
              break;
            case '&':
              if (NextCharEquals(i, '&'))
              {
                i++;
                this.tokens.Add(new Token(TokenType.ANDAND, "&&"));
              }
              else
              {
                this.tokens.Add(new Token(TokenType.BITAND, c));
              }
              break;
            case '|':
              if (NextCharEquals(i, '|'))
              {
                i++;
                this.tokens.Add(new Token(TokenType.OROR, "||"));
              }
              else
              {
                this.tokens.Add(new Token(TokenType.BITOR, c));
              }
              break;
            case '^':
              this.tokens.Add(new Token(TokenType.BITXOR, c));
              break;
            case '(':
              this.tokens.Add(new Token(TokenType.LPAREN, c));
              break;
            case ')':
              this.tokens.Add(new Token(TokenType.RPAREN, c));
              break;
            case '[':
              this.tokens.Add(new Token(TokenType.LSQBRACKET, c));
              break;
            case ']':
              this.tokens.Add(new Token(TokenType.RSQBRACKET, c));
              break;
            case '{':
              this.tokens.Add(new Token(TokenType.LCURLY, c));
              break;
            case '}':
              this.tokens.Add(new Token(TokenType.RCURLY, c));
              break;
            case '~':
              this.tokens.Add(new Token(TokenType.NEG, c));
              break;
            case ',':
              this.tokens.Add(new Token(TokenType.COMMA, c));
              break;
            case '!':
              if (NextCharEquals(i, '='))
              {
                i++;
                this.tokens.Add(new Token(TokenType.NE, "!="));
              }
              else
              {
                this.tokens.Add(new Token(TokenType.BANG, c));
              }
              break;
            case '?':
              this.tokens.Add(new Token(TokenType.EROTEME, c));
              break;
            case '<':
              if (NextCharEquals(i, '<'))
              {
                i++;
                this.tokens.Add(new Token(TokenType.LSHIFT, "<<"));
              }
              else if (NextCharEquals(i, '='))
              {
                i++;
                this.tokens.Add(new Token(TokenType.LE, "<="));
              }
              else
              {
                this.tokens.Add(new Token(TokenType.LT, c));
              }
              break;
            case '>':
              if (NextCharEquals(i, '>'))
              {
                i++;
                this.tokens.Add(new Token(TokenType.RSHIFT, ">>"));
              }
              else if (NextCharEquals(i, '='))
              {
                i++;
                this.tokens.Add(new Token(TokenType.GE, ">="));
              }
              else
              {
                this.tokens.Add(new Token(TokenType.GT, c));
              }
              break;
            case '.':
              if (NextCharEquals(i, '*'))
              {
                i++;
                this.tokens.Add(new Token(TokenType.DOTSTAR, ".*"));
              }
              else if (i + 1 < this.stringValue.Length && Char.IsDigit(this.stringValue[i + 1]))
              {
                i = LexNumber(i);
              }
              else
              {
                this.tokens.Add(new Token(TokenType.DOT, c));
              }
              break;
            case '"':
            case '\'':
            case '`':
              char quoteChar = c;
              StringBuilder val = new StringBuilder();
              try
              {
                for (c = this.stringValue[++i]; c != quoteChar || (i + 1 < this.stringValue.Length && this.stringValue[i + 1] == quoteChar);
                     c = this.stringValue[++i])
                {
                  if (c == '\\' || c == quoteChar)
                  {
                    ++i;
                  }
                  val.Append(this.stringValue[i]);
                }
              }
              catch (IndexOutOfRangeException)
              {
                throw new ArgumentException("Unterminated string starting at " + start);
              }
              var value = val.ToString();
              this.tokens.Add(new Token(quoteChar == '`' ? TokenType.IDENT : TokenType.LSTRING, value == string.Empty ? "" : value));
              break;
            default:
              throw new ArgumentException("Can't parse at pos: " + i);
          }
        }
        else
        {
          // otherwise, it's an identifier
          Identifier(ref i, start);
        }
      }
    }