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 MIT license. For more information, see 17 * <http://www.doctrine-project.org>. 18 */ 19 20namespace Doctrine\Common\Annotations; 21 22use Doctrine\Common\Lexer\AbstractLexer; 23 24/** 25 * Simple lexer for docblock annotations. 26 * 27 * @author Benjamin Eberlei <kontakt@beberlei.de> 28 * @author Guilherme Blanco <guilhermeblanco@hotmail.com> 29 * @author Jonathan Wage <jonwage@gmail.com> 30 * @author Roman Borschel <roman@code-factory.org> 31 * @author Johannes M. Schmitt <schmittjoh@gmail.com> 32 */ 33final class DocLexer extends AbstractLexer 34{ 35 const T_NONE = 1; 36 const T_INTEGER = 2; 37 const T_STRING = 3; 38 const T_FLOAT = 4; 39 40 // All tokens that are also identifiers should be >= 100 41 const T_IDENTIFIER = 100; 42 const T_AT = 101; 43 const T_CLOSE_CURLY_BRACES = 102; 44 const T_CLOSE_PARENTHESIS = 103; 45 const T_COMMA = 104; 46 const T_EQUALS = 105; 47 const T_FALSE = 106; 48 const T_NAMESPACE_SEPARATOR = 107; 49 const T_OPEN_CURLY_BRACES = 108; 50 const T_OPEN_PARENTHESIS = 109; 51 const T_TRUE = 110; 52 const T_NULL = 111; 53 const T_COLON = 112; 54 const T_MINUS = 113; 55 56 /** 57 * @var array 58 */ 59 protected $noCase = array( 60 '@' => self::T_AT, 61 ',' => self::T_COMMA, 62 '(' => self::T_OPEN_PARENTHESIS, 63 ')' => self::T_CLOSE_PARENTHESIS, 64 '{' => self::T_OPEN_CURLY_BRACES, 65 '}' => self::T_CLOSE_CURLY_BRACES, 66 '=' => self::T_EQUALS, 67 ':' => self::T_COLON, 68 '-' => self::T_MINUS, 69 '\\' => self::T_NAMESPACE_SEPARATOR 70 ); 71 72 /** 73 * @var array 74 */ 75 protected $withCase = array( 76 'true' => self::T_TRUE, 77 'false' => self::T_FALSE, 78 'null' => self::T_NULL 79 ); 80 81 /** 82 * Whether the next token starts immediately, or if there were 83 * non-captured symbols before that 84 */ 85 public function nextTokenIsAdjacent() : bool 86 { 87 return $this->token === null 88 || ($this->lookahead !== null 89 && ($this->lookahead['position'] - $this->token['position']) === strlen($this->token['value'])); 90 } 91 92 /** 93 * {@inheritdoc} 94 */ 95 protected function getCatchablePatterns() 96 { 97 return array( 98 '[a-z_\\\][a-z0-9_\:\\\]*[a-z_][a-z0-9_]*', 99 '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?', 100 '"(?:""|[^"])*+"', 101 ); 102 } 103 104 /** 105 * {@inheritdoc} 106 */ 107 protected function getNonCatchablePatterns() 108 { 109 return array('\s+', '\*+', '(.)'); 110 } 111 112 /** 113 * {@inheritdoc} 114 */ 115 protected function getType(&$value) 116 { 117 $type = self::T_NONE; 118 119 if ($value[0] === '"') { 120 $value = str_replace('""', '"', substr($value, 1, strlen($value) - 2)); 121 122 return self::T_STRING; 123 } 124 125 if (isset($this->noCase[$value])) { 126 return $this->noCase[$value]; 127 } 128 129 if ($value[0] === '_' || $value[0] === '\\' || ctype_alpha($value[0])) { 130 return self::T_IDENTIFIER; 131 } 132 133 $lowerValue = strtolower($value); 134 135 if (isset($this->withCase[$lowerValue])) { 136 return $this->withCase[$lowerValue]; 137 } 138 139 // Checking numeric value 140 if (is_numeric($value)) { 141 return (strpos($value, '.') !== false || stripos($value, 'e') !== false) 142 ? self::T_FLOAT : self::T_INTEGER; 143 } 144 145 return $type; 146 } 147} 148