Browse Source

Scope parser is functioning okay enough

main
Dustin Wilson 3 years ago
parent
commit
d0928d7c4d
  1. 24
      lib/Scope/Data.php
  2. 2
      lib/Scope/Exception.php
  3. 17
      lib/Scope/Matchers/AndMatcher.php
  4. 16
      lib/Scope/Matchers/CompositeMatcher.php
  5. 8
      lib/Scope/Matchers/GroupMatcher.php
  6. 6
      lib/Scope/Matchers/NegateMatcher.php
  7. 8
      lib/Scope/Matchers/OrMatcher.php
  8. 2
      lib/Scope/Matchers/PathMatcher.php
  9. 92
      lib/Scope/Parser.php

24
lib/Scope/Data.php

@ -14,7 +14,7 @@ class Data {
public function __construct(string $data) {
$this->data = $data;
$this->endPosition = strlen($data) - 1;
$this->endPosition = strlen($data);
}
public function consume(int $length = 1): string|bool {
@ -39,19 +39,6 @@ class Data {
return $this->consumeWhile($match, 1);
}
public function consumeUntil(string $match, $limit = null): string|bool {
if ($this->_position === $this->endPosition) {
return false;
}
$length = strcspn($this->data, $match, $this->_position, $limit);
if ($length === 0) {
return '';
}
return $this->consume($length);
}
public function consumeWhile(string $match, $limit = null): string|bool {
if ($this->_position === $this->endPosition) {
return false;
@ -83,6 +70,15 @@ class Data {
return $output;
}
public function unconsumeTo(int $position = 1): bool {
if ($position < 0 || $position > $this->endPosition) {
return false;
}
$this->_position = $position;
return true;
}
public function __get(string $name) {
if ($name === 'position') {
return $this->_position;

2
lib/Scope/Exception.php

@ -9,7 +9,7 @@ namespace dW\Highlighter\Scope;
class Exception extends \Exception {
const MESSAGE = '%s expected; found %s';
public function __construct(string $expected, string $found) {
public function __construct(string $expected, string|bool $found) {
$strlen = strlen($expected);
if ($strlen > 1) {
$temp = [];

17
lib/Scope/Matchers/AndMatcher.php

@ -0,0 +1,17 @@
<?php
/** @license MIT
* Copyright 2021 Dustin Wilson et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace dW\Highlighter\Scope;
class AndMatcher extends Matcher {
protected Matcher $left;
protected Matcher $right;
public function __construct(Matcher $left, Matcher $right) {
$this->left = $left;
$this->right = $right;
}
}

16
lib/Scope/Matchers/CompositeMatcher.php

@ -7,5 +7,19 @@ declare(strict_types=1);
namespace dW\Highlighter\Scope;
class CompositeMatcher extends Matcher {
public function __construct(Matcher $left, string $operator, Matcher $right) {}
protected Matcher $matcher;
public function __construct(Matcher $left, string $operator, Matcher $right) {
switch ($operator) {
case '|':
$this->matcher = new OrMatcher($left, $right);
break;
case '&':
$this->matcher = new AndMatcher($left, $right);
break;
case '-':
$this->matcher = new AndMatcher($left, new NegateMatcher($right));
break;
}
}
}

8
lib/Scope/Matchers/GroupMatcher.php

@ -7,5 +7,11 @@ declare(strict_types=1);
namespace dW\Highlighter\Scope;
class GroupMatcher extends Matcher {
public function __construct(string $prefix, Matcher $selector) {}
protected string|null $prefix;
protected Matcher $selector;
public function __construct(string|null $prefix, Matcher $selector) {
$this->prefix = ($prefix !== null) ? $prefix[0] : null;
$this->selector = $selector;
}
}

6
lib/Scope/Matchers/NegateMatcher.php

@ -7,5 +7,9 @@ declare(strict_types=1);
namespace dW\Highlighter\Scope;
class NegateMatcher extends Matcher {
public function __construct(Matcher $groupOrPath) {}
protected Matcher $matcher;
public function __construct(Matcher $matcher) {
$this->matcher = $matcher;
}
}

8
lib/Scope/Matchers/OrMatcher.php

@ -7,5 +7,11 @@ declare(strict_types=1);
namespace dW\Highlighter\Scope;
class OrMatcher extends Matcher {
public function __construct(Matcher $left, Matcher $right) {}
protected Matcher $left;
protected Matcher $right;
public function __construct(Matcher $left, Matcher $right) {
$this->left = $left;
$this->right = $right;
}
}

2
lib/Scope/Matchers/PathMatcher.php

@ -11,7 +11,7 @@ class PathMatcher extends Matcher {
protected array $matchers;
public function __construct(string|null $prefix, Matcher ...$matchers) {
$this->prefix = $prefix;
$this->prefix = ($prefix !== null) ? $prefix[0] : null;
$this->matchers = $matchers;
}
}

92
lib/Scope/Parser.php

@ -30,16 +30,10 @@ class Parser {
$s2 = self::parseSelector();
if ($s2 !== false) {
$s3 = self::parseSpace();
if ($s3 !== false) {
$result = $s2;
}
$result = $s2;
}
}
if (self::$debug === true) {
echo "------------------------------\n";
}
if ($result === false && self::$instance->lastExceptionData !== []) {
throw new Exception(self::$instance->lastExceptionData['expected'], self::$instance->lastExceptionData['found']);
}
@ -53,6 +47,7 @@ class Parser {
}
$result = false;
$position = self::$instance->data->position;
$s1 = self::parseExpression();
if ($s1 !== false) {
@ -77,11 +72,12 @@ class Parser {
}
if ($result === false) {
self::$instance->data->unconsumeTo($position);
$result = self::parseExpression();
}
if (self::$debug === true) {
echo "parseComposite Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -142,7 +138,7 @@ class Parser {
}
if (self::$debug === true) {
echo "parseExpression Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -174,29 +170,27 @@ class Parser {
}
}
if ($prefix !== null) {
$s2 = self::$instance->data->consumeIf('(');
if ($s2 === '' || $s2 === false) {
$s2 = false;
self::fail('(');
}
$s2 = self::$instance->data->consumeIf('(');
if ($s2 === '' || $s2 === false) {
$s2 = false;
self::fail('(');
}
if ($s2 !== false) {
$s3 = self::parse();
if ($s3 !== false) {
$s4 = self::parseSelector();
if ($s4 !== false) {
$s5 = self::parseSpace();
if ($s5 !== false) {
$s6 = self::$instance->data->consumeIf(')');
if ($s6 === '' || $s6 === false) {
$s6 = false;
self::fail(')');
}
if ($s6 !== false) {
$result = new GroupMatcher($prefix, $s4);
}
if ($s2 !== false) {
$s3 = self::parseSpace();
if ($s3 !== false) {
$s4 = self::parseSelector();
if ($s4 !== false) {
$s5 = self::parseSpace();
if ($s5 !== false) {
$s6 = self::$instance->data->consumeIf(')');
if ($s6 === '' || $s6 === false) {
$s6 = false;
self::fail(')');
}
if ($s6 !== false) {
$result = new GroupMatcher($prefix, $s4);
}
}
}
@ -204,7 +198,7 @@ class Parser {
}
if (self::$debug === true) {
echo "parseGroup Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -241,7 +235,7 @@ class Parser {
$s3 = [$s2];
do {
$s4 = false;
$s6 = false;
$s5 = self::parseSpace();
if ($s5 !== false) {
$s6 = self::parseScope();
@ -249,13 +243,13 @@ class Parser {
$s3[] = $s6;
}
}
} while ($s4 !== false);
} while ($s6 !== false);
$result = new PathMatcher($prefix, ...$s3);
}
if (self::$debug === true) {
echo "parsePath Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -313,7 +307,7 @@ class Parser {
}
if (self::$debug === true) {
echo "parseSegment Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -325,6 +319,7 @@ class Parser {
}
$result = false;
$position = self::$instance->data->position;
$s1 = self::parseComposite();
if ($s1 !== false) {
@ -346,8 +341,13 @@ class Parser {
}
}
if ($result === false) {
self::$instance->data->unconsumeTo($position);
$result = self::parseComposite();
}
if (self::$debug === true) {
echo "parseSelector Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -384,7 +384,7 @@ class Parser {
}
if (self::$debug === true) {
echo "parseScope Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -401,7 +401,7 @@ class Parser {
}
if (self::$debug === true) {
echo "parseSpace Result: " . var_export($result, true) . "\n";
self::debugResult($result);
}
return $result;
@ -409,12 +409,16 @@ class Parser {
protected static function debug() {
/*if (self::$debugCount === 2500) {
die();
}*/
$message = <<<DEBUG
------------------------------
%s
Method: %s
Position: %s
Char: '%s'
Char: %s
DEBUG;
@ -430,10 +434,16 @@ class Parser {
self::$debugCount++,
ltrim($methodTree, '->'),
self::$instance->data->position,
self::$instance->data->peek()
var_export(self::$instance->data->peek(), true)
);
}
protected static function debugResult($result) {
printf("%s Result: %s\n",
debug_backtrace()[1]['function'],
var_export($result, true));
}
protected static function fail(string $expected) {
self::$instance->lastExceptionData = [
'expected' => $expected,

Loading…
Cancel
Save