Chris@0: . Chris@0: */ Chris@0: Chris@0: namespace Doctrine\Common\Annotations; Chris@0: Chris@0: use Doctrine\Common\Lexer\AbstractLexer; Chris@0: Chris@0: /** Chris@0: * Simple lexer for docblock annotations. Chris@0: * Chris@0: * @author Benjamin Eberlei Chris@0: * @author Guilherme Blanco Chris@0: * @author Jonathan Wage Chris@0: * @author Roman Borschel Chris@0: * @author Johannes M. Schmitt Chris@0: */ Chris@0: final class DocLexer extends AbstractLexer Chris@0: { Chris@0: const T_NONE = 1; Chris@0: const T_INTEGER = 2; Chris@0: const T_STRING = 3; Chris@0: const T_FLOAT = 4; Chris@0: Chris@0: // All tokens that are also identifiers should be >= 100 Chris@0: const T_IDENTIFIER = 100; Chris@0: const T_AT = 101; Chris@0: const T_CLOSE_CURLY_BRACES = 102; Chris@0: const T_CLOSE_PARENTHESIS = 103; Chris@0: const T_COMMA = 104; Chris@0: const T_EQUALS = 105; Chris@0: const T_FALSE = 106; Chris@0: const T_NAMESPACE_SEPARATOR = 107; Chris@0: const T_OPEN_CURLY_BRACES = 108; Chris@0: const T_OPEN_PARENTHESIS = 109; Chris@0: const T_TRUE = 110; Chris@0: const T_NULL = 111; Chris@0: const T_COLON = 112; Chris@0: Chris@0: /** Chris@0: * @var array Chris@0: */ Chris@0: protected $noCase = array( Chris@0: '@' => self::T_AT, Chris@0: ',' => self::T_COMMA, Chris@0: '(' => self::T_OPEN_PARENTHESIS, Chris@0: ')' => self::T_CLOSE_PARENTHESIS, Chris@0: '{' => self::T_OPEN_CURLY_BRACES, Chris@0: '}' => self::T_CLOSE_CURLY_BRACES, Chris@0: '=' => self::T_EQUALS, Chris@0: ':' => self::T_COLON, Chris@0: '\\' => self::T_NAMESPACE_SEPARATOR Chris@0: ); Chris@0: Chris@0: /** Chris@0: * @var array Chris@0: */ Chris@0: protected $withCase = array( Chris@0: 'true' => self::T_TRUE, Chris@0: 'false' => self::T_FALSE, Chris@0: 'null' => self::T_NULL Chris@0: ); Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function getCatchablePatterns() Chris@0: { Chris@0: return array( Chris@0: '[a-z_\\\][a-z0-9_\:\\\]*[a-z_][a-z0-9_]*', Chris@0: '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?', Chris@0: '"(?:""|[^"])*+"', Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function getNonCatchablePatterns() Chris@0: { Chris@0: return array('\s+', '\*+', '(.)'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: protected function getType(&$value) Chris@0: { Chris@0: $type = self::T_NONE; Chris@0: Chris@0: if ($value[0] === '"') { Chris@0: $value = str_replace('""', '"', substr($value, 1, strlen($value) - 2)); Chris@0: Chris@0: return self::T_STRING; Chris@0: } Chris@0: Chris@0: if (isset($this->noCase[$value])) { Chris@0: return $this->noCase[$value]; Chris@0: } Chris@0: Chris@0: if ($value[0] === '_' || $value[0] === '\\' || ctype_alpha($value[0])) { Chris@0: return self::T_IDENTIFIER; Chris@0: } Chris@0: Chris@0: $lowerValue = strtolower($value); Chris@0: Chris@0: if (isset($this->withCase[$lowerValue])) { Chris@0: return $this->withCase[$lowerValue]; Chris@0: } Chris@0: Chris@0: // Checking numeric value Chris@0: if (is_numeric($value)) { Chris@0: return (strpos($value, '.') !== false || stripos($value, 'e') !== false) Chris@0: ? self::T_FLOAT : self::T_INTEGER; Chris@0: } Chris@0: Chris@0: return $type; Chris@0: } Chris@0: }