Ejemplo n.º 1
0
 /**
  * @dataProvider getTokenizeData
  */
 public function testTokenize($tokens, $expression)
 {
     $tokens[] = new Token('end of expression', null, strlen($expression) + 1);
     $lexer = new Lexer();
     $this->assertEquals(new TokenStream($tokens), $lexer->tokenize($expression));
 }
Ejemplo n.º 2
0
 /**
  * @dataProvider getInvalidPostfixData
  * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError
  */
 public function testParseWithInvalidPostfixData($expr, $names = array())
 {
     $lexer = new Lexer();
     $parser = new Parser(array());
     $parser->parse($lexer->tokenize($expr), $names);
 }
Ejemplo n.º 3
0
 /**
  * Actually tokenize an expression - at this point object and property access is
  * transformed, so that "this.property" will be "get('this.propery')"
  *
  * Also all function calls (but isset and empty) will be rewritten from
  * function(abc) to call("function", abc) to make dynamic functions possible
  *
  * @param string $expression The expression
  *
  * @return array
  */
 protected function tokenizeExpression($expression)
 {
     $stream = parent::tokenize($expression);
     $tokens = array();
     $previousWasDot = false;
     $ignorePrimaryExpressions = array_flip(['null', 'NULL', 'false', 'FALSE', 'true', 'TRUE']);
     while (!$stream->isEOF()) {
         /* @var \Symfony\Component\ExpressionLanguage\Token $token */
         $token = $stream->current;
         $stream->next();
         if ($token->type === Token::NAME_TYPE && !$previousWasDot) {
             if (array_key_exists($token->value, $ignorePrimaryExpressions)) {
                 $tokens[] = $token;
                 continue;
             }
             $isTest = false;
             if ($stream->current->test(Token::PUNCTUATION_TYPE, '(')) {
                 $tokens[] = $token;
                 $tokens[] = $stream->current;
                 $stream->next();
                 if ($token->value === 'isset' || $token->value === 'empty') {
                     $isTest = true;
                     $token = $stream->current;
                     if ($token->type !== Token::NAME_TYPE) {
                         throw new SyntaxError('Expected name', $token->cursor);
                     }
                     $stream->next();
                 } else {
                     $tokens[] = new Token(Token::STRING_TYPE, $token->value, $token->cursor);
                     $token->value = 'call';
                     if (!$stream->current->test(Token::PUNCTUATION_TYPE, ')')) {
                         $tokens[] = new Token(Token::PUNCTUATION_TYPE, ',', $token->cursor);
                     }
                     continue;
                 }
             }
             $names = array($token->value);
             $isFunctionCall = false;
             while (!$stream->isEOF() && $stream->current->type === Token::PUNCTUATION_TYPE && $stream->current->value === '.') {
                 $stream->next();
                 $nameToken = $stream->current;
                 $stream->next();
                 // Operators like "not" and "matches" are valid method or property names - others not
                 if ($nameToken->type !== Token::NAME_TYPE && ($nameToken->type !== Token::OPERATOR_TYPE || !preg_match('/[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/A', $nameToken->value))) {
                     throw new SyntaxError('Expected name', $nameToken->cursor);
                 }
                 if ($stream->current->test(Token::PUNCTUATION_TYPE, '(')) {
                     $isFunctionCall = true;
                 } else {
                     $names[] = $nameToken->value;
                 }
             }
             if ($isTest) {
                 if ($isFunctionCall) {
                     throw new SyntaxError('Can\'t use function return value in write context', $stream->current->cursor);
                 }
                 if (!$stream->current->test(Token::PUNCTUATION_TYPE, ')')) {
                     throw new SyntaxError('Expected )', $stream->current->cursor);
                 }
                 $tokens[] = new Token(Token::STRING_TYPE, implode('.', $names), $token->cursor);
             } else {
                 $tokens[] = new Token(Token::NAME_TYPE, 'get', $token->cursor);
                 $tokens[] = new Token(Token::PUNCTUATION_TYPE, '(', $token->cursor);
                 $tokens[] = new Token(Token::STRING_TYPE, implode('.', $names), $token->cursor);
                 $tokens[] = new Token(Token::PUNCTUATION_TYPE, ')', $token->cursor);
                 if ($isFunctionCall) {
                     $tokens[] = new Token(Token::PUNCTUATION_TYPE, '.', $nameToken->cursor - strlen($nameToken->value));
                     $tokens[] = $nameToken;
                 }
             }
         } else {
             $tokens[] = $token;
             $previousWasDot = $token->test(Token::PUNCTUATION_TYPE, '.');
         }
     }
     return $tokens;
 }
Ejemplo n.º 4
0
 /**
  * @dataProvider getParseData
  */
 public function testParse($node, $expression, $names = array())
 {
     $lexer = new Lexer();
     $parser = new Parser(array());
     $this->assertEquals($node, $parser->parse($lexer->tokenize($expression), $names));
 }