First commit
This commit is contained in:
commit
d5bb2f19fa
117 changed files with 68604 additions and 0 deletions
53
vendor/yosymfony/parser-utils/src/AbstractParser.php
vendored
Normal file
53
vendor/yosymfony/parser-utils/src/AbstractParser.php
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Yosymfony\ParserUtils package.
|
||||
*
|
||||
* (c) YoSymfony <http://github.com/yosymfony>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Yosymfony\ParserUtils;
|
||||
|
||||
abstract class AbstractParser
|
||||
{
|
||||
protected $lexer;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param LexerInterface $lexer The lexer
|
||||
*/
|
||||
public function __construct(LexerInterface $lexer)
|
||||
{
|
||||
$this->lexer = $lexer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given input
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function parse(string $input)
|
||||
{
|
||||
$ts = $this->lexer->tokenize($input);
|
||||
$parseResult = $this->parseImplementation($ts);
|
||||
|
||||
if ($ts->hasPendingTokens()) {
|
||||
throw new SyntaxErrorException('There are tokens not processed.');
|
||||
}
|
||||
|
||||
return $parseResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the real parsing
|
||||
*
|
||||
* @param TokenStream $stream The token stream returned by the lexer
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function parseImplementation(TokenStream $stream);
|
||||
}
|
175
vendor/yosymfony/parser-utils/src/BasicLexer.php
vendored
Normal file
175
vendor/yosymfony/parser-utils/src/BasicLexer.php
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Yosymfony\ParserUtils package.
|
||||
*
|
||||
* (c) YoSymfony <http://github.com/yosymfony>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Yosymfony\ParserUtils;
|
||||
|
||||
class BasicLexer implements LexerInterface
|
||||
{
|
||||
protected $newlineTokenName = 'T_NEWLINE';
|
||||
protected $eosTokenName = 'T_EOS';
|
||||
protected $activateNewlineToken = false;
|
||||
protected $activateEOSToken = false;
|
||||
protected $terminals = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $terminal List of terminals
|
||||
* e.g:
|
||||
* [
|
||||
* "/^([)/" => "T_BRAKET_BEGIN"
|
||||
* ]
|
||||
*/
|
||||
public function __construct(array $terminals)
|
||||
{
|
||||
$this->terminals = $terminals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an special "T_NEWLINE" for each line of the input
|
||||
*
|
||||
* @return BasicLexer The BasicLexer itself
|
||||
*/
|
||||
public function generateNewlineTokens() : BasicLexer
|
||||
{
|
||||
$this->activateNewlineToken = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an special "T_EOS" at the end of the input string
|
||||
*
|
||||
* @return BasicLexer The BasicLexer itself
|
||||
*/
|
||||
public function generateEosToken() : BasicLexer
|
||||
{
|
||||
$this->activateEOSToken = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the newline token
|
||||
*
|
||||
* @param string $name The name of the token
|
||||
*
|
||||
* @return BasicLexer The BasicLexer itself
|
||||
*
|
||||
* @throws InvalidArgumentException If the name is empty
|
||||
*/
|
||||
public function setNewlineTokenName(string $name) : BasicLexer
|
||||
{
|
||||
if (strlen($name) == 0) {
|
||||
throw new \InvalidArgumentException('The name of the newline token must be not empty.');
|
||||
}
|
||||
|
||||
$this->newlineTokenName = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the end-of-string token
|
||||
*
|
||||
* @param string $name The name of the token
|
||||
*
|
||||
* @return BasicLexer The BasicLexer itself
|
||||
*
|
||||
* @throws InvalidArgumentException If the name is empty
|
||||
*/
|
||||
public function setEosTokenName(string $name) : BasicLexer
|
||||
{
|
||||
if (strlen($name) == 0) {
|
||||
throw new \InvalidArgumentException('The name of the EOS token must be not empty.');
|
||||
}
|
||||
|
||||
$this->eosTokenName = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function tokenize(string $input) : TokenStream
|
||||
{
|
||||
$counter = 0;
|
||||
$tokens = [];
|
||||
$lines = explode("\n", $input);
|
||||
$totalLines = count($lines);
|
||||
|
||||
foreach ($lines as $number => $line) {
|
||||
$offset = 0;
|
||||
$lineNumber = $number + 1;
|
||||
|
||||
while ($offset < strlen($line)) {
|
||||
list($name, $matches) = $this->match($line, $lineNumber, $offset);
|
||||
|
||||
if (isset($matches[1])) {
|
||||
$token = new Token($matches[1], $name, $lineNumber);
|
||||
$this->processToken($token, $matches);
|
||||
$tokens[] = $token;
|
||||
}
|
||||
|
||||
$offset += strlen($matches[0]);
|
||||
}
|
||||
|
||||
if ($this->activateNewlineToken && ++$counter < $totalLines) {
|
||||
$tokens[] = new Token("\n", $this->newlineTokenName, $lineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->activateEOSToken) {
|
||||
$tokens[] = new Token('', $this->eosTokenName, $lineNumber);
|
||||
}
|
||||
|
||||
return new TokenStream($tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first match with the list of terminals
|
||||
*
|
||||
* @return array An array with the following keys:
|
||||
* [0] (string): name of the token
|
||||
* [1] (array): matches of the regular expression
|
||||
*
|
||||
* @throws SyntaxErrorException If the line does not contain any token
|
||||
*/
|
||||
protected function match(string $line, int $lineNumber, int $offset) : array
|
||||
{
|
||||
$restLine = substr($line, $offset);
|
||||
|
||||
foreach ($this->terminals as $pattern => $name) {
|
||||
if (preg_match($pattern, $restLine, $matches)) {
|
||||
return [
|
||||
$name,
|
||||
$matches,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
throw new SyntaxErrorException(sprintf('Lexer error: unable to parse "%s" at line %s.', $line, $lineNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies additional actions over a token.
|
||||
*
|
||||
* Implement this method if you need to do changes after a token was found.
|
||||
* This method is invoked for each token found
|
||||
*
|
||||
* @param Token $token The token
|
||||
* @param string[] $matches Set of matches from the regular expression
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processToken(Token $token, array $matches) : void
|
||||
{
|
||||
}
|
||||
}
|
25
vendor/yosymfony/parser-utils/src/LexerInterface.php
vendored
Normal file
25
vendor/yosymfony/parser-utils/src/LexerInterface.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Yosymfony\ParserUtils package.
|
||||
*
|
||||
* (c) YoSymfony <http://github.com/yosymfony>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Yosymfony\ParserUtils;
|
||||
|
||||
/**
|
||||
* Interface for a lexer
|
||||
*/
|
||||
interface LexerInterface
|
||||
{
|
||||
/**
|
||||
* Returns the tokens found
|
||||
*
|
||||
* @param string $input The input to be tokenized
|
||||
*
|
||||
* @return TokenStream The stream of tokens
|
||||
*/
|
||||
public function tokenize(string $input) : TokenStream;
|
||||
}
|
50
vendor/yosymfony/parser-utils/src/SyntaxErrorException.php
vendored
Normal file
50
vendor/yosymfony/parser-utils/src/SyntaxErrorException.php
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Yosymfony\ParserUtils package.
|
||||
*
|
||||
* (c) YoSymfony <http://github.com/yosymfony>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Yosymfony\ParserUtils;
|
||||
|
||||
/**
|
||||
* Exception thrown when an error occurs during parsing or tokenizing
|
||||
*/
|
||||
class SyntaxErrorException extends \RuntimeException
|
||||
{
|
||||
protected $token;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $message The error messsage
|
||||
* @param Token|null $token The token
|
||||
* @param \Exception|null $previous The previous exceptio
|
||||
*/
|
||||
public function __construct(string $message, Token $token = null, \Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, 0, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the token associated to the exception
|
||||
*
|
||||
* @param Token $token The token
|
||||
*/
|
||||
public function setToken(Token $token) : void
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token associated to the exception
|
||||
*
|
||||
* @return Token|null
|
||||
*/
|
||||
public function getToken() : ?Token
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
}
|
71
vendor/yosymfony/parser-utils/src/Token.php
vendored
Normal file
71
vendor/yosymfony/parser-utils/src/Token.php
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Yosymfony\ParserUtils package.
|
||||
*
|
||||
* (c) YoSymfony <http://github.com/yosymfony>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Yosymfony\ParserUtils;
|
||||
|
||||
class Token
|
||||
{
|
||||
protected $value;
|
||||
protected $name;
|
||||
protected $line;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $value The value of the token
|
||||
* @param string $name The name of the token. e.g: T_BRAKET_BEGIN
|
||||
* @param int $line Line of the code in where the token is found
|
||||
*/
|
||||
public function __construct(string $value, string $name, int $line)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->name = $name;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value (the match term)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue() : string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() : string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the line of the code in where the token is found
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLine() : int
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
public function __toString() : string
|
||||
{
|
||||
return sprintf(
|
||||
"[\n name: %s\n value:%s\n line: %s\n]",
|
||||
$this->name,
|
||||
$this->value,
|
||||
$this->line
|
||||
);
|
||||
}
|
||||
}
|
163
vendor/yosymfony/parser-utils/src/TokenStream.php
vendored
Normal file
163
vendor/yosymfony/parser-utils/src/TokenStream.php
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Yosymfony\ParserUtils package.
|
||||
*
|
||||
* (c) YoSymfony <http://github.com/yosymfony>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Yosymfony\ParserUtils;
|
||||
|
||||
class TokenStream implements TokenStreamInterface
|
||||
{
|
||||
protected $tokens;
|
||||
protected $index = -1;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Token[] List of tokens
|
||||
*/
|
||||
public function __construct(array $tokens)
|
||||
{
|
||||
$this->tokens = $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function moveNext() : ?Token
|
||||
{
|
||||
return $this->tokens[++$this->index] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function matchNext(string $tokenName) : string
|
||||
{
|
||||
$token = $this->moveNext();
|
||||
--$this->index;
|
||||
|
||||
if ($token->getName() == $tokenName) {
|
||||
return $this->moveNext()->getValue();
|
||||
}
|
||||
|
||||
throw new SyntaxErrorException(sprintf(
|
||||
'Syntax error: expected token with name "%s" instead of "%s" at line %s.',
|
||||
$tokenName,
|
||||
$token->getName(),
|
||||
$token->getLine()
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function skipWhile(string $tokenName) : void
|
||||
{
|
||||
$this->skipWhileAny([$tokenName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function skipWhileAny(array $tokenNames) : void
|
||||
{
|
||||
while ($this->isNextAny($tokenNames)) {
|
||||
$this->moveNext();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isNext(string $tokenName) : bool
|
||||
{
|
||||
$token = $this->moveNext();
|
||||
--$this->index;
|
||||
|
||||
if ($token === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $token->getName() == $tokenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isNextSequence(array $tokenNames) : bool
|
||||
{
|
||||
$result = true;
|
||||
$currentIndex = $this->index;
|
||||
|
||||
foreach ($tokenNames as $tokenName) {
|
||||
$token = $this->moveNext();
|
||||
|
||||
if ($token === null || $token->getName() != $tokenName) {
|
||||
$result = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->index = $currentIndex;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isNextAny(array $tokenNames) : bool
|
||||
{
|
||||
$token = $this->moveNext();
|
||||
--$this->index;
|
||||
|
||||
if ($token === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($tokenNames as $tokenName) {
|
||||
if ($tokenName === $token->getName()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all tokens
|
||||
*
|
||||
* @return token[] List of tokens
|
||||
*/
|
||||
public function getAll() : array
|
||||
{
|
||||
return $this->tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasPendingTokens() :bool
|
||||
{
|
||||
$tokenCount = count($this->tokens);
|
||||
|
||||
if ($tokenCount == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->index < ($tokenCount - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset() : void
|
||||
{
|
||||
$this->index = -1;
|
||||
}
|
||||
}
|
89
vendor/yosymfony/parser-utils/src/TokenStreamInterface.php
vendored
Normal file
89
vendor/yosymfony/parser-utils/src/TokenStreamInterface.php
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Yosymfony\ParserUtils package.
|
||||
*
|
||||
* (c) YoSymfony <http://github.com/yosymfony>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Yosymfony\ParserUtils;
|
||||
|
||||
interface TokenStreamInterface
|
||||
{
|
||||
/**
|
||||
* Moves the pointer one token forward
|
||||
*
|
||||
* @return Token|null The token or null if there are not more tokens
|
||||
*/
|
||||
public function moveNext() : ?Token;
|
||||
|
||||
/**
|
||||
* Matches the next token. This method moves the pointer one token forward
|
||||
* if an error does not occur
|
||||
*
|
||||
* @param string $tokenName The name of the token
|
||||
*
|
||||
* @return string The value of the token
|
||||
*
|
||||
* @throws SyntaxErrorException If the next token does not match
|
||||
*/
|
||||
public function matchNext(string $tokenName) : string;
|
||||
|
||||
/**
|
||||
* Skips tokens while they match with the token name passed as argument.
|
||||
* This method moves the pointer "n" tokens forward until the last one
|
||||
* that match with the token name
|
||||
*
|
||||
* @param string $tokenName The name of the token
|
||||
*/
|
||||
public function skipWhile(string $tokenName) : void;
|
||||
|
||||
/**
|
||||
* Skips tokens while they match with one of the token names passed as
|
||||
* argument. This method moves the pointer "n" tokens forward until the
|
||||
* last one that match with one of the token names
|
||||
*
|
||||
* @param string[] $tokenNames List of token names
|
||||
*/
|
||||
public function skipWhileAny(array $tokenNames) : void;
|
||||
|
||||
/**
|
||||
* Checks if the next token matches with the token name passed as argument
|
||||
*
|
||||
* @param string $tokenName The name of the token
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNext(string $tokenName) : bool;
|
||||
|
||||
/**
|
||||
* Checks if the following tokens in the stream match with the sequence of tokens
|
||||
*
|
||||
* @param string[] $tokenNames Sequence of token names
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNextSequence(array $tokenNames) : bool;
|
||||
|
||||
/**
|
||||
* Checks if one of the tokens passed as argument is the next token
|
||||
*
|
||||
* @param string[] $tokenNames List of token names. e.g: 'T_PLUS', 'T_SUB'
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNextAny(array $tokenNames) : bool;
|
||||
|
||||
/**
|
||||
* Has pending tokens?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPendingTokens() :bool;
|
||||
|
||||
/**
|
||||
* Resets the stream to the beginning
|
||||
*/
|
||||
public function reset() : void;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue