First commit
This commit is contained in:
commit
d5bb2f19fa
117 changed files with 68604 additions and 0 deletions
4
vendor/yosymfony/parser-utils/.gitignore
vendored
Normal file
4
vendor/yosymfony/parser-utils/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
vendor/
|
||||
phpunit.xml
|
||||
.php_cs.cache
|
||||
composer.lock
|
15
vendor/yosymfony/parser-utils/.travis.yml
vendored
Normal file
15
vendor/yosymfony/parser-utils/.travis.yml
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
language: php
|
||||
|
||||
php:
|
||||
- 7.1
|
||||
- 7.2
|
||||
- nightly
|
||||
|
||||
before_script:
|
||||
- composer self-update
|
||||
- composer install --no-interaction --no-dev
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
fast_finish: true
|
12
vendor/yosymfony/parser-utils/CHANGELOG.md
vendored
Normal file
12
vendor/yosymfony/parser-utils/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
2.0.0 (2018/06/29)
|
||||
------------------
|
||||
* [New] The class `TokenStream` implements `TokenStreamInterface`.
|
||||
* [New] Added PHPUnit as dev-requirement
|
||||
* [Fixed] Fixed a typo with the method `parseImplementation` from the class `AbstractParser`.
|
||||
The previous name was `parseImplentation`.
|
||||
|
||||
1.0.0 (2017/11/18)
|
||||
------------------
|
||||
* Initial version.
|
19
vendor/yosymfony/parser-utils/LICENSE
vendored
Normal file
19
vendor/yosymfony/parser-utils/LICENSE
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2017-2018 Víctor Puertas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
145
vendor/yosymfony/parser-utils/README.md
vendored
Normal file
145
vendor/yosymfony/parser-utils/README.md
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
A library for writing [recursive descent parsers](https://en.wikipedia.org/wiki/Recursive_descent_parser)
|
||||
in PHP.
|
||||
|
||||
[](https://travis-ci.org/yosymfony/parser-utils)
|
||||
|
||||
## requires
|
||||
|
||||
* PHP >= 7.1
|
||||
|
||||
## Installation
|
||||
|
||||
The preferred installation method is [composer](https://getcomposer.org):
|
||||
|
||||
```bash
|
||||
composer require yosymfony/parser-utils
|
||||
```
|
||||
|
||||
## An example
|
||||
|
||||
First, you need to create a lexer. This one will recognize tokens
|
||||
|
||||
```php
|
||||
use Yosymfony\ParserUtils\BasicLexer;
|
||||
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/x' => 'T_NUMBER',
|
||||
'/^(\+)/x' => 'T_PLUS',
|
||||
'/^(-)/x' => 'T_MINUS',
|
||||
'/^\s+/' => 'T_SPACE', // We do not surround it with parentheses because
|
||||
// this is not meaningful for us in this case
|
||||
]);
|
||||
```
|
||||
|
||||
Second, you need a parser for consuming the tokens provided by the lexer.
|
||||
The `AbstractParser` class contains an abstract method called `parseImplementation`
|
||||
that receives a `TokenStream` as an argument.
|
||||
|
||||
```php
|
||||
use Yosymfony\ParserUtils\AbstractParser;
|
||||
|
||||
class Parser extends AbstractParser
|
||||
{
|
||||
protected function parseImplementation(TokenStream $stream)
|
||||
{
|
||||
$result = $stream->matchNext('T_NUMBER');
|
||||
|
||||
while ($stream->isNextAny(['T_PLUS', 'T_MINUS'])) {
|
||||
switch ($stream->moveNext()->getName()) {
|
||||
case 'T_PLUS':
|
||||
$result += $stream->matchNext('T_NUMBER');
|
||||
break;
|
||||
case 'T_MINUS':
|
||||
$result -= $stream->matchNext('T_NUMBER');
|
||||
break;
|
||||
default:
|
||||
throw new SyntaxErrorException("Something went wrong");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now, you can see the results:
|
||||
|
||||
```php
|
||||
$parser = new Parser($lexer);
|
||||
$parser->parse('1 + 1'); // 2
|
||||
```
|
||||
|
||||
### The BasicLexer class
|
||||
|
||||
The lexer has the responsibility of recognizing tokens. This one works line by
|
||||
line. If you want to generate an special `T_NEWLINE` token for each line
|
||||
of the input, call `$lexer->generateNewlineTokens()` before tokenizing. You can set the
|
||||
name of this special token using the method `setNewlineTokenName`.
|
||||
|
||||
```php
|
||||
$lexer = new BasicLexer([...]);
|
||||
$lexer->generateNewlineTokens()
|
||||
->setNewlineTokenName('T_NL');
|
||||
|
||||
$lexer->tokenize('...');
|
||||
```
|
||||
|
||||
Additionally, there is another special token `T_EOS` that determines the end of the input
|
||||
string. To enable this feature call `$lexer->generateEosToken()` before tokenizing.
|
||||
You can set the name of this special token using the method `setEosTokenName`.
|
||||
|
||||
```php
|
||||
$lexer = new BasicLexer([...]);
|
||||
$lexer->generateEosToken()
|
||||
->setEosTokenName('T_MY_EOS');
|
||||
|
||||
$lexer->tokenize('...');
|
||||
```
|
||||
|
||||
### The TokenStream class
|
||||
|
||||
This class let you treat with the list of tokens returned by the lexer.
|
||||
|
||||
* **moveNext**: Moves the pointer one token forward. Returns a `Token` object or
|
||||
`null` if there are not more tokens. e.g: `$ts->moveNext()`.
|
||||
* **matchNext**: Matches the next token and returns its value. This method moves
|
||||
the pointer one token forward. It will throw an `SyntaxErrorException` exception
|
||||
if the next token does not match. e.g: `$number = $ts->matchNext('T_NUMBER')`.
|
||||
* **isNext**: Checks if the next token matches with the token name passed as argument.
|
||||
e.g: `$ts->isNext('T_PLUS') // true or false`.
|
||||
* **skipWhile**: 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. e.g: `$ts->skipWhile('T_PLUS')`
|
||||
* **skipWhileAny**: 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
|
||||
e.g: `$ts->skipWhileAny(['T_PLUS', 'T_MINUS'])`
|
||||
|
||||
* **isNextSequence**: Checks if the following tokens in the stream match with
|
||||
the sequence of tokens. e.g: `$ts->isNextSequence(['T_NUMBER', 'T_PLUS', 'T_NUMBER']) // true or false`.
|
||||
* **isNextAny**: Checks if one of the tokens passed as argument is the next token.
|
||||
e.g: `$fs->isNextAny(['T_PLUS', 'T_SUB']) // true or false`
|
||||
* **hasPendingTokens**: Has pending tokens? e.g: `$fs->hasPendingTokens() // true or false`.
|
||||
* **reset**: Resets the stream to the beginning.
|
||||
|
||||
### Tokens
|
||||
|
||||
Tokens are instances of `Token` class, a class than contains the following methods:
|
||||
|
||||
* **getName**: returns the name of the toke. e.g: `T_SUM`.
|
||||
* **getValue**: returns the value of the token.
|
||||
* **getLine**: returns the line in where the token is found.
|
||||
|
||||
## Unit tests
|
||||
|
||||
You can run the unit tests with the following command:
|
||||
|
||||
```bash
|
||||
$ cd parser-utils
|
||||
$ composer test
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This library is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
|
32
vendor/yosymfony/parser-utils/composer.json
vendored
Normal file
32
vendor/yosymfony/parser-utils/composer.json
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "yosymfony/parser-utils",
|
||||
"description": "Parser utilities",
|
||||
"type": "library",
|
||||
"keywords": ["parser", "lexer"],
|
||||
"homepage": "http://github.com/yosymfony/toml",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Victor Puertas",
|
||||
"email": "vpgugr@gmail.com",
|
||||
"homepage": "http://yosymfony.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Yosymfony\\ParserUtils\\": "src/" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/phpunit"
|
||||
}
|
||||
}
|
22
vendor/yosymfony/parser-utils/phpunit.xml.dist
vendored
Normal file
22
vendor/yosymfony/parser-utils/phpunit.xml.dist
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Spress Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./</directory>
|
||||
<exclude>
|
||||
<directory>./vendor</directory>
|
||||
<directory>./tests</directory>
|
||||
</exclude>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
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;
|
||||
}
|
62
vendor/yosymfony/parser-utils/tests/AbstractParserTest.php
vendored
Normal file
62
vendor/yosymfony/parser-utils/tests/AbstractParserTest.php
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?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\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Yosymfony\ParserUtils\AbstractParser;
|
||||
use Yosymfony\ParserUtils\BasicLexer;
|
||||
use Yosymfony\ParserUtils\SyntaxErrorException;
|
||||
use Yosymfony\ParserUtils\TokenStream;
|
||||
|
||||
class AbstractParserTest extends TestCase
|
||||
{
|
||||
private $parser;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/x' => 'T_NUMBER',
|
||||
'/^(\+)/x' => 'T_PLUS',
|
||||
'/^(-)/x' => 'T_MINUS',
|
||||
'/^\s+/' => 'T_SPACE',
|
||||
]);
|
||||
|
||||
$this->parser = $this->getMockBuilder(AbstractParser::class)
|
||||
->setConstructorArgs([$lexer])
|
||||
->getMockForAbstractClass();
|
||||
$this->parser->expects($this->any())
|
||||
->method('parseImplementation')
|
||||
->will($this->returnCallback(function (TokenStream $stream) {
|
||||
$result = $stream->matchNext('T_NUMBER');
|
||||
|
||||
while ($stream->isNextAny(['T_PLUS', 'T_MINUS'])) {
|
||||
switch ($stream->moveNext()->getName()) {
|
||||
case 'T_PLUS':
|
||||
$result += $stream->matchNext('T_NUMBER');
|
||||
break;
|
||||
case 'T_MINUS':
|
||||
$result -= $stream->matchNext('T_NUMBER');
|
||||
break;
|
||||
default:
|
||||
throw new SyntaxErrorException("Something went wrong");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}));
|
||||
}
|
||||
|
||||
public function testParseMustReturnTheResultOfTheSum()
|
||||
{
|
||||
$this->assertEquals(2, $this->parser->parse('1 + 1'));
|
||||
}
|
||||
}
|
127
vendor/yosymfony/parser-utils/tests/BasicLexerTest.php
vendored
Normal file
127
vendor/yosymfony/parser-utils/tests/BasicLexerTest.php
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?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\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Yosymfony\ParserUtils\BasicLexer;
|
||||
use Yosymfony\ParserUtils\Token;
|
||||
|
||||
class BasicLexerTest extends TestCase
|
||||
{
|
||||
public function testTokenizeMustReturnsTheListOfTokens()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/x' => 'T_NUMBER',
|
||||
'/^(\+)/x' => 'T_PLUS',
|
||||
'/^(-)/x' => 'T_MINUS',
|
||||
]);
|
||||
$tokens = $lexer->tokenize('1+2')->getAll();
|
||||
|
||||
$this->assertEquals([
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('2', 'T_NUMBER', 1),
|
||||
], $tokens);
|
||||
}
|
||||
|
||||
public function testTokenizeMustReturnsTheListOfTokensWithoutThoseDoNotHaveParenthesizedSupatternInTerminalSymbols()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/' => 'T_NUMBER',
|
||||
'/^(\+)/' => 'T_PLUS',
|
||||
'/^(-)/' => 'T_MINUS',
|
||||
'/^\s+/' => 'T_SPACE',
|
||||
]);
|
||||
|
||||
$tokens = $lexer->tokenize('1 + 2')->getAll();
|
||||
|
||||
$this->assertEquals([
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('2', 'T_NUMBER', 1),
|
||||
], $tokens, 'T_SPACE is not surround with (). e.g: ^(\s+)');
|
||||
}
|
||||
|
||||
public function testTokenizeWithEmptyStringMustReturnsZeroTokens()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/' => 'T_NUMBER',
|
||||
'/^(\+)/' => 'T_PLUS',
|
||||
'/^(-)/' => 'T_MINUS',
|
||||
]);
|
||||
|
||||
$tokens = $lexer->tokenize('')->getAll();
|
||||
|
||||
$this->assertCount(0, $tokens);
|
||||
}
|
||||
|
||||
public function testTokenizeMustReturnsNewLineTokensWhenGenerateNewlineTokensIsEnabled()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/' => 'T_NUMBER',
|
||||
]);
|
||||
$lexer->generateNewlineTokens();
|
||||
|
||||
$ts = $lexer->tokenize("0\n");
|
||||
$ts->moveNext();
|
||||
$token = $ts->moveNext();
|
||||
|
||||
$this->assertEquals('T_NEWLINE', $token->getName());
|
||||
$this->assertFalse($ts->hasPendingTokens());
|
||||
}
|
||||
|
||||
public function testTokenizeMustReturnsCustomNewLineTokensWhenThereIsCustomNameAndGenerateNewlineTokensIsEnabled()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/' => 'T_NUMBER',
|
||||
]);
|
||||
$lexer->setNewlineTokenName('T_MY_NEWLINE')
|
||||
->generateNewlineTokens();
|
||||
|
||||
$ts = $lexer->tokenize("0\n");
|
||||
$ts->moveNext();
|
||||
$token = $ts->moveNext();
|
||||
|
||||
$this->assertEquals('T_MY_NEWLINE', $token->getName());
|
||||
$this->assertFalse($ts->hasPendingTokens());
|
||||
}
|
||||
|
||||
public function testTokenizeMustReturnsEosTokenWhenGenerateEosTokenIsEnabled()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/' => 'T_NUMBER',
|
||||
]);
|
||||
$lexer->generateEosToken();
|
||||
|
||||
$ts = $lexer->tokenize("0");
|
||||
$ts->moveNext();
|
||||
$token = $ts->moveNext();
|
||||
|
||||
$this->assertEquals('T_EOS', $token->getName());
|
||||
$this->assertFalse($ts->hasPendingTokens());
|
||||
}
|
||||
|
||||
public function testTokenizeMustReturnsCustomNameEosTokenWhenThereIsCustomNameAndGenerateEosTokenIsEnabled()
|
||||
{
|
||||
$lexer = new BasicLexer([
|
||||
'/^([0-9]+)/' => 'T_NUMBER',
|
||||
]);
|
||||
$lexer->setEosTokenName('T_MY_EOS')
|
||||
->generateEosToken();
|
||||
|
||||
$ts = $lexer->tokenize("0");
|
||||
$ts->moveNext();
|
||||
$token = $ts->moveNext();
|
||||
|
||||
$this->assertEquals('T_MY_EOS', $token->getName());
|
||||
$this->assertFalse($ts->hasPendingTokens());
|
||||
}
|
||||
}
|
261
vendor/yosymfony/parser-utils/tests/TokenStreamTest.php
vendored
Normal file
261
vendor/yosymfony/parser-utils/tests/TokenStreamTest.php
vendored
Normal file
|
@ -0,0 +1,261 @@
|
|||
<?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\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Yosymfony\ParserUtils\SyntaxErrorException;
|
||||
use Yosymfony\ParserUtils\Token;
|
||||
use Yosymfony\ParserUtils\TokenStream;
|
||||
|
||||
class TokenStreamTest extends TestCase
|
||||
{
|
||||
public function testGetAllMustReturnsAllTokens()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$this->assertCount(2, $ts->getAll());
|
||||
}
|
||||
|
||||
public function testMoveNextMustReturnsTheFirstTokenTheFirstTime()
|
||||
{
|
||||
$token = new Token('+', 'T_PLUS', 1);
|
||||
$ts = new TokenStream([
|
||||
$token,
|
||||
]);
|
||||
|
||||
$this->assertEquals($token, $ts->moveNext());
|
||||
}
|
||||
|
||||
public function testMoveNextMustReturnsTheSecondTokenTheSecondTime()
|
||||
{
|
||||
$token = new Token('1', 'T_NUMBER', 1);
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
$token,
|
||||
]);
|
||||
$ts->moveNext();
|
||||
|
||||
$this->assertEquals($token, $ts->moveNext());
|
||||
}
|
||||
|
||||
public function testMoveNextMustReturnsWhenThereAreNotMoreTokens()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
]);
|
||||
$ts->moveNext();
|
||||
|
||||
$this->assertNull($ts->moveNext());
|
||||
}
|
||||
|
||||
public function testMoveNextMustReturnsTheFirstTokenAfterAReset()
|
||||
{
|
||||
$token = new Token('1', 'T_NUMBER', 1);
|
||||
$ts = new TokenStream([
|
||||
$token,
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
]);
|
||||
$ts->moveNext();
|
||||
$ts->moveNext();
|
||||
|
||||
$ts->reset();
|
||||
|
||||
$this->assertEquals($token, $ts->moveNext());
|
||||
}
|
||||
|
||||
public function testMatchNextMustReturnMatchValueWhenTheNameOfNextTokenMatchWithTheNamePassed()
|
||||
{
|
||||
$token = new Token('1', 'T_NUMBER', 1);
|
||||
$ts = new TokenStream([
|
||||
$token,
|
||||
]);
|
||||
|
||||
$this->assertEquals('1', $ts->matchNext('T_NUMBER'));
|
||||
}
|
||||
|
||||
public function testMatchNextMustThrowExceptionWhenTheNameOfNextTokenDoesNotMatchWithTheNamePassed()
|
||||
{
|
||||
$this->expectException(SyntaxErrorException::class);
|
||||
$this->expectExceptionMessage('Syntax error: expected token with name "T_PLUS" instead of "T_NUMBER" at line 1.');
|
||||
|
||||
$token = new Token('1', 'T_NUMBER', 1);
|
||||
$ts = new TokenStream([
|
||||
$token,
|
||||
]);
|
||||
|
||||
$ts->matchNext('T_PLUS');
|
||||
}
|
||||
|
||||
public function testIsNextMustReturnsTrueWhenTheNameOfNextTokenMatchWithTheNamePassed()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$ts->moveNext();
|
||||
|
||||
$this->assertTrue($ts->isNext('T_NUMBER'));
|
||||
}
|
||||
|
||||
public function testIsNextMustReturnsTrueWhenTheNameOfNextTokenMatchWithTheNamePassedAtTheBeginning()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$this->assertTrue($ts->isNext('T_PLUS'));
|
||||
}
|
||||
|
||||
public function testIsNextMustReturnsFalseWhenTheNameOfNextTokenDoesNotMatchWithTheNamePassed()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$this->assertFalse($ts->isNext('T_NUMBER'));
|
||||
}
|
||||
|
||||
public function testIsNextMustNotAlterTheTokenStream()
|
||||
{
|
||||
$token = new Token('+', 'T_PLUS', 1);
|
||||
$ts = new TokenStream([
|
||||
$token,
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
$ts->isNext('T_PLUS');
|
||||
|
||||
$this->assertEquals($token, $ts->moveNext(), 'The next token must be T_PLUS');
|
||||
}
|
||||
|
||||
public function testIsNextSequenceMustReturnTrueWhenTheFollowingTokensInTheStreamMatchWithSequence()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$this->assertTrue($ts->isNextSequence(['T_PLUS', 'T_NUMBER']));
|
||||
}
|
||||
|
||||
public function testIsNextSequenceMustReturnFalseWhenTheFollowingTokensInTheStreamDoesNotMatchWithSequence()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$this->assertFalse($ts->isNextSequence(['T_NUMBER', 'T_PLUS']));
|
||||
}
|
||||
|
||||
public function testIsNextSequenceMustNotAlterTheTokenStream()
|
||||
{
|
||||
$token = new Token('+', 'T_PLUS', 1);
|
||||
$ts = new TokenStream([
|
||||
$token,
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
$ts->isNextSequence(['T_NUMBER', 'T_PLUS']);
|
||||
|
||||
$this->assertEquals($token, $ts->moveNext(), 'The next token must be T_PLUS');
|
||||
}
|
||||
|
||||
public function testIsNextAnyMustReturnTrueWhenNameOfNextTokenMatchWithOneOfTheList()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$this->assertTrue($ts->isNextAny(['T_MINUS', 'T_PLUS']));
|
||||
}
|
||||
|
||||
public function testIsNextAnyMustReturnFalseWhenNameOfNextTokenDoesNotMatchWithOneOfTheList()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$this->assertFalse($ts->isNextAny(['T_DIV', 'T_MINUS']));
|
||||
}
|
||||
|
||||
public function testIsNextAnyMustNotAlterTheTokenStream()
|
||||
{
|
||||
$token = new Token('+', 'T_PLUS', 1);
|
||||
$ts = new TokenStream([
|
||||
$token,
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
$ts->isNextAny(['T_MINUS', 'T_PLUS']);
|
||||
|
||||
$this->assertEquals($token, $ts->moveNext(), 'The next token must be T_PLUS');
|
||||
}
|
||||
|
||||
public function testHasPendingTokensMustReturnTrueWhenThereArePendingTokens()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
]);
|
||||
|
||||
$this->assertTrue($ts->hasPendingTokens());
|
||||
}
|
||||
|
||||
public function testHasPendingTokensMustReturnFalseWhenTokenStreamIsEmpty()
|
||||
{
|
||||
$ts = new TokenStream([]);
|
||||
|
||||
$this->assertFalse($ts->hasPendingTokens());
|
||||
}
|
||||
|
||||
public function testHasPendingTokensMustReturnFalseAfterPointingToTheLastToken()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
]);
|
||||
|
||||
$ts->moveNext();
|
||||
|
||||
$this->assertFalse($ts->hasPendingTokens());
|
||||
}
|
||||
|
||||
public function testSkipWhileMustMovesPointerNTokensForwardUtilLastOneInstanceOfToken()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$ts->skipWhile('T_PLUS');
|
||||
|
||||
$this->assertTrue($ts->isNext('T_NUMBER'));
|
||||
}
|
||||
|
||||
public function testSkipWhileAnyMustMovesPointerNTokensForwardUtilLastOneInstanceOfOneOfAnyTokens()
|
||||
{
|
||||
$ts = new TokenStream([
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('+', 'T_PLUS', 1),
|
||||
new Token('+', 'T_MINUS', 1),
|
||||
new Token('1', 'T_NUMBER', 1),
|
||||
]);
|
||||
|
||||
$ts->skipWhileAny(['T_PLUS', 'T_MINUS']);
|
||||
|
||||
$this->assertTrue($ts->isNext('T_NUMBER'));
|
||||
}
|
||||
}
|
26
vendor/yosymfony/parser-utils/tests/TokenTest.php
vendored
Normal file
26
vendor/yosymfony/parser-utils/tests/TokenTest.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?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\Test;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Yosymfony\ParserUtils\Token;
|
||||
|
||||
class TokenTest extends TestCase
|
||||
{
|
||||
public function testConstructorMustSetMatchAndNameAndLine()
|
||||
{
|
||||
$token = new Token('+', 'T_PLUS', 1);
|
||||
|
||||
$this->assertEquals('+', $token->getValue());
|
||||
$this->assertEquals('T_PLUS', $token->getName());
|
||||
$this->assertEquals(1, $token->getLine());
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue