Browse Source

Scope parsing improvements

main
Dustin Wilson 3 years ago
parent
commit
3e939feadf
  1. 2
      lib/Scope/Data.php
  2. 33
      lib/Scope/Matchers/CompositeMatcher.php
  3. 4
      lib/Scope/Matchers/GroupMatcher.php
  4. 4
      lib/Scope/Matchers/PathMatcher.php
  5. 23
      lib/Scope/Parser.php

2
lib/Scope/Data.php

@ -15,7 +15,7 @@ class Data {
public function __construct(string $data) { public function __construct(string $data) {
preg_match_all('/[BLR]:|[A-Za-z0-9-+_\*\.]+|[\,\|\-\(\)&]/', $data, $matches); preg_match_all('/[BLR]:|[A-Za-z0-9-+_\*\.]+|[\,\|\-\(\)&]/', $data, $matches);
$this->data = $matches[0] ?? []; $this->data = $matches[0] ?? [];
$this->endPosition = count($this->data); $this->endPosition = count($this->data) - 1;
} }
public function consume(): string|bool { public function consume(): string|bool {

33
lib/Scope/Matchers/CompositeMatcher.php

@ -1,33 +0,0 @@
<?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 CompositeMatcher extends Matcher {
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;
}
}
public function matches(string ...$scopes): bool {
return $this->matcher->matches(...$scopes);
}
public function getPrefix(string ...$scopes): string|null|false {
return $this->matcher->getPrefix(...$scopes);
}
}

4
lib/Scope/Matchers/GroupMatcher.php

@ -10,8 +10,8 @@ class GroupMatcher extends Matcher {
protected string|null $prefix; protected string|null $prefix;
protected Matcher $selector; protected Matcher $selector;
public function __construct(string|null $prefix, Matcher $selector) { public function __construct(string $prefix, Matcher $selector) {
$this->prefix = ($prefix !== null) ? $prefix[0] : null; $this->prefix = $prefix[0];
$this->selector = $selector; $this->selector = $selector;
} }

4
lib/Scope/Matchers/PathMatcher.php

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

23
lib/Scope/Parser.php

@ -86,8 +86,10 @@ class Parser {
$result = self::parseGroup($prefix); $result = self::parseGroup($prefix);
} elseif (preg_match(self::SCOPE_REGEX, $peek)) { } elseif (preg_match(self::SCOPE_REGEX, $peek)) {
$result = self::parsePath($prefix); $result = self::parsePath($prefix);
} else { } elseif ($peek !== false) {
die('Group or path expected.'); die('Group or path expected.');
} else {
die('Unexpected eod');
} }
if (self::$debug) { if (self::$debug) {
@ -103,8 +105,9 @@ class Parser {
} }
$result = self::parseSelector(); $result = self::parseSelector();
if (self::$instance->data->consume() !== ')') { $token = self::$instance->data->consume();
die('Close parenthesis expected'); if ($token !== ')') {
die(($token !== false) ? 'Close parenthesis expected' : 'Unexpected eod');
} }
$result = ($prefix === null) ? $result : new GroupMatcher($prefix, $result); $result = ($prefix === null) ? $result : new GroupMatcher($prefix, $result);
@ -116,17 +119,17 @@ class Parser {
return $result; return $result;
} }
protected static function parsePath(string|null $prefix = null): Matcher { protected static function parsePath(string|null $prefix = null): PathMatcher|ScopeMatcher {
if (self::$debug) { if (self::$debug) {
self::debug(); self::debug();
} }
$result = []; $result = [];
$result[] = self::parseScope(); $result[] = self::parseScope();
die(var_export($result));
$peek = self::$instance->data->peek(); $peek = self::$instance->data->peek();
while ($peek != '-' && preg_match(self::SCOPE_REGEX, $peek)) { while (!in_array($peek, [ '-', false ]) && preg_match(self::SCOPE_REGEX, $peek)) {
self::$instance->data->consume();
$result[] = self::parseScope(); $result[] = self::parseScope();
$peek = self::$instance->data->peek(); $peek = self::$instance->data->peek();
} }
@ -164,13 +167,15 @@ class Parser {
return $result; return $result;
} }
protected static function parseScope(): Matcher { protected static function parseScope(): ScopeMatcher {
if (self::$debug) { if (self::$debug) {
self::debug(); self::debug();
} }
$token = self::$instance->data->consume(); $token = self::$instance->data->consume();
if (!preg_match('/^(?:[A-Za-z0-9-_]+|\*)(?:\.(?:[A-Za-z0-9-+_]+|\*))*$/S', $token)) { if ($token === false) {
die('Unexpected eod');
} elseif (!preg_match('/^(?:[A-Za-z0-9-_]+|\*)(?:\.(?:[A-Za-z0-9-+_]+|\*))*$/S', $token)) {
die('Invalid scope'); die('Invalid scope');
} }
@ -217,6 +222,6 @@ class Parser {
protected static function debugResult($result) { protected static function debugResult($result) {
printf("%s Result: %s\n", printf("%s Result: %s\n",
debug_backtrace()[1]['function'], debug_backtrace()[1]['function'],
var_export($result, true)); str_replace([ '::__set_state(array', __NAMESPACE__ ], '', var_export($result, true)));
} }
} }

Loading…
Cancel
Save