1
0
mirror of synced 2024-12-13 14:56:01 +03:00

Merged tokens into lexer.

This commit is contained in:
romanb 2009-03-14 10:30:47 +00:00
parent 22de495e19
commit 5b4564109e
3 changed files with 222 additions and 269 deletions

View File

@ -34,6 +34,63 @@ namespace Doctrine\ORM\Query;
*/ */
class Lexer class Lexer
{ {
const T_NONE = 1;
const T_IDENTIFIER = 2;
const T_INTEGER = 3;
const T_STRING = 4;
const T_INPUT_PARAMETER = 5;
const T_FLOAT = 6;
const T_ALL = 101;
const T_AND = 102;
const T_ANY = 103;
const T_AS = 104;
const T_ASC = 105;
const T_AVG = 106;
const T_BETWEEN = 107;
const T_BY = 108;
const T_COMMA = 109;
const T_COUNT = 110;
const T_DELETE = 111;
const T_DESC = 112;
const T_DISTINCT = 113;
const T_DOT = 114;
const T_ESCAPE = 115;
const T_EXISTS = 116;
const T_FROM = 117;
const T_GROUP = 118;
const T_HAVING = 119;
const T_IN = 120;
const T_INDEX = 121;
const T_INNER = 122;
const T_IS = 123;
const T_JOIN = 124;
const T_LEFT = 125;
const T_LIKE = 126;
const T_LIMIT = 127;
const T_MAX = 128;
const T_MIN = 129;
const T_MOD = 130;
const T_NOT = 131;
const T_NULL = 132;
const T_OFFSET = 133;
const T_ON = 134;
const T_OR = 135;
const T_ORDER = 136;
const T_OUTER = 137;
const T_SELECT = 138;
const T_SET = 139;
const T_SIZE = 140;
const T_SOME = 141;
const T_SUM = 142;
const T_UPDATE = 143;
const T_WHERE = 144;
const T_WITH = 145;
const T_TRUE = 146;
const T_FALSE = 147;
private $_keywordsTable;
/** /**
* Array of scanned tokens. * Array of scanned tokens.
* *
@ -134,7 +191,7 @@ class Lexer
*/ */
public function _checkLiteral($identifier) public function _checkLiteral($identifier)
{ {
$name = 'Doctrine\ORM\Query\Token::T_' . strtoupper($identifier); $name = 'Doctrine\ORM\Query\Lexer::T_' . strtoupper($identifier);
if (defined($name)) { if (defined($name)) {
$type = constant($name); $type = constant($name);
@ -144,7 +201,7 @@ class Lexer
} }
} }
return Token::T_IDENTIFIER; return self::T_IDENTIFIER;
} }
/** /**
@ -187,23 +244,23 @@ class Lexer
{ {
// $value is referenced because it can be changed if it is numeric. // $value is referenced because it can be changed if it is numeric.
// [TODO] Revisit the _isNumeric and _getNumeric methods to reduce overhead. // [TODO] Revisit the _isNumeric and _getNumeric methods to reduce overhead.
$type = Token::T_NONE; $type = self::T_NONE;
$newVal = $this->_getNumeric($value); $newVal = $this->_getNumeric($value);
if ($newVal !== false){ if ($newVal !== false){
$value = $newVal; $value = $newVal;
if (strpos($value, '.') !== false || stripos($value, 'e') !== false) { if (strpos($value, '.') !== false || stripos($value, 'e') !== false) {
$type = Token::T_FLOAT; $type = self::T_FLOAT;
} else { } else {
$type = Token::T_INTEGER; $type = self::T_INTEGER;
} }
} }
if ($value[0] === "'" && $value[strlen($value) - 1] === "'") { if ($value[0] === "'" && $value[strlen($value) - 1] === "'") {
$type = Token::T_STRING; $type = self::T_STRING;
} else if (ctype_alpha($value[0]) || $value[0] === '_') { } else if (ctype_alpha($value[0]) || $value[0] === '_') {
$type = $this->_checkLiteral($value); $type = $this->_checkLiteral($value);
} else if ($value[0] === '?' || $value[0] === ':') { } else if ($value[0] === '?' || $value[0] === ':') {
$type = Token::T_INPUT_PARAMETER; $type = self::T_INPUT_PARAMETER;
} }
return $type; return $type;
@ -289,4 +346,65 @@ class Lexer
{ {
$this->_position = $position; $this->_position = $position;
} }
private function _addKeyword($token, $value)
{
$this->_keywordsTable[$token] = $value;
}
public function getLiteral($token)
{
if ( ! $this->_keywordsTable) {
$this->_addKeyword(self::T_ALL, "ALL");
$this->_addKeyword(self::T_AND, "AND");
$this->_addKeyword(self::T_ANY, "ANY");
$this->_addKeyword(self::T_AS, "AS");
$this->_addKeyword(self::T_ASC, "ASC");
$this->_addKeyword(self::T_AVG, "AVG");
$this->_addKeyword(self::T_BETWEEN, "BETWEEN");
$this->_addKeyword(self::T_BY, "BY");
$this->_addKeyword(self::T_COMMA, ",");
$this->_addKeyword(self::T_COUNT, "COUNT");
$this->_addKeyword(self::T_DELETE, "DELETE");
$this->_addKeyword(self::T_DESC, "DESC");
$this->_addKeyword(self::T_DISTINCT, "DISTINCT");
$this->_addKeyword(self::T_DOT, ".");
$this->_addKeyword(self::T_ESCAPE, "ESPACE");
$this->_addKeyword(self::T_EXISTS, "EXISTS");
$this->_addKeyword(self::T_FALSE, "FALSE");
$this->_addKeyword(self::T_FROM, "FROM");
$this->_addKeyword(self::T_GROUP, "GROUP");
$this->_addKeyword(self::T_HAVING, "HAVING");
$this->_addKeyword(self::T_IN, "IN");
$this->_addKeyword(self::T_INDEX, "INDEX");
$this->_addKeyword(self::T_INNER, "INNER");
$this->_addKeyword(self::T_IS, "IS");
$this->_addKeyword(self::T_JOIN, "JOIN");
$this->_addKeyword(self::T_LEFT, "LEFT");
$this->_addKeyword(self::T_LIKE, "LIKE");
$this->_addKeyword(self::T_LIMIT, "LIMIT");
$this->_addKeyword(self::T_MAX, "MAX");
$this->_addKeyword(self::T_MIN, "MIN");
$this->_addKeyword(self::T_MOD, "MOD");
$this->_addKeyword(self::T_NOT, "NOT");
$this->_addKeyword(self::T_NULL, "NULL");
$this->_addKeyword(self::T_OFFSET, "OFFSET");
$this->_addKeyword(self::T_ON, "ON");
$this->_addKeyword(self::T_OR, "OR");
$this->_addKeyword(self::T_ORDER, "ORDER");
$this->_addKeyword(self::T_OUTER, "OUTER");
$this->_addKeyword(self::T_SELECT, "SELECT");
$this->_addKeyword(self::T_SET, "SET");
$this->_addKeyword(self::T_SIZE, "SIZE");
$this->_addKeyword(self::T_SOME, "SOME");
$this->_addKeyword(self::T_SUM, "SUM");
$this->_addKeyword(self::T_TRUE, "TRUE");
$this->_addKeyword(self::T_UPDATE, "UPDATE");
$this->_addKeyword(self::T_WHERE, "WHERE");
$this->_addKeyword(self::T_WITH, "WITH");
}
return isset($this->_keywordsTable[$token])
? $this->_keywordsTable[$token]
: (is_string($token) ? $token : '');
}
} }

View File

@ -69,13 +69,6 @@ class Parser
*/ */
protected $_parserResult; protected $_parserResult;
/**
* Keyword symbol table
*
* @var Token
*/
protected $_keywordTable;
/** /**
* The EntityManager. * The EntityManager.
* *
@ -93,7 +86,6 @@ class Parser
{ {
$this->_em = $query->getEntityManager(); $this->_em = $query->getEntityManager();
$this->_lexer = new Lexer($query->getDql()); $this->_lexer = new Lexer($query->getDql());
$this->_keywordTable = new Token();
$defaultQueryComponent = ParserRule::DEFAULT_QUERYCOMPONENT; $defaultQueryComponent = ParserRule::DEFAULT_QUERYCOMPONENT;
@ -136,7 +128,7 @@ class Parser
if ( ! $isMatch) { if ( ! $isMatch) {
// No definition for value checking. // No definition for value checking.
$this->syntaxError($this->_keywordTable->getLiteral($token)); $this->syntaxError($this->_lexer->getLiteral($token));
} }
$this->_lexer->next(); $this->_lexer->next();
@ -320,7 +312,7 @@ class Parser
{ {
$la = $this->_lexer->lookahead; $la = $this->_lexer->lookahead;
$next = $this->_lexer->glimpse(); $next = $this->_lexer->glimpse();
return ($la['value'] === '(' && $next['type'] === Token::T_SELECT); return ($la['value'] === '(' && $next['type'] === Lexer::T_SELECT);
} }
/* Parse methods */ /* Parse methods */
@ -334,15 +326,15 @@ class Parser
{ {
$this->_lexer->next(); $this->_lexer->next();
switch ($this->_lexer->lookahead['type']) { switch ($this->_lexer->lookahead['type']) {
case Token::T_SELECT: case Lexer::T_SELECT:
return $this->_SelectStatement(); return $this->_SelectStatement();
break; break;
case Token::T_UPDATE: case Lexer::T_UPDATE:
return $this->_UpdateStatement(); return $this->_UpdateStatement();
break; break;
case Token::T_DELETE: case Lexer::T_DELETE:
return $this->_DeleteStatement(); return $this->_DeleteStatement();
break; break;
@ -363,16 +355,16 @@ class Parser
$fromClause = $this->_FromClause(); $fromClause = $this->_FromClause();
$this->_processPendingPathExpressionsInSelect(); $this->_processPendingPathExpressionsInSelect();
$whereClause = $this->_lexer->isNextToken(Token::T_WHERE) ? $whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ?
$this->_WhereClause() : null; $this->_WhereClause() : null;
$groupByClause = $this->_lexer->isNextToken(Token::T_GROUP) ? $groupByClause = $this->_lexer->isNextToken(Lexer::T_GROUP) ?
$this->_GroupByClause() : null; $this->_GroupByClause() : null;
$havingClause = $this->_lexer->isNextToken(Token::T_HAVING) ? $havingClause = $this->_lexer->isNextToken(Lexer::T_HAVING) ?
$this->_HavingClause() : null; $this->_HavingClause() : null;
$orderByClause = $this->_lexer->isNextToken(Token::T_ORDER) ? $orderByClause = $this->_lexer->isNextToken(Lexer::T_ORDER) ?
$this->_OrderByClause() : null; $this->_OrderByClause() : null;
return new AST\SelectStatement( return new AST\SelectStatement(
@ -451,11 +443,11 @@ class Parser
private function _SelectClause() private function _SelectClause()
{ {
$isDistinct = false; $isDistinct = false;
$this->match(Token::T_SELECT); $this->match(Lexer::T_SELECT);
// Inspecting if we are in a DISTINCT query // Inspecting if we are in a DISTINCT query
if ($this->_lexer->isNextToken(Token::T_DISTINCT)) { if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) {
$this->match(Token::T_DISTINCT); $this->match(Lexer::T_DISTINCT);
$isDistinct = true; $isDistinct = true;
} }
@ -475,7 +467,7 @@ class Parser
*/ */
private function _FromClause() private function _FromClause()
{ {
$this->match(Token::T_FROM); $this->match(Lexer::T_FROM);
$identificationVariableDeclarations = array(); $identificationVariableDeclarations = array();
$identificationVariableDeclarations[] = $this->_IdentificationVariableDeclaration(); $identificationVariableDeclarations[] = $this->_IdentificationVariableDeclaration();
while ($this->_lexer->isNextToken(',')) { while ($this->_lexer->isNextToken(',')) {
@ -497,14 +489,14 @@ class Parser
$fieldIdentificationVariable = null; $fieldIdentificationVariable = null;
$peek = $this->_lexer->glimpse(); $peek = $this->_lexer->glimpse();
// First we recognize for an IdentificationVariable (DQL class alias) // First we recognize for an IdentificationVariable (DQL class alias)
if ($peek['value'] != '.' && $this->_lexer->lookahead['type'] === Token::T_IDENTIFIER) { if ($peek['value'] != '.' && $this->_lexer->lookahead['type'] === Lexer::T_IDENTIFIER) {
$expression = $this->_IdentificationVariable(); $expression = $this->_IdentificationVariable();
} else if (($isFunction = $this->_isFunction()) !== false || $this->_isSubselect()) { } else if (($isFunction = $this->_isFunction()) !== false || $this->_isSubselect()) {
$expression = $isFunction ? $this->_AggregateExpression() : $this->_Subselect(); $expression = $isFunction ? $this->_AggregateExpression() : $this->_Subselect();
if ($this->_lexer->isNextToken(Token::T_AS)) { if ($this->_lexer->isNextToken(Lexer::T_AS)) {
$this->match(Token::T_AS); $this->match(Lexer::T_AS);
$fieldIdentificationVariable = $this->_FieldAliasIdentificationVariable(); $fieldIdentificationVariable = $this->_FieldAliasIdentificationVariable();
} elseif ($this->_lexer->isNextToken(Token::T_IDENTIFIER)) { } elseif ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) {
$fieldIdentificationVariable = $this->_FieldAliasIdentificationVariable(); $fieldIdentificationVariable = $this->_FieldAliasIdentificationVariable();
} }
} else { } else {
@ -519,7 +511,7 @@ class Parser
*/ */
private function _IdentificationVariable() private function _IdentificationVariable()
{ {
$this->match(Token::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
return $this->_lexer->token['value']; return $this->_lexer->token['value'];
} }
@ -529,13 +521,13 @@ class Parser
private function _IdentificationVariableDeclaration() private function _IdentificationVariableDeclaration()
{ {
$rangeVariableDeclaration = $this->_RangeVariableDeclaration(); $rangeVariableDeclaration = $this->_RangeVariableDeclaration();
$indexBy = $this->_lexer->isNextToken(Token::T_INDEX) ? $indexBy = $this->_lexer->isNextToken(Lexer::T_INDEX) ?
$this->_IndexBy() : null; $this->_IndexBy() : null;
$joinVariableDeclarations = array(); $joinVariableDeclarations = array();
while ( while (
$this->_lexer->isNextToken(Token::T_LEFT) || $this->_lexer->isNextToken(Lexer::T_LEFT) ||
$this->_lexer->isNextToken(Token::T_INNER) || $this->_lexer->isNextToken(Lexer::T_INNER) ||
$this->_lexer->isNextToken(Token::T_JOIN) $this->_lexer->isNextToken(Lexer::T_JOIN)
) { ) {
$joinVariableDeclarations[] = $this->_JoinVariableDeclaration(); $joinVariableDeclarations[] = $this->_JoinVariableDeclaration();
} }
@ -552,8 +544,8 @@ class Parser
{ {
$abstractSchemaName = $this->_AbstractSchemaName(); $abstractSchemaName = $this->_AbstractSchemaName();
if ($this->_lexer->isNextToken(Token::T_AS)) { if ($this->_lexer->isNextToken(Lexer::T_AS)) {
$this->match(Token::T_AS); $this->match(Lexer::T_AS);
} }
$aliasIdentificationVariable = $this->_AliasIdentificationVariable(); $aliasIdentificationVariable = $this->_AliasIdentificationVariable();
$classMetadata = $this->_em->getClassMetadata($abstractSchemaName); $classMetadata = $this->_em->getClassMetadata($abstractSchemaName);
@ -578,7 +570,7 @@ class Parser
*/ */
private function _AbstractSchemaName() private function _AbstractSchemaName()
{ {
$this->match(Token::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
return $this->_lexer->token['value']; return $this->_lexer->token['value'];
} }
@ -587,7 +579,7 @@ class Parser
*/ */
private function _AliasIdentificationVariable() private function _AliasIdentificationVariable()
{ {
$this->match(Token::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
return $this->_lexer->token['value']; return $this->_lexer->token['value'];
} }
@ -596,11 +588,11 @@ class Parser
*/ */
private function _PathExpression() private function _PathExpression()
{ {
$this->match(Token::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$parts = array($this->_lexer->token['value']); $parts = array($this->_lexer->token['value']);
while ($this->_lexer->isNextToken('.')) { while ($this->_lexer->isNextToken('.')) {
$this->match('.'); $this->match('.');
$this->match(Token::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$parts[] = $this->_lexer->token['value']; $parts[] = $this->_lexer->token['value'];
} }
$pathExpression = new AST\PathExpression($parts); $pathExpression = new AST\PathExpression($parts);
@ -625,7 +617,7 @@ class Parser
private function _JoinVariableDeclaration() private function _JoinVariableDeclaration()
{ {
$join = $this->_Join(); $join = $this->_Join();
$indexBy = $this->_lexer->isNextToken(Token::T_INDEX) ? $indexBy = $this->_lexer->isNextToken(Lexer::T_INDEX) ?
$this->_IndexBy() : null; $this->_IndexBy() : null;
return new AST\JoinVariableDeclaration($join, $indexBy); return new AST\JoinVariableDeclaration($join, $indexBy);
} }
@ -638,24 +630,24 @@ class Parser
{ {
// Check Join type // Check Join type
$joinType = AST\Join::JOIN_TYPE_INNER; $joinType = AST\Join::JOIN_TYPE_INNER;
if ($this->_lexer->isNextToken(Token::T_LEFT)) { if ($this->_lexer->isNextToken(Lexer::T_LEFT)) {
$this->match(Token::T_LEFT); $this->match(Lexer::T_LEFT);
// Possible LEFT OUTER join // Possible LEFT OUTER join
if ($this->_lexer->isNextToken(Token::T_OUTER)) { if ($this->_lexer->isNextToken(Lexer::T_OUTER)) {
$this->match(Token::T_OUTER); $this->match(Lexer::T_OUTER);
$joinType = AST\Join::JOIN_TYPE_LEFTOUTER; $joinType = AST\Join::JOIN_TYPE_LEFTOUTER;
} else { } else {
$joinType = AST\Join::JOIN_TYPE_LEFT; $joinType = AST\Join::JOIN_TYPE_LEFT;
} }
} else if ($this->_lexer->isNextToken(Token::T_INNER)) { } else if ($this->_lexer->isNextToken(Lexer::T_INNER)) {
$this->match(Token::T_INNER); $this->match(Lexer::T_INNER);
} }
$this->match(Token::T_JOIN); $this->match(Lexer::T_JOIN);
$joinPathExpression = $this->_JoinPathExpression(); $joinPathExpression = $this->_JoinPathExpression();
if ($this->_lexer->isNextToken(Token::T_AS)) { if ($this->_lexer->isNextToken(Lexer::T_AS)) {
$this->match(Token::T_AS); $this->match(Lexer::T_AS);
} }
$aliasIdentificationVariable = $this->_AliasIdentificationVariable(); $aliasIdentificationVariable = $this->_AliasIdentificationVariable();
@ -686,14 +678,14 @@ class Parser
// Check Join where type // Check Join where type
if ( if (
$this->_lexer->isNextToken(Token::T_ON) || $this->_lexer->isNextToken(Lexer::T_ON) ||
$this->_lexer->isNextToken(Token::T_WITH) $this->_lexer->isNextToken(Lexer::T_WITH)
) { ) {
if ($this->_lexer->isNextToken(Token::T_ON)) { if ($this->_lexer->isNextToken(Lexer::T_ON)) {
$this->match(Token::T_ON); $this->match(Lexer::T_ON);
$join->setWhereType(AST\Join::JOIN_WHERE_ON); $join->setWhereType(AST\Join::JOIN_WHERE_ON);
} else { } else {
$this->match(Token::T_WITH); $this->match(Lexer::T_WITH);
} }
$join->setConditionalExpression($this->_ConditionalExpression()); $join->setConditionalExpression($this->_ConditionalExpression());
} }
@ -738,7 +730,7 @@ class Parser
{ {
$identificationVariable = $this->_IdentificationVariable(); $identificationVariable = $this->_IdentificationVariable();
$this->match('.'); $this->match('.');
$this->match(Token::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$assocField = $this->_lexer->token['value']; $assocField = $this->_lexer->token['value'];
return new AST\JoinPathExpression( return new AST\JoinPathExpression(
$identificationVariable, $assocField $identificationVariable, $assocField
@ -750,8 +742,8 @@ class Parser
*/ */
private function _IndexBy() private function _IndexBy()
{ {
$this->match(Token::T_INDEX); $this->match(Lexer::T_INDEX);
$this->match(Token::T_BY); $this->match(Lexer::T_BY);
$pathExp = $this->_SimpleStateFieldPathExpression(); $pathExp = $this->_SimpleStateFieldPathExpression();
// Add the INDEX BY info to the query component // Add the INDEX BY info to the query component
$qComp = $this->_parserResult->getQueryComponent($pathExp->getIdentificationVariable()); $qComp = $this->_parserResult->getQueryComponent($pathExp->getIdentificationVariable());
@ -767,7 +759,7 @@ class Parser
{ {
$identificationVariable = $this->_IdentificationVariable(); $identificationVariable = $this->_IdentificationVariable();
$this->match('.'); $this->match('.');
$this->match(Token::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$simpleStateField = $this->_lexer->token['value']; $simpleStateField = $this->_lexer->token['value'];
return new AST\SimpleStateFieldPathExpression($identificationVariable, $simpleStateField); return new AST\SimpleStateFieldPathExpression($identificationVariable, $simpleStateField);
} }
@ -830,19 +822,19 @@ class Parser
{ {
$isDistinct = false; $isDistinct = false;
$functionName = ''; $functionName = '';
if ($this->_lexer->isNextToken(Token::T_COUNT)) { if ($this->_lexer->isNextToken(Lexer::T_COUNT)) {
$this->match(Token::T_COUNT); $this->match(Lexer::T_COUNT);
$functionName = $this->_lexer->token['value']; $functionName = $this->_lexer->token['value'];
$this->match('('); $this->match('(');
if ($this->_lexer->isNextToken(Token::T_DISTINCT)) { if ($this->_lexer->isNextToken(Lexer::T_DISTINCT)) {
$this->match(Token::T_DISTINCT); $this->match(Lexer::T_DISTINCT);
$isDistinct = true; $isDistinct = true;
} }
// For now we only support a PathExpression here... // For now we only support a PathExpression here...
$pathExp = $this->_PathExpression(); $pathExp = $this->_PathExpression();
$this->match(')'); $this->match(')');
} else if ($this->_lexer->isNextToken(Token::T_AVG)) { } else if ($this->_lexer->isNextToken(Lexer::T_AVG)) {
$this->match(Token::T_AVG); $this->match(Lexer::T_AVG);
$functionName = $this->_lexer->token['value']; $functionName = $this->_lexer->token['value'];
$this->match('('); $this->match('(');
//... //...
@ -858,8 +850,8 @@ class Parser
*/ */
private function _GroupByClause() private function _GroupByClause()
{ {
$this->match(Token::T_GROUP); $this->match(Lexer::T_GROUP);
$this->match(Token::T_BY); $this->match(Lexer::T_BY);
$groupByItems = array(); $groupByItems = array();
$groupByItems[] = $this->_PathExpression(); $groupByItems[] = $this->_PathExpression();
while ($this->_lexer->isNextToken(',')) { while ($this->_lexer->isNextToken(',')) {
@ -874,7 +866,7 @@ class Parser
*/ */
private function _WhereClause() private function _WhereClause()
{ {
$this->match(Token::T_WHERE); $this->match(Lexer::T_WHERE);
return new AST\WhereClause($this->_ConditionalExpression()); return new AST\WhereClause($this->_ConditionalExpression());
} }
@ -885,8 +877,8 @@ class Parser
{ {
$conditionalTerms = array(); $conditionalTerms = array();
$conditionalTerms[] = $this->_ConditionalTerm(); $conditionalTerms[] = $this->_ConditionalTerm();
while ($this->_lexer->isNextToken(Token::T_OR)) { while ($this->_lexer->isNextToken(Lexer::T_OR)) {
$this->match(Token::T_OR); $this->match(Lexer::T_OR);
$conditionalTerms[] = $this->_ConditionalTerm(); $conditionalTerms[] = $this->_ConditionalTerm();
} }
return new AST\ConditionalExpression($conditionalTerms); return new AST\ConditionalExpression($conditionalTerms);
@ -899,8 +891,8 @@ class Parser
{ {
$conditionalFactors = array(); $conditionalFactors = array();
$conditionalFactors[] = $this->_ConditionalFactor(); $conditionalFactors[] = $this->_ConditionalFactor();
while ($this->_lexer->isNextToken(Token::T_AND)) { while ($this->_lexer->isNextToken(Lexer::T_AND)) {
$this->match(Token::T_AND); $this->match(Lexer::T_AND);
$conditionalFactors[] = $this->_ConditionalFactor(); $conditionalFactors[] = $this->_ConditionalFactor();
} }
return new AST\ConditionalTerm($conditionalFactors); return new AST\ConditionalTerm($conditionalFactors);
@ -912,8 +904,8 @@ class Parser
private function _ConditionalFactor() private function _ConditionalFactor()
{ {
$not = false; $not = false;
if ($this->_lexer->isNextToken(Token::T_NOT)) { if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
$this->match(Token::T_NOT); $this->match(Lexer::T_NOT);
$not = true; $not = true;
} }
return new AST\ConditionalFactor($this->_ConditionalPrimary(), $not); return new AST\ConditionalFactor($this->_ConditionalPrimary(), $not);
@ -963,17 +955,17 @@ class Parser
*/ */
private function _SimpleConditionalExpression() private function _SimpleConditionalExpression()
{ {
if ($this->_lexer->isNextToken(Token::T_NOT)) { if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
$token = $this->_lexer->glimpse(); $token = $this->_lexer->glimpse();
} else { } else {
$token = $this->_lexer->lookahead; $token = $this->_lexer->lookahead;
} }
if ($token['type'] === Token::T_EXISTS) { if ($token['type'] === Lexer::T_EXISTS) {
return $this->_ExistsExpression(); return $this->_ExistsExpression();
} }
$stateFieldPathExpr = false; $stateFieldPathExpr = false;
if ($token['type'] === Token::T_IDENTIFIER) { if ($token['type'] === Lexer::T_IDENTIFIER) {
// Peek beyond the PathExpression // Peek beyond the PathExpression
$stateFieldPathExpr = true; $stateFieldPathExpr = true;
$peek = $this->_lexer->peek(); $peek = $this->_lexer->peek();
@ -987,15 +979,15 @@ class Parser
if ($stateFieldPathExpr) { if ($stateFieldPathExpr) {
switch ($token['type']) { switch ($token['type']) {
case Token::T_BETWEEN: case Lexer::T_BETWEEN:
return $this->_BetweenExpression(); return $this->_BetweenExpression();
case Token::T_LIKE: case Lexer::T_LIKE:
return $this->_LikeExpression(); return $this->_LikeExpression();
case Token::T_IN: case Lexer::T_IN:
return $this->_InExpression(); return $this->_InExpression();
case Token::T_IS: case Lexer::T_IS:
return $this->_NullComparisonExpression(); return $this->_NullComparisonExpression();
case Token::T_NONE: case Lexer::T_NONE:
return $this->_ComparisonExpression(); return $this->_ComparisonExpression();
default: default:
$this->syntaxError(); $this->syntaxError();
@ -1004,10 +996,10 @@ class Parser
return $this->_ComparisonExpression(); return $this->_ComparisonExpression();
} else { } else {
switch ($token['type']) { switch ($token['type']) {
case Token::T_INTEGER: case Lexer::T_INTEGER:
// IF it turns out its a ComparisonExpression, then it MUST be ArithmeticExpression // IF it turns out its a ComparisonExpression, then it MUST be ArithmeticExpression
break; break;
case Token::T_STRING: case Lexer::T_STRING:
// IF it turns out its a ComparisonExpression, then it MUST be StringExpression // IF it turns out its a ComparisonExpression, then it MUST be StringExpression
break; break;
default: default:
@ -1024,9 +1016,9 @@ class Parser
{ {
$leftExpr = $this->_ArithmeticExpression(); $leftExpr = $this->_ArithmeticExpression();
$operator = $this->_ComparisonOperator(); $operator = $this->_ComparisonOperator();
if ($this->_lexer->lookahead['type'] === Token::T_ALL || if ($this->_lexer->lookahead['type'] === Lexer::T_ALL ||
$this->_lexer->lookahead['type'] === Token::T_ANY || $this->_lexer->lookahead['type'] === Lexer::T_ANY ||
$this->_lexer->lookahead['type'] === Token::T_SOME) { $this->_lexer->lookahead['type'] === Lexer::T_SOME) {
$rightExpr = $this->_QuantifiedExpression(); $rightExpr = $this->_QuantifiedExpression();
} else { } else {
$rightExpr = $this->_ArithmeticExpression(); $rightExpr = $this->_ArithmeticExpression();
@ -1042,7 +1034,7 @@ class Parser
$expr = new AST\ArithmeticExpression; $expr = new AST\ArithmeticExpression;
if ($this->_lexer->lookahead['value'] === '(') { if ($this->_lexer->lookahead['value'] === '(') {
$peek = $this->_lexer->glimpse(); $peek = $this->_lexer->glimpse();
if ($peek['type'] === Token::T_SELECT) { if ($peek['type'] === Lexer::T_SELECT) {
$expr->setSubselect($this->_Subselect()); $expr->setSubselect($this->_Subselect());
return $expr; return $expr;
} }
@ -1117,7 +1109,7 @@ class Parser
return $expr; return $expr;
} }
switch ($this->_lexer->lookahead['type']) { switch ($this->_lexer->lookahead['type']) {
case Token::T_IDENTIFIER: case Lexer::T_IDENTIFIER:
$peek = $this->_lexer->glimpse(); $peek = $this->_lexer->glimpse();
if ($peek['value'] == '(') { if ($peek['value'] == '(') {
if ($this->_isAggregateFunction($peek['type'])) { if ($this->_isAggregateFunction($peek['type'])) {
@ -1126,12 +1118,12 @@ class Parser
return $this->_FunctionsReturningStrings(); return $this->_FunctionsReturningStrings();
} }
return $this->_StateFieldPathExpression(); return $this->_StateFieldPathExpression();
case Token::T_INPUT_PARAMETER: case Lexer::T_INPUT_PARAMETER:
$this->match($this->_lexer->lookahead['value']); $this->match($this->_lexer->lookahead['value']);
return new AST\InputParameter($this->_lexer->token['value']); return new AST\InputParameter($this->_lexer->token['value']);
case Token::T_STRING: case Lexer::T_STRING:
case Token::T_INTEGER: case Lexer::T_INTEGER:
case Token::T_FLOAT: case Lexer::T_FLOAT:
$this->match($this->_lexer->lookahead['value']); $this->match($this->_lexer->lookahead['value']);
return $this->_lexer->token['value']; return $this->_lexer->token['value'];
default: default:
@ -1177,11 +1169,11 @@ class Parser
private function _isAggregateFunction($tokenType) private function _isAggregateFunction($tokenType)
{ {
switch ($tokenType) { switch ($tokenType) {
case Token::T_AVG: case Lexer::T_AVG:
case Token::T_MIN: case Lexer::T_MIN:
case Token::T_MAX: case Lexer::T_MAX:
case Token::T_SUM: case Lexer::T_SUM:
case Token::T_COUNT: case Lexer::T_COUNT:
return true; return true;
default: default:
return false; return false;
@ -1233,18 +1225,18 @@ class Parser
{ {
$stringExpr = $this->_StringExpression(); $stringExpr = $this->_StringExpression();
$isNot = false; $isNot = false;
if ($this->_lexer->lookahead['type'] === Token::T_NOT) { if ($this->_lexer->lookahead['type'] === Lexer::T_NOT) {
$this->match(Token::T_NOT); $this->match(Lexer::T_NOT);
$isNot = true; $isNot = true;
} }
$this->match(Token::T_LIKE); $this->match(Lexer::T_LIKE);
$this->match(Token::T_STRING); $this->match(Lexer::T_STRING);
$stringPattern = $this->_lexer->token['value']; $stringPattern = $this->_lexer->token['value'];
$escapeChar = null; $escapeChar = null;
if ($this->_lexer->lookahead['type'] === Token::T_ESCAPE) { if ($this->_lexer->lookahead['type'] === Lexer::T_ESCAPE) {
$this->match(Token::T_ESCAPE); $this->match(Lexer::T_ESCAPE);
var_dump($this->_lexer->lookahead); var_dump($this->_lexer->lookahead);
//$this->match(Token::T_) //$this->match(Lexer::T_)
//$escapeChar = //$escapeChar =
} }
return new AST\LikeExpression($stringExpr, $stringPattern, $isNot, $escapeChar); return new AST\LikeExpression($stringExpr, $stringPattern, $isNot, $escapeChar);
@ -1257,7 +1249,7 @@ class Parser
{ {
if ($this->_lexer->lookahead['value'] === '(') { if ($this->_lexer->lookahead['value'] === '(') {
$peek = $this->_lexer->glimpse(); $peek = $this->_lexer->glimpse();
if ($peek['type'] === Token::T_SELECT) { if ($peek['type'] === Lexer::T_SELECT) {
return $this->_Subselect(); return $this->_Subselect();
} }
} }
@ -1269,7 +1261,7 @@ class Parser
*/ */
private function _StringPrimary() private function _StringPrimary()
{ {
if ($this->_lexer->lookahead['type'] === Token::T_IDENTIFIER) { if ($this->_lexer->lookahead['type'] === Lexer::T_IDENTIFIER) {
$peek = $this->_lexer->glimpse(); $peek = $this->_lexer->glimpse();
if ($peek['value'] == '.') { if ($peek['value'] == '.') {
return $this->_StateFieldPathExpression(); return $this->_StateFieldPathExpression();
@ -1278,9 +1270,9 @@ class Parser
} else { } else {
$this->syntaxError("'.' or '('"); $this->syntaxError("'.' or '('");
} }
} else if ($this->_lexer->lookahead['type'] === Token::T_STRING) { } else if ($this->_lexer->lookahead['type'] === Lexer::T_STRING) {
//TODO... //TODO...
} else if ($this->_lexer->lookahead['type'] === Token::T_INPUT_PARAMETER) { } else if ($this->_lexer->lookahead['type'] === Lexer::T_INPUT_PARAMETER) {
//TODO... //TODO...
} else { } else {
$this->syntaxError('StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression'); $this->syntaxError('StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression');

View File

@ -1,157 +0,0 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
namespace Doctrine\ORM\Query;
/**
* Container for token type constants of Doctrine Query Language.
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Janne Vanhala <jpvanhal@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @since 2.0
* @version $Revision$
*/
final class Token
{
const T_NONE = 1;
const T_IDENTIFIER = 2;
const T_INTEGER = 3;
const T_STRING = 4;
const T_INPUT_PARAMETER = 5;
const T_FLOAT = 6;
const T_ALL = 101;
const T_AND = 102;
const T_ANY = 103;
const T_AS = 104;
const T_ASC = 105;
const T_AVG = 106;
const T_BETWEEN = 107;
const T_BY = 108;
const T_COMMA = 109;
const T_COUNT = 110;
const T_DELETE = 111;
const T_DESC = 112;
const T_DISTINCT = 113;
const T_DOT = 114;
const T_ESCAPE = 115;
const T_EXISTS = 116;
const T_FROM = 117;
const T_GROUP = 118;
const T_HAVING = 119;
const T_IN = 120;
const T_INDEX = 121;
const T_INNER = 122;
const T_IS = 123;
const T_JOIN = 124;
const T_LEFT = 125;
const T_LIKE = 126;
const T_LIMIT = 127;
const T_MAX = 128;
const T_MIN = 129;
const T_MOD = 130;
const T_NOT = 131;
const T_NULL = 132;
const T_OFFSET = 133;
const T_ON = 134;
const T_OR = 135;
const T_ORDER = 136;
const T_OUTER = 137;
const T_SELECT = 138;
const T_SET = 139;
const T_SIZE = 140;
const T_SOME = 141;
const T_SUM = 142;
const T_UPDATE = 143;
const T_WHERE = 144;
const T_WITH = 145;
const T_TRUE = 146;
const T_FALSE = 147;
protected $_keywordsTable;
public function __construct()
{
}
protected function addKeyword($token, $value)
{
$this->_keywordsTable[$token] = $value;
}
public function getLiteral($token)
{
if ( ! $this->_keywordsTable) {
$this->addKeyword(self::T_ALL, "ALL");
$this->addKeyword(self::T_AND, "AND");
$this->addKeyword(self::T_ANY, "ANY");
$this->addKeyword(self::T_AS, "AS");
$this->addKeyword(self::T_ASC, "ASC");
$this->addKeyword(self::T_AVG, "AVG");
$this->addKeyword(self::T_BETWEEN, "BETWEEN");
$this->addKeyword(self::T_BY, "BY");
$this->addKeyword(self::T_COMMA, ",");
$this->addKeyword(self::T_COUNT, "COUNT");
$this->addKeyword(self::T_DELETE, "DELETE");
$this->addKeyword(self::T_DESC, "DESC");
$this->addKeyword(self::T_DISTINCT, "DISTINCT");
$this->addKeyword(self::T_DOT, ".");
$this->addKeyword(self::T_ESCAPE, "ESPACE");
$this->addKeyword(self::T_EXISTS, "EXISTS");
$this->addKeyword(self::T_FALSE, "FALSE");
$this->addKeyword(self::T_FROM, "FROM");
$this->addKeyword(self::T_GROUP, "GROUP");
$this->addKeyword(self::T_HAVING, "HAVING");
$this->addKeyword(self::T_IN, "IN");
$this->addKeyword(self::T_INDEX, "INDEX");
$this->addKeyword(self::T_INNER, "INNER");
$this->addKeyword(self::T_IS, "IS");
$this->addKeyword(self::T_JOIN, "JOIN");
$this->addKeyword(self::T_LEFT, "LEFT");
$this->addKeyword(self::T_LIKE, "LIKE");
$this->addKeyword(self::T_LIMIT, "LIMIT");
$this->addKeyword(self::T_MAX, "MAX");
$this->addKeyword(self::T_MIN, "MIN");
$this->addKeyword(self::T_MOD, "MOD");
$this->addKeyword(self::T_NOT, "NOT");
$this->addKeyword(self::T_NULL, "NULL");
$this->addKeyword(self::T_OFFSET, "OFFSET");
$this->addKeyword(self::T_ON, "ON");
$this->addKeyword(self::T_OR, "OR");
$this->addKeyword(self::T_ORDER, "ORDER");
$this->addKeyword(self::T_OUTER, "OUTER");
$this->addKeyword(self::T_SELECT, "SELECT");
$this->addKeyword(self::T_SET, "SET");
$this->addKeyword(self::T_SIZE, "SIZE");
$this->addKeyword(self::T_SOME, "SOME");
$this->addKeyword(self::T_SUM, "SUM");
$this->addKeyword(self::T_TRUE, "TRUE");
$this->addKeyword(self::T_UPDATE, "UPDATE");
$this->addKeyword(self::T_WHERE, "WHERE");
$this->addKeyword(self::T_WITH, "WITH");
}
return isset($this->_keywordsTable[$token])
? $this->_keywordsTable[$token]
: (is_string($token) ? $token : '');
}
}