Browse Source

Remove old expression parser

master
Adam Pippin 3 years ago
parent
commit
2b619d767b
  1. 61
      app/Cfnpp/Expression/Parser.php
  2. 90
      app/Cfnpp/Expression/TokenFunction.php
  3. 87
      app/Cfnpp/Expression/TokenNumericLiteral.php
  4. 97
      app/Cfnpp/Expression/TokenOperator.php
  5. 95
      app/Cfnpp/Expression/TokenStringLiteral.php
  6. 79
      app/Cfnpp/Expression/TokenVariable.php

61
app/Cfnpp/Expression/Parser.php

@ -1,61 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Cfnpp\Expression;
/**
* Parse a string into a series of expression tokens.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class Parser
{
/**
* List of class names of tokens this parser will parse.
*
* @var string[]
*/
public const TOKEN_TYPES = [
TokenFunction::class,
TokenNumericLiteral::class,
TokenOperator::class,
TokenStringLiteral::class,
TokenVariable::class
];
/**
* Parse a string into an expression.
*
* @param string $value
* @return Expression
*/
public function parse(string $value): Expression
{
$original_value = $value;
$value .= ' ';
$tokens = [];
while (strlen($value) > 0)
{
foreach (static::TOKEN_TYPES as $token_class)
{
if ($token_class::isToken($value))
{
$tokens[] = $token_class::getToken($value);
if (substr($value, 0, 1) != ' ')
{
throw new \Exception('Incompletely consumed token at offset '.(strlen($original_value) - strlen($value)).' in expression '.$original_value);
}
$value = substr($value, 1);
continue 2;
}
}
throw new \Exception('Unparseable value at offset '.(strlen($original_value) - strlen($value)).' in expression '.$original_value);
}
return new Expression($tokens);
}
}

90
app/Cfnpp/Expression/TokenFunction.php

@ -1,90 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Cfnpp\Expression;
/**
* Token representing a function.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class TokenFunction extends Token
{
/**
* List of valid functions this can parse.
* @var string[]
*/
public const FUNCTIONS = [
'concat*',
'concat'
];
/**
* Function this token represents.
* @var string
*/
protected $function;
/**
* Create a new function token.
*
* @param string $function
*/
public function __construct($function)
{
$this->function = $function;
}
/**
* Get the function this token represents.
*
* @return string
*/
public function getFunction(): string
{
return $this->function;
}
/**
* Determine whether a function token can be parsed from a stream.
*
* @param string $stream
* @return bool
*/
public static function isToken(string $stream): bool
{
foreach (static::FUNCTIONS as $function)
{
if (strlen($stream) > strlen($function) &&
substr($stream, 0, strlen($function)) == $function)
{
return true;
}
}
return false;
}
/**
* Parse a function token from a stream.
*
* Returns token, and modifies stream to remove all consumed characters
*
* @param string $stream
* @return Token
*/
public static function getToken(string &$stream): Token
{
foreach (static::FUNCTIONS as $function)
{
if (strlen($stream) > strlen($function) &&
substr($stream, 0, strlen($function)) == $function)
{
$function = substr($stream, 0, strlen($function));
$stream = substr($stream, strlen($function));
return new TokenFunction($function);
}
}
throw new \Exception('Could not parse function token!');
}
}

87
app/Cfnpp/Expression/TokenNumericLiteral.php

@ -1,87 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Cfnpp\Expression;
/**
* Token representing a numeric (integer or float) literal.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class TokenNumericLiteral extends Token
{
/**
* Numeric value this token represents.
* @var int|float
*/
protected $value;
/**
* Create a new numeric literal.
*
* @param int|float $value
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* Get the value this token represents.
*
* @return int|float
*/
public function getValue()
{
return $this->value;
}
/**
* Determine whether a numeric token can be parsed from a stream.
*
* @param string $stream
* @return bool
*/
public static function isToken(string $stream): bool
{
return is_numeric($stream[0]);
}
/**
* Parse a numeric token from a stream.
*
* Returns token, and modifies stream to remove all consumed characters.
*
* @param string $stream
* @return Token
*/
public static function getToken(string &$stream): Token
{
$buffer = '';
for ($i = 0; $i < strlen($stream); $i++)
{
if (preg_match('/^[0-9]$/', $stream[$i]))
{
$buffer .= $stream[$i];
}
else
{
break;
}
}
$stream = substr($stream, strlen($buffer));
if (stristr($buffer, '.'))
{
$buffer = (float)$buffer;
}
else
{
$buffer = (int)$buffer;
}
return new TokenNumericLiteral($buffer);
}
}

