diff --git a/lib/Scope/Exception.php b/lib/Scope/Exception.php index 41d7f36..930b1cb 100644 --- a/lib/Scope/Exception.php +++ b/lib/Scope/Exception.php @@ -9,23 +9,25 @@ namespace dW\Highlighter\Scope; class Exception extends \Exception { const MESSAGE = '%s expected; found %s'; - public function __construct(string $expected, string|bool $found) { - $strlen = strlen($expected); - if ($strlen > 1) { - $temp = []; - for ($i = 0; $i < $strlen; $i++) { - $temp[] = ($expected[$i] !== false) ? "\"{$expected[$i]}\"" : 'end of input'; - } - $expected = $temp; - - if (count($expected) > 2) { - $last = array_pop($expected); - $expected = implode(', ', $expected) . ', or ' . $last; + public function __construct(array|string $expected, string|bool $found) { + if (!is_string($expected)) { + $expectedLen = count($expected); + if ($expectedLen === 1) { + $expected = ($expected[0] !== false) ? $expected[0] : 'end of input'; } else { - $expected = implode(' or ', $expected); + $temp = []; + for ($i = 0; $i < $strlen; $i++) { + $temp[] = ($expected[$i] !== false) ? "{$expected[$i]}" : 'end of input'; + } + $expected = $temp; + + if ($expectedLen > 2) { + $last = array_pop($expected); + $expected = implode(', ', $expected) . ', or ' . $last; + } else { + $expected = implode(' or ', $expected); + } } - } else { - $expected = ($expected !== false) ? "\"$expected\"" : 'end of input'; } $found = ($found !== false) ? "\"$found\"" : 'end of input'; diff --git a/lib/Scope/Matchers/GroupMatcher.php b/lib/Scope/Matchers/GroupMatcher.php index f7a9105..5e28e83 100644 --- a/lib/Scope/Matchers/GroupMatcher.php +++ b/lib/Scope/Matchers/GroupMatcher.php @@ -10,8 +10,8 @@ class GroupMatcher extends Matcher { protected string|null $prefix; protected Matcher $selector; - public function __construct(string $prefix, Matcher $selector) { - $this->prefix = $prefix[0]; + public function __construct(string|null $prefix, Matcher $selector) { + $this->prefix = ($prefix !== null) ? $prefix[0] : null; $this->selector = $selector; } diff --git a/lib/Scope/Matchers/PathMatcher.php b/lib/Scope/Matchers/PathMatcher.php index a72231a..7f6763b 100644 --- a/lib/Scope/Matchers/PathMatcher.php +++ b/lib/Scope/Matchers/PathMatcher.php @@ -10,8 +10,8 @@ class PathMatcher extends Matcher { protected string|null $prefix; protected array $matchers; - public function __construct(string $prefix, ScopeMatcher ...$matchers) { - $this->prefix = $prefix[0]; + public function __construct(string|null $prefix, ScopeMatcher ...$matchers) { + $this->prefix = ($prefix !== null) ? $prefix[0] : null; $this->matchers = $matchers; } diff --git a/lib/Scope/Parser.php b/lib/Scope/Parser.php index 2e393b7..c75c26d 100644 --- a/lib/Scope/Parser.php +++ b/lib/Scope/Parser.php @@ -86,10 +86,8 @@ class Parser { $result = self::parseGroup($prefix); } elseif (preg_match(self::SCOPE_REGEX, $peek)) { $result = self::parsePath($prefix); - } elseif ($peek !== false) { - die('Group or path expected.'); } else { - die('Unexpected eod'); + throw new Exception([ 'Instance of ' . __NAMESPACE__ . 'GroupMatcher', 'Instance of ' . __NAMESPACE__ . 'PathMatcher' ], $peek); } if (self::$debug) { @@ -107,7 +105,7 @@ class Parser { $result = self::parseSelector(); $token = self::$instance->data->consume(); if ($token !== ')') { - die(($token !== false) ? 'Close parenthesis expected' : 'Unexpected eod'); + throw new Exception(')', $token); } $result = ($prefix === null) ? $result : new GroupMatcher($prefix, $result); @@ -126,7 +124,6 @@ class Parser { $result = []; $result[] = self::parseScope(); - die(var_export($result)); $peek = self::$instance->data->peek(); while (!in_array($peek, [ '-', false ]) && preg_match(self::SCOPE_REGEX, $peek)) { @@ -173,10 +170,9 @@ class Parser { } $token = self::$instance->data->consume(); - if ($token === false) { - die('Unexpected eod'); - } elseif (!preg_match('/^(?:[A-Za-z0-9-_]+|\*)(?:\.(?:[A-Za-z0-9-+_]+|\*))*$/S', $token)) { - die('Invalid scope'); + if ($token === false || !preg_match('/^(?:[A-Za-z0-9-_]+|\*)(?:\.(?:[A-Za-z0-9-+_]+|\*))*$/S', $token)) { + // TODO: Take the effort to make this more descriptive + throw new Exception('valid scope syntax', $token); } $segments = explode('.', $token);