/** * Attempts to match the given token with the current lookahead token. * If they match, updates the lookahead token; otherwise raises a syntax error. * * @param int Token type. * @return bool True if tokens match; false otherwise. */ public function match($token) { if (!($this->lexer->lookahead['type'] === $token)) { $this->syntaxError($this->lexer->getLiteral($token)); } $this->lexer->moveNext(); }
/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName | AliasedName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * AliasedName ::= Alias ":" SimpleName * NameSpacePart ::= identifier * SimpleName ::= identifier * Alias ::= identifier * * @return mixed False if it is not a valid annotation. */ public function Annotation() { $values = array(); $nameParts = array(); $this->match(Lexer::T_AT); if ($this->isNestedAnnotation === false) { if ($this->lexer->lookahead['type'] !== Lexer::T_IDENTIFIER) { return false; } $this->lexer->moveNext(); } else { $this->match(Lexer::T_IDENTIFIER); } $nameParts[] = $this->lexer->token['value']; while ($this->lexer->isNextToken(Lexer::T_NAMESPACE_SEPARATOR)) { $this->match(Lexer::T_NAMESPACE_SEPARATOR); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->lexer->token['value']; } // Effectively pick the name of the class (append default NS if none, grab from NS alias, etc) if (strpos($nameParts[0], ':')) { list($alias, $nameParts[0]) = explode(':', $nameParts[0]); // If the namespace alias doesnt exist, skip until next annotation if (!isset($this->namespaceAliases[$alias])) { $this->lexer->skipUntil(Lexer::T_AT); return false; } $name = $this->namespaceAliases[$alias] . implode('\\', $nameParts); } else { if (count($nameParts) == 1) { $name = $this->defaultAnnotationNamespace . $nameParts[0]; } else { $name = implode('\\', $nameParts); } } // Does the annotation class exist? if (!class_exists($name, $this->autoloadAnnotations)) { $this->lexer->skipUntil(Lexer::T_AT); return false; } // Next will be nested $this->isNestedAnnotation = true; if ($this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { $this->match(Lexer::T_OPEN_PARENTHESIS); if (!$this->lexer->isNextToken(Lexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(Lexer::T_CLOSE_PARENTHESIS); } if ($this->annotationCreationFunction !== null) { $func = $this->annotationCreationFunction; $annot = $func($name, $values); } return isset($annot) ? $annot : $this->newAnnotation($name, $values); }