97
app/Cfnpp/Expression/TokenOperator.php

@ -1,97 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Cfnpp\Expression;
/**
* Token representing a comparison operator.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class TokenOperator extends Token
{
/**
* List of valid operators this can parse.
* @var string[]
*/
public const OPERATORS = [
'eq',
'neq',
'gt',
'gte',
'lt',
'lte',
'and',
'or',
'not'
];
/**
* Operator this token represents.
* @var string
*/
protected $operator;
/**
* Create a new operator token.
*
* @param string $operator
*/
public function __construct($operator)
{
$this->operator = $operator;
}
/**
* Get the operator this token represents.
*
* @return string
*/
public function getOperator(): string
{
return $this->operator;
}
/**
* Determine whether a operator token can be parsed from a stream.
*
* @param string $stream
* @return bool
*/
public static function isToken(string $stream): bool
{
foreach (static::OPERATORS as $operator)
{
if (strlen($stream) > strlen($operator) &&
substr($stream, 0, strlen($operator)) == $operator)
{
return true;
}
}
return false;
}
/**
* Parse an operator token from a stream.
*
* Returns token, and modifies stream to remove all consumed characters
*
* @param string $stream
* @return Token
*/
public static function getToken(string &$stream): Token
{
foreach (static::OPERATORS as $operator)
{
if (strlen($stream) > strlen($operator) &&
substr($stream, 0, strlen($operator)) == $operator)
{
$operator = substr($stream, 0, strlen($operator));
$stream = substr($stream, strlen($operator));
return new TokenOperator($operator);
}
}
throw new \Exception('Could not parse operator token!');
}
}

95
app/Cfnpp/Expression/TokenStringLiteral.php

@ -1,95 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Cfnpp\Expression;
/**
* Token representing a string literal.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class TokenStringLiteral extends Token
{
/**
* Value of the string literal.
* @var string
*/
protected $value;
/**
* Create a new string literal token.
*
* @param string $value
*/
public function __construct(string $value)
{
$this->value = $value;
}
/**
* Get the value of the string literal.
*
* @return string
*/
public function getValue(): string
{
return $this->value;
}
/**
* Determine whether a string token can be parsed from a stream.
*
* @param string $stream
* @return bool
*/
public static function isToken(string $stream): bool
{
return $stream[0] == '"';
}
/**
* Parse a string literal token from a stream.
*
* Returns token, and modifies stream to remove all consumed characters
*
* @param string $stream
* @return Token
*/
public static function getToken(string &$stream): Token
{
$buffer = '';
$in_string = false;
$escaped = false;
for ($i = 0; $i < strlen($stream); $i++)
{
if ($escaped)
{
$buffer .= $stream[$i];
$escaped = false;
}
elseif ($stream[$i] == '"')
{
if ($in_string)
{
break;
}
$in_string = true;
}
elseif ($stream[$i] == '\\')
{
$escaped = true;
}
else
{
$buffer .= $stream[$i];
}
}
$stream = substr($stream, $i + 1);
return new TokenStringLiteral($buffer);
}
}

79
app/Cfnpp/Expression/TokenVariable.php

@ -1,79 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Cfnpp\Expression;
/**
* Expression token referencing a variable.
*
* @author Adam Pippin <hello@adampippin.ca>
*/
class TokenVariable extends Token
{
/**
* Name of the variable this token references.
* @var string
*/
protected $name;
/**
* Create a new variable token.
*
* @param string $name
*/
public function __construct(string $name)
{
$this->name = $name;
}
/**
* Get the name of the variable this token references.
*
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* Determine whether a variable name token can be parsed from a stream.
*
* @param string $stream
* @return bool
*/
public static function isToken(string $stream): bool
{
return (bool)preg_match('/^[A-Za-z]$/', $stream[0]);
}
/**
* Parse a variable token from a stream.
*
* Returns token, and modifies stream to remove all consumed characters.
*
* @param string $stream
* @return Token
*/
public static function getToken(string &$stream): Token
{
$buffer = '';
$buffer = $stream[0];
for ($i = 1; $i < strlen($stream); $i++)
{
if (preg_match('/^[A-Za-z0-9]$/', $stream[$i]))
{
$buffer .= $stream[$i];
}
else
{
break;
}
}
$stream = substr($stream, strlen($buffer));
return new TokenVariable($buffer);
}
}
Loading…
Cancel
Save