Commit 4a861f08 authored by guilhermeblanco's avatar guilhermeblanco

[2.0] More refactorings in Annotations parser and DQL parser. Now they only...

[2.0] More refactorings in Annotations parser and DQL parser. Now they only use constants instead of string processment
parent e05ec39f
...@@ -34,13 +34,22 @@ namespace Doctrine\Common\Annotations; ...@@ -34,13 +34,22 @@ namespace Doctrine\Common\Annotations;
*/ */
class Lexer extends \Doctrine\Common\Lexer class Lexer extends \Doctrine\Common\Lexer
{ {
const T_NONE = 1; const T_NONE = 1;
const T_FLOAT = 2; const T_IDENTIFIER = 2;
const T_INTEGER = 3; const T_INTEGER = 3;
const T_STRING = 4; const T_STRING = 4;
const T_IDENTIFIER = 5; const T_FLOAT = 5;
const T_TRUE = 6;
const T_FALSE = 7; const T_AT = 101;
const T_CLOSE_CURLY_BRACES = 102;
const T_CLOSE_PARENTHESIS = 103;
const T_COMMA = 104;
const T_EQUALS = 105;
const T_FALSE = 106;
const T_NAMESPACE_SEPARATOR = 107;
const T_OPEN_CURLY_BRACES = 108;
const T_OPEN_PARENTHESIS = 109;
const T_TRUE = 110;
/** /**
* @inheritdoc * @inheritdoc
...@@ -70,21 +79,34 @@ class Lexer extends \Doctrine\Common\Lexer ...@@ -70,21 +79,34 @@ class Lexer extends \Doctrine\Common\Lexer
$type = self::T_NONE; $type = self::T_NONE;
$newVal = $this->_getNumeric($value); $newVal = $this->_getNumeric($value);
// Checking numeric value
if ($newVal !== false){ if ($newVal !== false){
$value = $newVal; $value = $newVal;
if (strpos($value, '.') !== false || stripos($value, 'e') !== false) { return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
$type = self::T_FLOAT; ? self::T_FLOAT : self::T_INTEGER;
} else {
$type = self::T_INTEGER;
}
} }
if ($value[0] === '"') { if ($value[0] === '"') {
$type = self::T_STRING;
$value = str_replace('""', '"', substr($value, 1, strlen($value) - 2)); $value = str_replace('""', '"', substr($value, 1, strlen($value) - 2));
return self::T_STRING;
} else if (ctype_alpha($value[0]) || $value[0] === '_') { } else if (ctype_alpha($value[0]) || $value[0] === '_') {
$type = $this->_checkLiteral($value); return $this->_checkLiteral($value);
} else {
switch ($value) {
case '@': return self::T_AT;
case ',': return self::T_COMMA;
case '(': return self::T_OPEN_PARENTHESIS;
case ')': return self::T_CLOSE_PARENTHESIS;
case '{': return self::T_OPEN_CURLY_BRACES;
case '}': return self::T_CLOSE_CURLY_BRACES;
case '=': return self::T_EQUALS;
case '\\': return self::T_NAMESPACE_SEPARATOR;
default:
// Do nothing
break;
}
} }
return $type; return $type;
......
...@@ -130,7 +130,7 @@ class Parser ...@@ -130,7 +130,7 @@ class Parser
$this->_lexer->setInput(trim($input, '* /')); $this->_lexer->setInput(trim($input, '* /'));
$this->_lexer->moveNext(); $this->_lexer->moveNext();
if ($this->_lexer->isNextToken('@')) { if ($this->_lexer->isNextToken(Lexer::T_AT)) {
return $this->Annotations(); return $this->Annotations();
} }
...@@ -146,11 +146,8 @@ class Parser ...@@ -146,11 +146,8 @@ class Parser
*/ */
public function match($token) public function match($token)
{ {
$key = (is_string($token)) ? 'value' : 'type'; if ( ! ($this->_lexer->lookahead['type'] === $token)) {
$this->syntaxError($this->_lexer->getLiteral($token));
if ( ! ($this->_lexer->lookahead[$key] === $token)) {
$token = (is_string($token)) ? $token : $token['value'];
$this->syntaxError($token);
} }
$this->_lexer->moveNext(); $this->_lexer->moveNext();
...@@ -169,7 +166,7 @@ class Parser ...@@ -169,7 +166,7 @@ class Parser
$token = $this->_lexer->lookahead; $token = $this->_lexer->lookahead;
} }
$message = "Expected '{$expected}', got "; $message = "Expected {$expected}, got ";
if ($this->_lexer->lookahead === null) { if ($this->_lexer->lookahead === null) {
$message .= 'end of string'; $message .= 'end of string';
...@@ -201,7 +198,7 @@ class Parser ...@@ -201,7 +198,7 @@ class Parser
$annotations[get_class($annot)] = $annot; $annotations[get_class($annot)] = $annot;
} }
while ($this->_lexer->lookahead !== null && $this->_lexer->lookahead['value'] == '@') { while ($this->_lexer->lookahead !== null && $this->_lexer->isNextToken(Lexer::T_AT)) {
$this->_isNestedAnnotation = false; $this->_isNestedAnnotation = false;
$annot = $this->Annotation(); $annot = $this->Annotation();
...@@ -228,12 +225,12 @@ class Parser ...@@ -228,12 +225,12 @@ class Parser
$values = array(); $values = array();
$nameParts = array(); $nameParts = array();
$this->match('@'); $this->match(Lexer::T_AT);
$this->match(Lexer::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$nameParts[] = $this->_lexer->token['value']; $nameParts[] = $this->_lexer->token['value'];
while ($this->_lexer->isNextToken('\\')) { while ($this->_lexer->isNextToken(Lexer::T_NAMESPACE_SEPARATOR)) {
$this->match('\\'); $this->match(Lexer::T_NAMESPACE_SEPARATOR);
$this->match(Lexer::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$nameParts[] = $this->_lexer->token['value']; $nameParts[] = $this->_lexer->token['value'];
} }
...@@ -250,12 +247,12 @@ class Parser ...@@ -250,12 +247,12 @@ class Parser
// If it really an annotation class? // If it really an annotation class?
if ( if (
(! $this->_isNestedAnnotation && $this->_lexer->lookahead != null && (! $this->_isNestedAnnotation && $this->_lexer->lookahead != null &&
! $this->_lexer->isNextToken('(') && ! $this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS) &&
! $this->_lexer->isNextToken('@')) || ! $this->_lexer->isNextToken(Lexer::T_AT)) ||
! class_exists($name, false) || ! class_exists($name, false) ||
! is_subclass_of($name, 'Doctrine\Common\Annotations\Annotation') ! is_subclass_of($name, 'Doctrine\Common\Annotations\Annotation')
) { ) {
$this->_lexer->skipUntil('@'); $this->_lexer->skipUntil(Lexer::T_AT);
return false; return false;
} }
...@@ -263,14 +260,14 @@ class Parser ...@@ -263,14 +260,14 @@ class Parser
// Next will be nested // Next will be nested
$this->_isNestedAnnotation = true; $this->_isNestedAnnotation = true;
if ($this->_lexer->isNextToken('(')) { if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
$this->match('('); $this->match(Lexer::T_OPEN_PARENTHESIS);
if ( ! $this->_lexer->isNextToken(')')) { if ( ! $this->_lexer->isNextToken(Lexer::T_CLOSE_PARENTHESIS)) {
$values = $this->Values(); $values = $this->Values();
} }
$this->match(')'); $this->match(Lexer::T_CLOSE_PARENTHESIS);
} }
return new $name($values); return new $name($values);
...@@ -286,19 +283,19 @@ class Parser ...@@ -286,19 +283,19 @@ class Parser
$values = array(); $values = array();
// Handle the case of a single array as value, i.e. @Foo({....}) // Handle the case of a single array as value, i.e. @Foo({....})
if ($this->_lexer->isNextToken('{')) { if ($this->_lexer->isNextToken(Lexer::T_OPEN_CURLY_BRACES)) {
$values['value'] = $this->Value(); $values['value'] = $this->Value();
return $values; return $values;
} }
$values[] = $this->Value(); $values[] = $this->Value();
while ($this->_lexer->isNextToken(',')) { while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
$this->match(','); $this->match(Lexer::T_COMMA);
$value = $this->Value(); $value = $this->Value();
if ( ! is_array($value)) { if ( ! is_array($value)) {
$this->syntaxError('FieldAssignment', $value); $this->syntaxError('Value', $value);
} }
$values[] = $value; $values[] = $value;
...@@ -341,11 +338,11 @@ class Parser ...@@ -341,11 +338,11 @@ class Parser
*/ */
public function PlainValue() public function PlainValue()
{ {
if ($this->_lexer->lookahead['value'] == '{') { if ($this->_lexer->isNextToken(Lexer::T_OPEN_CURLY_BRACES)) {
return $this->Arrayx(); return $this->Arrayx();
} }
if ($this->_lexer->lookahead['value'] == '@') { if ($this->_lexer->isNextToken(Lexer::T_AT)) {
return $this->Annotation(); return $this->Annotation();
} }
...@@ -385,7 +382,7 @@ class Parser ...@@ -385,7 +382,7 @@ class Parser
{ {
$this->match(Lexer::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$fieldName = $this->_lexer->token['value']; $fieldName = $this->_lexer->token['value'];
$this->match('='); $this->match(Lexer::T_EQUALS);
return array($fieldName => $this->PlainValue()); return array($fieldName => $this->PlainValue());
} }
...@@ -399,15 +396,15 @@ class Parser ...@@ -399,15 +396,15 @@ class Parser
{ {
$array = $values = array(); $array = $values = array();
$this->match('{'); $this->match(Lexer::T_OPEN_CURLY_BRACES);
$values[] = $this->ArrayEntry(); $values[] = $this->ArrayEntry();
while ($this->_lexer->isNextToken(',')) { while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
$this->match(','); $this->match(Lexer::T_COMMA);
$values[] = $this->ArrayEntry(); $values[] = $this->ArrayEntry();
} }
$this->match('}'); $this->match(Lexer::T_CLOSE_CURLY_BRACES);
foreach ($values as $value) { foreach ($values as $value) {
$key = key($value); $key = key($value);
...@@ -434,14 +431,12 @@ class Parser ...@@ -434,14 +431,12 @@ class Parser
$peek = $this->_lexer->glimpse(); $peek = $this->_lexer->glimpse();
if ($peek['value'] == '=') { if ($peek['value'] == '=') {
if ($this->_lexer->lookahead['type'] === Lexer::T_INTEGER) { $this->match(
$this->match(Lexer::T_INTEGER); $this->_lexer->isNextToken(Lexer::T_INTEGER) ? Lexer::T_INTEGER : Lexer::T_STRING
} else { );
$this->match(Lexer::T_STRING);
}
$key = $this->_lexer->token['value']; $key = $this->_lexer->token['value'];
$this->match('='); $this->match(Lexer::T_EQUALS);
return array($key => $this->PlainValue()); return array($key => $this->PlainValue());
} }
......
...@@ -110,8 +110,7 @@ abstract class Lexer ...@@ -110,8 +110,7 @@ abstract class Lexer
*/ */
public function isNextToken($token) public function isNextToken($token)
{ {
$la = $this->lookahead; return $this->lookahead['type'] === $token;
return ($la['type'] === $token || $la['value'] === $token);
} }
/** /**
...@@ -138,11 +137,11 @@ abstract class Lexer ...@@ -138,11 +137,11 @@ abstract class Lexer
/** /**
* Tells the lexer to skip input tokens until it sees a token with the given value. * Tells the lexer to skip input tokens until it sees a token with the given value.
* *
* @param $value The value to skip until. * @param $type The token type to skip until.
*/ */
public function skipUntil($value) public function skipUntil($type)
{ {
while ($this->lookahead !== null && $this->lookahead['value'] !== $value) { while ($this->lookahead !== null && $this->lookahead['type'] !== $type) {
$this->moveNext(); $this->moveNext();
} }
} }
...@@ -214,6 +213,27 @@ abstract class Lexer ...@@ -214,6 +213,27 @@ abstract class Lexer
} }
} }
/**
* Gets the literal for a given token.
*
* @param integer $token
* @return string
*/
public function getLiteral($token)
{
$className = get_class($this);
$reflClass = new \ReflectionClass($className);
$constants = $reflClass->getConstants();
foreach ($constants as $name => $value) {
if ($value === $token) {
return $className . '::' . $name;
}
}
return $token;
}
/** /**
* Lexical catchable patterns * Lexical catchable patterns
* *
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "ABS" "(" SimpleArithmeticExpression ")" * "ABS" "(" SimpleArithmeticExpression ")"
* *
...@@ -52,10 +54,13 @@ class AbsFunction extends FunctionNode ...@@ -52,10 +54,13 @@ class AbsFunction extends FunctionNode
public function parse(\Doctrine\ORM\Query\Parser $parser) public function parse(\Doctrine\ORM\Query\Parser $parser)
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']);
$parser->match('('); $parser->match(Lexer::T_ABS);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(')');
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "CONCAT" "(" StringPrimary "," StringPrimary ")" * "CONCAT" "(" StringPrimary "," StringPrimary ")"
* *
...@@ -55,14 +57,15 @@ class ConcatFunction extends FunctionNode ...@@ -55,14 +57,15 @@ class ConcatFunction extends FunctionNode
public function parse(\Doctrine\ORM\Query\Parser $parser) public function parse(\Doctrine\ORM\Query\Parser $parser)
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']);
$parser->match('('); $parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->firstStringPrimary = $parser->StringPrimary(); $this->firstStringPrimary = $parser->StringPrimary();
$parser->match(','); $parser->match(Lexer::T_COMMA);
$this->secondStringPrimary = $parser->StringPrimary(); $this->secondStringPrimary = $parser->StringPrimary();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "CURRENT_DATE" * "CURRENT_DATE"
* *
...@@ -48,8 +50,9 @@ class CurrentDateFunction extends FunctionNode ...@@ -48,8 +50,9 @@ class CurrentDateFunction extends FunctionNode
public function parse(\Doctrine\ORM\Query\Parser $parser) public function parse(\Doctrine\ORM\Query\Parser $parser)
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']);
$parser->match('('); $parser->match(Lexer::T_IDENTIFIER);
$parser->match(')'); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
\ No newline at end of file
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "CURRENT_TIME" * "CURRENT_TIME"
* *
...@@ -48,8 +50,9 @@ class CurrentTimeFunction extends FunctionNode ...@@ -48,8 +50,9 @@ class CurrentTimeFunction extends FunctionNode
public function parse(\Doctrine\ORM\Query\Parser $parser) public function parse(\Doctrine\ORM\Query\Parser $parser)
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']);
$parser->match('('); $parser->match(Lexer::T_IDENTIFIER);
$parser->match(')'); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
\ No newline at end of file
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "CURRENT_TIMESTAMP" * "CURRENT_TIMESTAMP"
* *
...@@ -27,8 +29,9 @@ class CurrentTimestampFunction extends FunctionNode ...@@ -27,8 +29,9 @@ class CurrentTimestampFunction extends FunctionNode
public function parse(\Doctrine\ORM\Query\Parser $parser) public function parse(\Doctrine\ORM\Query\Parser $parser)
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']);
$parser->match('('); $parser->match(Lexer::T_IDENTIFIER);
$parser->match(')'); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
\ No newline at end of file
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "LENGTH" "(" StringPrimary ")" * "LENGTH" "(" StringPrimary ")"
* *
...@@ -52,12 +54,12 @@ class LengthFunction extends FunctionNode ...@@ -52,12 +54,12 @@ class LengthFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_IDENTIFIER);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringPrimary = $parser->StringPrimary(); $this->stringPrimary = $parser->StringPrimary();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" * "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")"
* *
...@@ -59,22 +61,22 @@ class LocateFunction extends FunctionNode ...@@ -59,22 +61,22 @@ class LocateFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_IDENTIFIER);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->firstStringPrimary = $parser->StringPrimary(); $this->firstStringPrimary = $parser->StringPrimary();
$parser->match(','); $parser->match(Lexer::T_COMMA);
$this->secondStringPrimary = $parser->StringPrimary(); $this->secondStringPrimary = $parser->StringPrimary();
if ($lexer->isNextToken(',')) { if ($lexer->isNextToken(Lexer::T_COMMA)) {
$parser->match(','); $parser->match(Lexer::T_COMMA);
$this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
} }
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "LOWER" "(" StringPrimary ")" * "LOWER" "(" StringPrimary ")"
* *
...@@ -52,12 +54,12 @@ class LowerFunction extends FunctionNode ...@@ -52,12 +54,12 @@ class LowerFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_IDENTIFIER);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringPrimary = $parser->StringPrimary(); $this->stringPrimary = $parser->StringPrimary();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" * "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")"
* *
...@@ -57,16 +59,16 @@ class ModFunction extends FunctionNode ...@@ -57,16 +59,16 @@ class ModFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_MOD);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(','); $parser->match(Lexer::T_COMMA);
$this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "SIZE" "(" CollectionValuedPathExpression ")" * "SIZE" "(" CollectionValuedPathExpression ")"
* *
...@@ -77,12 +79,12 @@ class SizeFunction extends FunctionNode ...@@ -77,12 +79,12 @@ class SizeFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_SIZE);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->collectionPathExpression = $parser->CollectionValuedPathExpression(); $this->collectionPathExpression = $parser->CollectionValuedPathExpression();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "SQRT" "(" SimpleArithmeticExpression ")" * "SQRT" "(" SimpleArithmeticExpression ")"
* *
...@@ -52,12 +54,12 @@ class SqrtFunction extends FunctionNode ...@@ -52,12 +54,12 @@ class SqrtFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_IDENTIFIER);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" * "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")"
* *
...@@ -60,19 +62,20 @@ class SubstringFunction extends FunctionNode ...@@ -60,19 +62,20 @@ class SubstringFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_IDENTIFIER);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringPrimary = $parser->StringPrimary(); $this->stringPrimary = $parser->StringPrimary();
$parser->match(','); $parser->match(Lexer::T_COMMA);
$this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(',');
$parser->match(Lexer::T_COMMA);
$this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -71,17 +71,17 @@ class TrimFunction extends FunctionNode ...@@ -71,17 +71,17 @@ class TrimFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_IDENTIFIER);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
if (strcasecmp('leading', $lexer->lookahead['value']) === 0) { if (strcasecmp('leading', $lexer->lookahead['value']) === 0) {
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_LEADING);
$this->leading = true; $this->leading = true;
} else if (strcasecmp('trailing', $lexer->lookahead['value']) === 0) { } else if (strcasecmp('trailing', $lexer->lookahead['value']) === 0) {
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_TRAILING);
$this->trailing = true; $this->trailing = true;
} else if (strcasecmp('both', $lexer->lookahead['value']) === 0) { } else if (strcasecmp('both', $lexer->lookahead['value']) === 0) {
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_BOTH);
$this->both = true; $this->both = true;
} }
...@@ -96,7 +96,7 @@ class TrimFunction extends FunctionNode ...@@ -96,7 +96,7 @@ class TrimFunction extends FunctionNode
$this->stringPrimary = $parser->StringPrimary(); $this->stringPrimary = $parser->StringPrimary();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query\AST\Functions; namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\Lexer;
/** /**
* "UPPER" "(" StringPrimary ")" * "UPPER" "(" StringPrimary ")"
* *
...@@ -52,12 +54,12 @@ class UpperFunction extends FunctionNode ...@@ -52,12 +54,12 @@ class UpperFunction extends FunctionNode
{ {
$lexer = $parser->getLexer(); $lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']); $parser->match(Lexer::T_IDENTIFIER);
$parser->match('('); $parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringPrimary = $parser->StringPrimary(); $this->stringPrimary = $parser->StringPrimary();
$parser->match(')'); $parser->match(Lexer::T_CLOSE_PARENTHESIS);
} }
} }
...@@ -48,59 +48,62 @@ class Lexer extends \Doctrine\Common\Lexer ...@@ -48,59 +48,62 @@ class Lexer extends \Doctrine\Common\Lexer
const T_ASC = 105; const T_ASC = 105;
const T_AVG = 106; const T_AVG = 106;
const T_BETWEEN = 107; const T_BETWEEN = 107;
const T_BY = 108; const T_BOTH = 108;
const T_CLOSE_PARENTHESIS = 109; const T_BY = 109;
const T_COMMA = 110; const T_CLOSE_PARENTHESIS = 110;
const T_COUNT = 111; const T_COMMA = 111;
const T_DELETE = 112; const T_COUNT = 112;
const T_DESC = 113; const T_DELETE = 113;
const T_DISTINCT = 114; const T_DESC = 114;
const T_DIVIDE = 115; const T_DISTINCT = 115;
const T_DOT = 116; const T_DIVIDE = 116;
const T_EMPTY = 117; const T_DOT = 117;
const T_EQUALS = 118; const T_EMPTY = 118;
const T_ESCAPE = 119; const T_EQUALS = 119;
const T_EXISTS = 120; const T_ESCAPE = 120;
const T_FALSE = 121; const T_EXISTS = 121;
const T_FROM = 122; const T_FALSE = 122;
const T_GREATER_THAN = 123; const T_FROM = 123;
const T_GROUP = 124; const T_GREATER_THAN = 124;
const T_HAVING = 125; const T_GROUP = 125;
const T_IN = 126; const T_HAVING = 126;
const T_INDEX = 127; const T_IN = 127;
const T_INNER = 128; const T_INDEX = 128;
const T_IS = 129; const T_INNER = 129;
const T_JOIN = 130; const T_IS = 130;
const T_LEFT = 131; const T_JOIN = 131;
const T_LIKE = 132; const T_LEADING = 132;
const T_LIMIT = 133; const T_LEFT = 133;
const T_LOWER_THAN = 134; const T_LIKE = 134;
const T_MAX = 135; const T_LIMIT = 135;
const T_MEMBER = 136; const T_LOWER_THAN = 136;
const T_MIN = 137; const T_MAX = 137;
const T_MINUS = 138; const T_MEMBER = 138;
const T_MOD = 139; const T_MIN = 139;
const T_MULTIPLY = 140; const T_MINUS = 140;
const T_NEGATE = 141; const T_MOD = 141;
const T_NOT = 142; const T_MULTIPLY = 142;
const T_NULL = 143; const T_NEGATE = 143;
const T_OF = 144; const T_NOT = 144;
const T_OFFSET = 145; const T_NULL = 145;
const T_ON = 146; const T_OF = 146;
const T_OPEN_PARENTHESIS = 147; const T_OFFSET = 147;
const T_OR = 148; const T_ON = 148;
const T_ORDER = 149; const T_OPEN_PARENTHESIS = 149;
const T_OUTER = 150; const T_OR = 150;
const T_PLUS = 151; const T_ORDER = 151;
const T_SELECT = 152; const T_OUTER = 152;
const T_SET = 153; const T_PLUS = 153;
const T_SIZE = 154; const T_SELECT = 154;
const T_SOME = 155; const T_SET = 155;
const T_SUM = 156; const T_SIZE = 156;
const T_TRUE = 157; const T_SOME = 157;
const T_UPDATE = 158; const T_SUM = 158;
const T_WHERE = 159; const T_TRAILING = 159;
const T_WITH = 160; const T_TRUE = 160;
const T_UPDATE = 161;
const T_WHERE = 162;
const T_WITH = 163;
private $_keywordsTable; private $_keywordsTable;
...@@ -217,68 +220,4 @@ class Lexer extends \Doctrine\Common\Lexer ...@@ -217,68 +220,4 @@ class Lexer extends \Doctrine\Common\Lexer
return self::T_IDENTIFIER; return self::T_IDENTIFIER;
} }
/**
* Gets the literal for a given token.
*
* @param mixed $token
* @return string
*/
public function getLiteral($token)
{
if ( ! $this->_keywordsTable) {
$this->_keywordsTable = array(
self::T_ALL => "ALL",
self::T_AND => "AND",
self::T_ANY => "ANY",
self::T_AS => "AS",
self::T_ASC => "ASC",
self::T_AVG => "AVG",
self::T_BETWEEN => "BETWEEN",
self::T_BY => "BY",
self::T_COMMA => ",",
self::T_COUNT => "COUNT",
self::T_DELETE => "DELETE",
self::T_DESC => "DESC",
self::T_DISTINCT => "DISTINCT",
self::T_DOT => ".",
self::T_EMPTY => "EMPTY",
self::T_ESCAPE => "ESCAPE",
self::T_EXISTS => "EXISTS",
self::T_FALSE => "FALSE",
self::T_FROM => "FROM",
self::T_GROUP => "GROUP",
self::T_HAVING => "HAVING",
self::T_IN => "IN",
self::T_INDEX => "INDEX",
self::T_INNER => "INNER",
self::T_IS => "IS",
self::T_JOIN => "JOIN",
self::T_LEFT => "LEFT",
self::T_LIKE => "LIKE",
self::T_LIMIT => "LIMIT",
self::T_MAX => "MAX",
self::T_MIN => "MIN",
self::T_MOD => "MOD",
self::T_NOT => "NOT",
self::T_NULL => "NULL",
self::T_OFFSET => "OFFSET",
self::T_ON => "ON",
self::T_OR => "OR",
self::T_ORDER => "ORDER",
self::T_OUTER => "OUTER",
self::T_SELECT => "SELECT",
self::T_SET => "SET",
self::T_SIZE => "SIZE",
self::T_SOME => "SOME",
self::T_SUM => "SUM",
self::T_TRUE => "TRUE",
self::T_UPDATE => "UPDATE",
self::T_WHERE => "WHERE",
self::T_WITH => "WITH");
}
return isset($this->_keywordsTable[$token])
? $this->_keywordsTable[$token]
: (is_string($token) ? $token : '');
}
} }
\ No newline at end of file
...@@ -237,9 +237,7 @@ class Parser ...@@ -237,9 +237,7 @@ class Parser
*/ */
public function match($token) public function match($token)
{ {
$key = (is_string($token)) ? 'value' : 'type'; if ( ! ($this->_lexer->lookahead['type'] === $token)) {
if ( ! ($this->_lexer->lookahead[$key] === $token)) {
$this->syntaxError($this->_lexer->getLiteral($token)); $this->syntaxError($this->_lexer->getLiteral($token));
} }
...@@ -334,7 +332,7 @@ class Parser ...@@ -334,7 +332,7 @@ class Parser
$message = "line 0, col {$tokenPos}: Error: "; $message = "line 0, col {$tokenPos}: Error: ";
if ($expected !== '') { if ($expected !== '') {
$message .= "Expected '{$expected}', got "; $message .= "Expected {$expected}, got ";
} else { } else {
$message .= 'Unexpected '; $message .= 'Unexpected ';
} }
...@@ -1601,9 +1599,7 @@ class Parser ...@@ -1601,9 +1599,7 @@ class Parser
return new AST\SimpleSelectExpression($this->StateFieldPathExpression()); return new AST\SimpleSelectExpression($this->StateFieldPathExpression());
} }
// TODO Fix this!!! $this->match(Lexer::T_IDENTIFIER);
echo 'SimpleSelectExpression: '; var_dump($this->_lexer->lookahead);
$this->match($this->_lexer->lookahead['value']);
return new AST\SimpleSelectExpression($this->_lexer->token['value']); return new AST\SimpleSelectExpression($this->_lexer->token['value']);
} }
...@@ -1696,7 +1692,7 @@ class Parser ...@@ -1696,7 +1692,7 @@ class Parser
{ {
$condPrimary = new AST\ConditionalPrimary; $condPrimary = new AST\ConditionalPrimary;
if ($this->_lexer->isNextToken('(')) { if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
// Peek beyond the matching closing paranthesis ')' // Peek beyond the matching closing paranthesis ')'
$numUnmatched = 1; $numUnmatched = 1;
$peek = $this->_lexer->peek(); $peek = $this->_lexer->peek();
...@@ -2023,6 +2019,7 @@ class Parser ...@@ -2023,6 +2019,7 @@ class Parser
if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
$this->match(Lexer::T_OPEN_PARENTHESIS); $this->match(Lexer::T_OPEN_PARENTHESIS);
$expr = $this->SimpleArithmeticExpression(); $expr = $this->SimpleArithmeticExpression();
$this->match(Lexer::T_CLOSE_PARENTHESIS); $this->match(Lexer::T_CLOSE_PARENTHESIS);
return $expr; return $expr;
......
...@@ -62,7 +62,7 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase ...@@ -62,7 +62,7 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase
{ {
$this->setExpectedException( $this->setExpectedException(
"Doctrine\Common\Annotations\AnnotationException", "Doctrine\Common\Annotations\AnnotationException",
"[Syntax Error] Expected '', got ')' at position 18 in class ". "[Syntax Error] Expected Doctrine\Common\Annotations\Lexer::T_IDENTIFIER, got ')' at position 18 in class ".
"Doctrine\Tests\Common\Annotations\DummyClassSyntaxError." "Doctrine\Tests\Common\Annotations\DummyClassSyntaxError."
); );
...@@ -76,7 +76,7 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase ...@@ -76,7 +76,7 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase
{ {
$this->setExpectedException( $this->setExpectedException(
"Doctrine\Common\Annotations\AnnotationException", "Doctrine\Common\Annotations\AnnotationException",
"[Syntax Error] Expected '', got ')' at position 18 in ". "[Syntax Error] Expected Doctrine\Common\Annotations\Lexer::T_IDENTIFIER, got ')' at position 18 in ".
"method Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError::foo()." "method Doctrine\Tests\Common\Annotations\DummyClassMethodSyntaxError::foo()."
); );
...@@ -91,7 +91,7 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase ...@@ -91,7 +91,7 @@ class AnnotationReaderTest extends \Doctrine\Tests\DoctrineTestCase
{ {
$this->setExpectedException( $this->setExpectedException(
"Doctrine\Common\Annotations\AnnotationException", "Doctrine\Common\Annotations\AnnotationException",
"[Syntax Error] Expected '', got ')' at position 18 in ". "[Syntax Error] Expected Doctrine\Common\Annotations\Lexer::T_IDENTIFIER, got ')' at position 18 in ".
"property Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError::\$foo." "property Doctrine\Tests\Common\Annotations\DummyClassPropertySyntaxError::\$foo."
); );
......
...@@ -94,7 +94,7 @@ DOCBLOCK; ...@@ -94,7 +94,7 @@ DOCBLOCK;
{ {
$this->setExpectedException( $this->setExpectedException(
'Doctrine\Common\Annotations\AnnotationException', 'Doctrine\Common\Annotations\AnnotationException',
"[Syntax Error] Expected 'PlainValue', got ''' at position 10." "[Syntax Error] Expected PlainValue, got ''' at position 10."
); );
$parser = $this->createTestParser(); $parser = $this->createTestParser();
...@@ -115,7 +115,7 @@ DOCBLOCK; ...@@ -115,7 +115,7 @@ DOCBLOCK;
{ {
$this->setExpectedException( $this->setExpectedException(
'Doctrine\Common\Annotations\AnnotationException', 'Doctrine\Common\Annotations\AnnotationException',
"[Syntax Error] Expected 'PlainValue', got ''' at position 10 ". "[Syntax Error] Expected PlainValue, got ''' at position 10 ".
"in class \Doctrine\Tests\Common\Annotations\Name" "in class \Doctrine\Tests\Common\Annotations\Name"
); );
......
...@@ -52,6 +52,10 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ...@@ -52,6 +52,10 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
parent::assertEquals($sqlToBeConfirmed, $query->getSql()); parent::assertEquals($sqlToBeConfirmed, $query->getSql());
$query->free(); $query->free();
} catch (\Exception $e) { } catch (\Exception $e) {
if ($debug) {
echo $e->getTraceAsString() . PHP_EOL;
}
$this->fail($e->getMessage()); $this->fail($e->getMessage());
} }
} }
......
...@@ -22,6 +22,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -22,6 +22,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
if ($debug) { if ($debug) {
echo $e->getTraceAsString() . PHP_EOL; echo $e->getTraceAsString() . PHP_EOL;
} }
$this->fail($e->getMessage()); $this->fail($e->getMessage());
} }
} }
......
...@@ -23,8 +23,10 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ...@@ -23,8 +23,10 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
parent::assertEquals($sqlToBeConfirmed, $query->getSql()); parent::assertEquals($sqlToBeConfirmed, $query->getSql());
$query->free(); $query->free();
} catch (Doctrine_Exception $e) { } catch (Doctrine_Exception $e) {
echo $e->getMessage(); if ($debug) {
echo $e->getTraceAsString(); echo $e->getTraceAsString() . PHP_EOL;
}
$this->fail($e->getMessage()); $this->fail($e->getMessage());
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment