vendor/symfony/expression-language/Lexer.php line 28

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\ExpressionLanguage;
  11. /**
  12.  * Lexes an expression.
  13.  *
  14.  * @author Fabien Potencier <fabien@symfony.com>
  15.  */
  16. class Lexer
  17. {
  18.     /**
  19.      * Tokenizes an expression.
  20.      *
  21.      * @return TokenStream
  22.      *
  23.      * @throws SyntaxError
  24.      */
  25.     public function tokenize(string $expression)
  26.     {
  27.         $expression str_replace(["\r""\n""\t""\v""\f"], ' '$expression);
  28.         $cursor 0;
  29.         $tokens = [];
  30.         $brackets = [];
  31.         $end \strlen($expression);
  32.         while ($cursor $end) {
  33.             if (' ' == $expression[$cursor]) {
  34.                 ++$cursor;
  35.                 continue;
  36.             }
  37.             if (preg_match('/[0-9]+(?:\.[0-9]+)?([Ee][\+\-][0-9]+)?/A'$expression$match0$cursor)) {
  38.                 // numbers
  39.                 $number = (float) $match[0];  // floats
  40.                 if (preg_match('/^[0-9]+$/'$match[0]) && $number <= \PHP_INT_MAX) {
  41.                     $number = (int) $match[0]; // integers lower than the maximum
  42.                 }
  43.                 $tokens[] = new Token(Token::NUMBER_TYPE$number$cursor 1);
  44.                 $cursor += \strlen($match[0]);
  45.             } elseif (false !== strpos('([{'$expression[$cursor])) {
  46.                 // opening bracket
  47.                 $brackets[] = [$expression[$cursor], $cursor];
  48.                 $tokens[] = new Token(Token::PUNCTUATION_TYPE$expression[$cursor], $cursor 1);
  49.                 ++$cursor;
  50.             } elseif (false !== strpos(')]}'$expression[$cursor])) {
  51.                 // closing bracket
  52.                 if (empty($brackets)) {
  53.                     throw new SyntaxError(sprintf('Unexpected "%s".'$expression[$cursor]), $cursor$expression);
  54.                 }
  55.                 [$expect$cur] = array_pop($brackets);
  56.                 if ($expression[$cursor] != strtr($expect'([{'')]}')) {
  57.                     throw new SyntaxError(sprintf('Unclosed "%s".'$expect), $cur$expression);
  58.                 }
  59.                 $tokens[] = new Token(Token::PUNCTUATION_TYPE$expression[$cursor], $cursor 1);
  60.                 ++$cursor;
  61.             } elseif (preg_match('/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As'$expression$match0$cursor)) {
  62.                 // strings
  63.                 $tokens[] = new Token(Token::STRING_TYPEstripcslashes(substr($match[0], 1, -1)), $cursor 1);
  64.                 $cursor += \strlen($match[0]);
  65.             } elseif (preg_match('/(?<=^|[\s(])not in(?=[\s(])|\!\=\=|(?<=^|[\s(])not(?=[\s(])|(?<=^|[\s(])and(?=[\s(])|\=\=\=|\>\=|(?<=^|[\s(])or(?=[\s(])|\<\=|\*\*|\.\.|(?<=^|[\s(])in(?=[\s(])|&&|\|\||(?<=^|[\s(])matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A'$expression$match0$cursor)) {
  66.                 // operators
  67.                 $tokens[] = new Token(Token::OPERATOR_TYPE$match[0], $cursor 1);
  68.                 $cursor += \strlen($match[0]);
  69.             } elseif (false !== strpos('.,?:'$expression[$cursor])) {
  70.                 // punctuation
  71.                 $tokens[] = new Token(Token::PUNCTUATION_TYPE$expression[$cursor], $cursor 1);
  72.                 ++$cursor;
  73.             } elseif (preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A'$expression$match0$cursor)) {
  74.                 // names
  75.                 $tokens[] = new Token(Token::NAME_TYPE$match[0], $cursor 1);
  76.                 $cursor += \strlen($match[0]);
  77.             } else {
  78.                 // unlexable
  79.                 throw new SyntaxError(sprintf('Unexpected character "%s".'$expression[$cursor]), $cursor$expression);
  80.             }
  81.         }
  82.         $tokens[] = new Token(Token::EOF_TYPEnull$cursor 1);
  83.         if (!empty($brackets)) {
  84.             [$expect$cur] = array_pop($brackets);
  85.             throw new SyntaxError(sprintf('Unclosed "%s".'$expect), $cur$expression);
  86.         }
  87.         return new TokenStream($tokens$expression);
  88.     }
  89. }