Browse Source

Scope parsing fixes

main
Dustin Wilson 3 years ago
parent
commit
6a9fd79f11
  1. 1
      lib/Scope/Composite.php
  2. 2
      lib/Scope/Data.php
  3. 8
      lib/Scope/Exception.php
  4. 9
      lib/Scope/Expression.php
  5. 28
      lib/Scope/Filter.php
  6. 20
      lib/Scope/Parser.php

1
lib/Scope/Composite.php

@ -26,7 +26,6 @@ class Composite extends Node {
return true;
}
public function __toString(): string {
return implode(' ', $this->_expressions);
}

2
lib/Scope/Data.php

@ -37,7 +37,7 @@ class Data {
return false;
}
return $this->data[$this->_position + 1][1];
return $this->data[$this->_position][1];
}
/** Returns the next token without moving the pointer */

8
lib/Scope/Exception.php

@ -9,7 +9,11 @@ namespace dW\Lit\Scope;
class Exception extends \Exception {
const MESSAGE = '%s expected; found %s at offset %s'.\PHP_EOL;
public function __construct(array|string $expected, string|bool $found, int $offset) {
public function __construct(array|string|bool $expected, string|bool $found, int $offset) {
if ($expected === false) {
$expected = 'end of input';
}
if (!is_string($expected)) {
$expectedLen = count($expected);
if ($expectedLen === 1) {
@ -28,8 +32,6 @@ class Exception extends \Exception {
$expected = implode(' or ', $expected);
}
}
} else {
$expected = ($expected !== false) ? $expected : 'end of input';
}
$found = ($found !== false) ? "\"$found\"" : 'end of input';

9
lib/Scope/Expression.php

@ -9,6 +9,7 @@ namespace dW\Lit\Scope;
class Expression extends Node {
protected Filter|Group|Path $_child;
protected bool $frozen = false;
protected bool $_negate = false;
protected int $_operator;
const OPERATOR_NONE = 0;
@ -17,11 +18,12 @@ class Expression extends Node {
const OPERATOR_NOT = 3;
public function __construct(Composite $parent, int $operator = self::OPERATOR_NONE) {
public function __construct(Composite $parent, int $operator = self::OPERATOR_NONE, bool $negate = false) {
$this->_negate = $negate;
$this->_operator = $operator;
$this->_parent = \WeakReference::create($parent);
}
public function __set(string $name, $value) {
if ($name !== 'child') {
@ -51,6 +53,7 @@ class Expression extends Node {
case self::OPERATOR_NOT: $operator = '- ';
}
return "$operator{$this->_child}";
$negate = ($this->_negate) ? '- ' : '';
return "$operator$negate{$this->_child}";
}
}

28
lib/Scope/Filter.php

@ -9,14 +9,25 @@ namespace dW\Lit\Scope;
class Filter extends Node {
protected Group|Path $_child;
protected bool $frozen = false;
protected string $_side;
protected int $_side;
const SIDE_LEFT = 0;
const SIDE_RIGHT = 1;
const SIDE_BOTH = 2;
public function __construct(Expression $parent, string $side) {
$this->_parent = \WeakReference::create($parent);
$this->_side = $side;
}
switch ($side) {
case 'L': $this->_side = self::SIDE_LEFT;
break;
case 'R': $this->_side = self::SIDE_RIGHT;
break;
case 'B': $this->_side = self::SIDE_BOTH;
break;
}
}
public function __set(string $name, $value) {
if ($name !== 'child') {
@ -36,6 +47,15 @@ class Filter extends Node {
public function __toString(): string {
return "{$this->_side}:{$this->_child}";
switch ($this->_side) {
case self::SIDE_LEFT: $side = 'L';
break;
case self::SIDE_RIGHT: $side = 'R';
break;
case self::SIDE_BOTH: $side = 'B';
break;
}
return "$side:{$this->_child}";
}
}

20
lib/Scope/Parser.php

@ -36,6 +36,13 @@ class Parser {
self::$instance = new self($string);
$result = self::parseSelector();
// If not at the end of input throw an exception.
$token = self::$instance->data->consume();
if ($token !== false) {
self::throw(false, $token);
}
self::$cache[$string] = $result;
return $result;
}
@ -73,9 +80,16 @@ class Parser {
protected static function parseExpression(Composite $parent, int $operator = Expression::OPERATOR_NONE): Expression {
assert((fn() => self::debug())());
$result = new Expression($parent, $operator);
$peek = self::$instance->data->peek();
$negate = false;
if ($peek === '-') {
self::$instance->data->consume();
$peek = self::$instance->data->peek();
$negate = true;
}
$result = new Expression($parent, $operator, $negate);
if (in_array($peek[0], [ 'B', 'L', 'R' ])) {
$result->child = self::parseFilter($result, self::$instance->data->consume()[0]);
} elseif ($peek === '(') {
@ -271,7 +285,7 @@ class Parser {
return true;
}
protected static function throw(array|string $expected, string|bool $found) {
protected static function throw(array|string|bool $expected, string|bool $found) {
throw new Exception($expected, $found, self::$instance->data->offset());
}
}

Loading…
Cancel
Save