Browse Source

Starting to add scope exception handling

main
Dustin Wilson 3 years ago
parent
commit
147b4c4ceb
  1. 255
      lib/Scope/Parser.php

255
lib/Scope/Parser.php

@ -8,32 +8,45 @@ namespace dW\Highlighter\Scope;
class Parser { class Parser {
protected Data $data; protected Data $data;
protected array $lastExceptionData = [];
protected static Parser $instance; protected static Parser $instance;
protected function __construct(string $selector) { protected function __construct(string $selector) {
$this->data = new Data($selector); $this->data = new Data($selector);
} }
public static function parse(string $selector): Matcher|bool { public static function parse(string $selector): Matcher|false {
self::$instance = new self($selector); self::$instance = new self($selector);
$output = false; $result = false;
$s1 = self::parseSpace(); $s1 = self::parseSpace();
if ($s1 !== false) { if ($s1 !== false) {
$s2 = self::parseSelector(); $s2 = self::parseSelector();
if ($s2 !== false) { if ($s2 !== false) {
$s3 = self::parseSpace(); $s3 = self::parseSpace();
if ($s3 !== false) { if ($s3 !== false) {
$output = $s2; $result = $s2;
} }
} }
} }
return $output; if (self::$instance->lastExceptionData !== []) {
throw new Exception(self::$instance->lastExceptionData['expected'], self::$instance->lastExceptionData['found']);
}
return $result;
} }
protected static function parseComposite(): Matcher|bool { protected static function fail(array|string $expected) {
$output = false; self::$instance->lastExceptionData = [
'expected' => $expected,
'found' => self::$instance->data->peek()
];
}
protected static function parseComposite(): Matcher|false {
$result = false;
$s1 = self::parseExpression(); $s1 = self::parseExpression();
if ($s1 !== false) { if ($s1 !== false) {
@ -41,31 +54,31 @@ class Parser {
if ($s2 !== false) { if ($s2 !== false) {
$s3 = self::$instance->data->consumeIf('|&-'); $s3 = self::$instance->data->consumeIf('|&-');
if (!in_array($s3, [ '|', '&', '-' ])) { if (!in_array($s3, [ '|', '&', '-' ])) {
throw new Exception([ '|', '&', '-' ], self::$instance->data->peek()); self::fail([ '|', '&', '-' ]);
} } else {
$s4 = self::parseSpace();
$s4 = self::parseSpace(); if ($s4 !== false) {
if ($s4 !== false) { $s5 = self::parseComposite();
$s5 = self::parseComposite(); if ($s5 !== false) {
if ($s5 !== false) { $result = new Matcher\CompositeMatcher($s1, $s3, $s5);
$output = new Matcher\CompositeMatcher($s1, $s3, $s5); }
} }
} }
} }
} }
if ($output === false) { if ($result === false) {
$output = self::parseExpression(); $result = self::parseExpression();
} }
return $output; return $result;
} }
protected static function parseExpression(): Matcher|bool { protected static function parseExpression(): Matcher|false {
$output = false; $result = false;
$s1 = self::$instance->data->consumeIf('-'); $s1 = self::$instance->data->consumeIf('-');
if ($s1 !== '-') { if ($s1 !== '-') {
throw new Exception('-', self::$instance->data->peek()); self::fail('-');
} }
$s2 = self::parseSpace(); $s2 = self::parseSpace();
@ -74,157 +87,157 @@ class Parser {
if ($s3 !== false) { if ($s3 !== false) {
$s4 = self::parseSpace(); $s4 = self::parseSpace();
if ($s4 !== false) { if ($s4 !== false) {
$output = new Matcher\NegateMatcher($s3); $result = new Matcher\NegateMatcher($s3);
} }
} }
} }
if ($output === false) { if ($result === false) {
$s1 = self::$instance->data->consumeIf('-', 1); $s1 = self::$instance->data->consumeIf('-', 1);
if ($s1 !== '-') { if ($s1 !== '-') {
throw new Exception('-', self::$instance->data->peek()); self::fail('-');
} } else {
$s2 = self::parseSpace();
$s2 = self::parseSpace(); if ($s2 !== false) {
if ($s2 !== false) { $s3 = self::parsePath();
$s3 = self::parsePath(); if ($s3 !== false) {
if ($s3 !== false) { $s4 = self::parseSpace();
$s4 = self::parseSpace(); if ($s4 !== false) {
if ($s4 !== false) { $result = new Matcher\NegateMatcher($s3);
$output = new Matcher\NegateMatcher($s3); }
} }
} }
} }
} }
if ($output === false) { if ($result === false) {
$output = self::parseGroup(); $result = self::parseGroup();
if ($output === false) { if ($result === false) {
$output = self::parsePath(); $result = self::parsePath();
} }
} }
return $output; return $result;
} }
protected static function parseGroup(): Matcher|bool { protected static function parseGroup(): Matcher|false {
$output = false; $result = false;
$s2 = self::$instance->data->consumeIf('BLR'); $s2 = self::$instance->data->consumeIf('BLR');
if (!in_array($s2, [ 'B', 'L', 'R' ])) { if (!in_array($s2, [ 'B', 'L', 'R' ])) {
throw new Exception([ 'B', 'L', 'R' ], self::$instance->data->peek()); self::fail([ 'B', 'L', 'R' ]);
} } else {
$s3 = self::$instance->data->consumeIf(':');
$s3 = self::$instance->data->consumeIf(':'); if ($s3 !== ':') {
if ($s3 !== ':') { self::fail(':');
throw new Exception(':', self::$instance->data->peek()); } else {
} $prefix = "$s2$s3";
$prefix = "$s2$s3"; $s2 = self::$instance->data->consumeIf('(');
if ($s2 !== '(') {
$s2 = self::$instance->data->consumeIf('('); self::fail('(');
if ($s2 !== '(') { } else {
throw new Exception('(', self::$instance->data->peek()); $s3 = self::parseSpace();
} if ($s3 !== false) {
$s4 = self::parseSelector();
$s3 = self::parseSpace(); if ($s4 !== false) {
if ($s3 !== false) { $s5 = self::parseSpace();
$s4 = self::parseSelector(); if ($s5 !== false) {
if ($s4 !== false) { $s6 = self::$instance->data->consumeIf(')');
$s5 = self::parseSpace(); if ($s6 !== ')') {
if ($s5 !== false) { self::fail(')');
$s6 = self::$instance->data->consumeIf(')'); } else {
if ($s6 !== ')') { $result = new GroupMatcher($prefix, $s4);
throw new Exception(')', self::$instance->data->peek()); }
}
}
} }
$output = new GroupMatcher($prefix, $s4);
} }
} }
} }
return $output; return $result;
} }
protected static function parsePath(): Matcher|bool { protected static function parsePath(): Matcher|false {
$output = false; $result = false;
$s2 = self::$instance->data->consumeIf('BLR'); $s2 = self::$instance->data->consumeIf('BLR');
if (!in_array($s2, [ 'B', 'L', 'R' ])) { if (!in_array($s2, [ 'B', 'L', 'R' ])) {
throw new Exception([ 'B', 'L', 'R' ], self::$instance->data->peek()); self::fail([ 'B', 'L', 'R' ]);
} } else {
$s3 = self::$instance->data->consumeIf(':');
$s3 = self::$instance->data->consumeIf(':'); if ($s3 !== ':') {
if ($s3 !== ':') { self::fail(':');
throw new Exception(':', self::$instance->data->peek()); } else {
} $prefix = "$s2$s3";
$prefix = "$s2$s3"; $s2 = self::parseScope();
if ($s2 !== false) {
$s2 = self::parseScope(); $s3 = '';
if ($s2 !== false) { $s4 = '';
$s3 = '';
$s4 = ''; while ($s4 !== false) {
$s3 .= $s4;
while ($s4 !== false) { $s4 = false;
$s3 .= $s4;
$s4 = false; $s5 = self::parseSpace();
if ($s5 !== false) {
$s6 = self::parseScope();
if ($s6 !== false) {
$s4 = "$s5$s6";
}
}
}
$s5 = self::parseSpace(); if (strlen($s3) > 0) {
if ($s5 !== false) { $result = new Matcher\PathMatcher($prefix, $s2, $s3);
$s6 = self::parseScope();
if ($s6 !== false) {
$s4 = "$s5$s6";
} }
} }
} }
if (strlen($s3) > 0) {
$output = new Matcher\PathMatcher($prefix, $s2, $s3);
}
} }
return $output; return $result;
} }
protected static function parseSpace(): string|bool { protected static function parseSpace(): string|false {
return self::$instance->data->consumeIf(" \t"); return self::$instance->data->consumeIf(" \t");
} }
protected static function parseSegment(): string|bool { protected static function parseSegment(): string|false {
return false; return false;
} }
protected static function parseSelector(): Matcher|bool { protected static function parseSelector(): Matcher|false {
$output = false; $result = false;
$s1 = self::parseComposite(); $s1 = self::parseComposite();
if ($s1 !== false) { if ($s1 !== false) {
$s2 = self::parseSpace(); $s2 = self::parseSpace();
if ($s2 !== false) { if ($s2 !== false) {
$s3 = self::$instance->data->consumeIf(','); $s3 = self::$instance->data->consumeIf(',');
if ($s3 !== ',') { if ($s3 !== ',') {
throw new Exception(',', self::$instance->data->peek()); self::fail(',');
} } else {
$s4 = self::parseSpace();
$s4 = self::parseSpace(); if ($s4 !== false) {
if ($s4 !== false) { $s5 = self::parseSelector();
$s5 = self::parseSelector(); if ($s5 !== false) {
if ($s5 !== false) { $result = new Matcher\OrMatcher($s1, $s5);
$output = new Matcher\OrMatcher($s1, $s5); }
} }
} }
} }
} }
if ($output === false) { if ($result === false) {
$output = self::parseComposite(); $result = self::parseComposite();
} }
return $output; return $result;
} }
protected static function parseScope(): string|bool { protected static function parseScope(): string|false {
$output = false; $result = false;
$s1 = self::parseSegment(); $s1 = self::parseSegment();
if ($s1 !== false) { if ($s1 !== false) {
@ -237,20 +250,20 @@ class Parser {
$s4 = self::$instance->data->consumeIf('.'); $s4 = self::$instance->data->consumeIf('.');
if ($s4 !== '.') { if ($s4 !== '.') {
throw new Exception('.', self::$instance->data->peek()); self::fail('.');
} } else {
$s5 = self::parseSegment();
$s5 = self::parseSegment(); if ($s5 !== false) {
if ($s5 !== false) { $s3 = "$s4$s5";
$s3 = "$s4$s5"; }
} }
} }
if (strlen($s2) > 0) { if (strlen($s2) > 0) {
$output = new Matcher\ScopeMatcher($s1, $s2); $result = new Matcher\ScopeMatcher($s1, $s2);
} }
} }
return $output; return $result;
} }
} }

Loading…
Cancel
Save