vendor/doctrine/lib/Doctrine/ORM/Query/Lexer.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 /*
       
     3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
     4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
     5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
     6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
     7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
     8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
     9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    14  *
       
    15  * This software consists of voluntary contributions made by many individuals
       
    16  * and is licensed under the LGPL. For more information, see
       
    17  * <http://www.doctrine-project.org>.
       
    18  */
       
    19 
       
    20 namespace Doctrine\ORM\Query;
       
    21 
       
    22 /**
       
    23  * Scans a DQL query for tokens.
       
    24  *
       
    25  * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
       
    26  * @author Janne Vanhala <jpvanhal@cc.hut.fi>
       
    27  * @author Roman Borschel <roman@code-factory.org>
       
    28  * @since 2.0
       
    29  */
       
    30 class Lexer extends \Doctrine\Common\Lexer
       
    31 {
       
    32     // All tokens that are not valid identifiers must be < 100
       
    33     const T_NONE                = 1;
       
    34     const T_INTEGER             = 2;
       
    35     const T_STRING              = 3;
       
    36     const T_INPUT_PARAMETER     = 4;
       
    37     const T_FLOAT               = 5;
       
    38     const T_CLOSE_PARENTHESIS   = 6;
       
    39     const T_OPEN_PARENTHESIS    = 7;
       
    40     const T_COMMA               = 8;
       
    41     const T_DIVIDE              = 9;
       
    42     const T_DOT                 = 10;
       
    43     const T_EQUALS              = 11;
       
    44     const T_GREATER_THAN        = 12;
       
    45     const T_LOWER_THAN          = 13;
       
    46     const T_MINUS               = 14;
       
    47     const T_MULTIPLY            = 15;
       
    48     const T_NEGATE              = 16;
       
    49     const T_PLUS                = 17;
       
    50     const T_OPEN_CURLY_BRACE    = 18;
       
    51     const T_CLOSE_CURLY_BRACE   = 19;
       
    52     
       
    53     // All tokens that are also identifiers should be >= 100
       
    54     const T_IDENTIFIER          = 100;
       
    55     const T_ALL                 = 101;
       
    56     const T_AND                 = 102;
       
    57     const T_ANY                 = 103;
       
    58     const T_AS                  = 104;
       
    59     const T_ASC                 = 105;
       
    60     const T_AVG                 = 106;
       
    61     const T_BETWEEN             = 107;
       
    62     const T_BOTH                = 108;
       
    63     const T_BY                  = 109;
       
    64     const T_CASE                = 110;
       
    65     const T_COALESCE            = 111;
       
    66     const T_COUNT               = 112;
       
    67     const T_DELETE              = 113;
       
    68     const T_DESC                = 114;
       
    69     const T_DISTINCT            = 115;
       
    70     const T_EMPTY               = 116;
       
    71     const T_ESCAPE              = 117;
       
    72     const T_EXISTS              = 118;
       
    73     const T_FALSE               = 119;
       
    74     const T_FROM                = 120;
       
    75     const T_GROUP               = 121;
       
    76     const T_HAVING              = 122;
       
    77     const T_IN                  = 123;
       
    78     const T_INDEX               = 124;
       
    79     const T_INNER               = 125;
       
    80     const T_INSTANCE            = 126;
       
    81     const T_IS                  = 127;
       
    82     const T_JOIN                = 128;
       
    83     const T_LEADING             = 129;
       
    84     const T_LEFT                = 130;
       
    85     const T_LIKE                = 131;
       
    86     const T_MAX                 = 132;
       
    87     const T_MEMBER              = 133;
       
    88     const T_MIN                 = 134;
       
    89     const T_NOT                 = 135;
       
    90     const T_NULL                = 136;
       
    91     const T_NULLIF              = 137;
       
    92     const T_OF                  = 138;
       
    93     const T_OR                  = 139;
       
    94     const T_ORDER               = 140;
       
    95     const T_OUTER               = 141;
       
    96     const T_SELECT              = 142;
       
    97     const T_SET                 = 143;
       
    98     const T_SIZE                = 144;
       
    99     const T_SOME                = 145;
       
   100     const T_SUM                 = 146;
       
   101     const T_TRAILING            = 147;
       
   102     const T_TRUE                = 148;
       
   103     const T_UPDATE              = 149;
       
   104     const T_WHEN                = 150;
       
   105     const T_WHERE               = 151;
       
   106     const T_WITH                = 153;
       
   107     const T_PARTIAL             = 154;
       
   108     const T_MOD                 = 155;
       
   109    
       
   110     /**
       
   111      * Creates a new query scanner object.
       
   112      *
       
   113      * @param string $input a query string
       
   114      */
       
   115     public function __construct($input)
       
   116     {
       
   117         $this->setInput($input);
       
   118     }
       
   119 
       
   120     /**
       
   121      * @inheritdoc
       
   122      */
       
   123     protected function getCatchablePatterns()
       
   124     {
       
   125         return array(
       
   126             '[a-z_\\\][a-z0-9_\:\\\]*[a-z0-9_]{1}',
       
   127             '(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?',
       
   128             "'(?:[^']|'')*'",
       
   129             '\?[0-9]*|:[a-z]{1}[a-z0-9_]{0,}'
       
   130         );
       
   131     }
       
   132     
       
   133     /**
       
   134      * @inheritdoc
       
   135      */
       
   136     protected function getNonCatchablePatterns()
       
   137     {
       
   138         return array('\s+', '(.)');
       
   139     }
       
   140 
       
   141     /**
       
   142      * @inheritdoc
       
   143      */
       
   144     protected function getType(&$value)
       
   145     {
       
   146         $type = self::T_NONE;
       
   147 
       
   148         // Recognizing numeric values
       
   149         if (is_numeric($value)) {
       
   150             return (strpos($value, '.') !== false || stripos($value, 'e') !== false) 
       
   151                     ? self::T_FLOAT : self::T_INTEGER;
       
   152         }
       
   153 
       
   154         // Differentiate between quoted names, identifiers, input parameters and symbols
       
   155         if ($value[0] === "'") {
       
   156             $value = str_replace("''", "'", substr($value, 1, strlen($value) - 2));
       
   157             return self::T_STRING;
       
   158         } else if (ctype_alpha($value[0]) || $value[0] === '_') {
       
   159             $name = 'Doctrine\ORM\Query\Lexer::T_' . strtoupper($value);
       
   160 
       
   161             if (defined($name)) {
       
   162                 $type = constant($name);
       
   163                 
       
   164                 if ($type > 100) {
       
   165                     return $type;
       
   166                 }
       
   167             }
       
   168 
       
   169             return self::T_IDENTIFIER;
       
   170         } else if ($value[0] === '?' || $value[0] === ':') {
       
   171             return self::T_INPUT_PARAMETER;
       
   172         } else {
       
   173             switch ($value) {
       
   174                 case '.': return self::T_DOT;
       
   175                 case ',': return self::T_COMMA;
       
   176                 case '(': return self::T_OPEN_PARENTHESIS;
       
   177                 case ')': return self::T_CLOSE_PARENTHESIS;
       
   178                 case '=': return self::T_EQUALS;
       
   179                 case '>': return self::T_GREATER_THAN;
       
   180                 case '<': return self::T_LOWER_THAN;
       
   181                 case '+': return self::T_PLUS;
       
   182                 case '-': return self::T_MINUS;
       
   183                 case '*': return self::T_MULTIPLY;
       
   184                 case '/': return self::T_DIVIDE;
       
   185                 case '!': return self::T_NEGATE;
       
   186                 case '{': return self::T_OPEN_CURLY_BRACE;
       
   187                 case '}': return self::T_CLOSE_CURLY_BRACE;
       
   188                 default:
       
   189                     // Do nothing
       
   190                     break;
       
   191             }
       
   192         }
       
   193 
       
   194         return $type;
       
   195     }
       
   196 }