Browse Source

Started injections, broken lol

main
Dustin Wilson 3 years ago
parent
commit
5027113596
  1. 6
      lib/Scope/Path.php
  2. 12
      lib/Scope/Selector.php
  3. 47
      lib/Tokenizer.php

6
lib/Scope/Path.php

@ -34,6 +34,12 @@ class Path extends Node {
$index = 0; $index = 0;
$cur = $this->_scopes[$index]; $cur = $this->_scopes[$index];
foreach ($scopes as $s) { foreach ($scopes as $s) {
if (is_string($s)) {
$s = Parser::parseScope($s);
} elseif (!$s instanceof Scope) {
throw new \Exception('Argument $scopes must be an array of strings or instances of '. __NAMESPACE__. "\\Scope.\n");
}
if ($cur->matches($s)) { if ($cur->matches($s)) {
$cur = $this->_scopes[++$index] ?? null; $cur = $this->_scopes[++$index] ?? null;
} }

12
lib/Scope/Selector.php

@ -16,23 +16,11 @@ class Selector extends Node {
public function getPrefix(array $scopes): ?int { public function getPrefix(array $scopes): ?int {
foreach ($scopes as $s) {
if (!$s instanceof Scope) {
throw new \Exception("Argument \$scopes must be an array of Scope instances.\n");
}
}
$matches = $this->matches($scopes, $match); $matches = $this->matches($scopes, $match);
return ($matches) ? $match->getPrefix($scopes) : null; return ($matches) ? $match->getPrefix($scopes) : null;
} }
public function matches(array $scopes, ?Composite &$match = null): bool { public function matches(array $scopes, ?Composite &$match = null): bool {
foreach ($scopes as $s) {
if (!$s instanceof Scope) {
throw new \Exception("Argument \$scopes must be an array of Scope instances.\n");
}
}
foreach ($this->_composites as $composite) { foreach ($this->_composites as $composite) {
if ($composite->matches($scopes)) { if ($composite->matches($scopes)) {
$match = $composite; $match = $composite;

47
lib/Tokenizer.php

@ -5,17 +5,21 @@
declare(strict_types=1); declare(strict_types=1);
namespace dW\Lit; namespace dW\Lit;
use dW\Lit\Scope\Parser as ScopeParser;
use dW\Lit\Grammar\{ use dW\Lit\Grammar\{
Pattern, Pattern,
Reference Reference
}; };
use dW\Lit\Scope\{
Filter,
Parser as ScopeParser
};
class Tokenizer { class Tokenizer {
protected \Generator $data; protected \Generator $data;
protected Grammar $grammar; protected Grammar $grammar;
protected int $offset = 0; protected int $offset = 0;
protected ?Pattern $activeInjection = null;
protected array $ruleStack; protected array $ruleStack;
protected array $scopeStack; protected array $scopeStack;
protected $debug = false; protected $debug = false;
@ -65,14 +69,31 @@ class Tokenizer {
protected function tokenizeLine(string $line): array { protected function tokenizeLine(string $line): array {
$tokens = []; $tokens = [];
$lineLength = strlen($line);
if ($this->activeInjection === null && $this->grammar->injections !== null) {
foreach ($this->grammar->injections as $selector => $injection) {
$selector = ScopeParser::parseSelector($selector);
if ($selector->matches($this->scopeStack)) {
$prefix = $selector->getPrefix($this->scopeStack);
if ($prefix === Filter::PREFIX_LEFT || $prefix === Filter::PREFIX_BOTH) {
$this->scopeStack[] = $injection;
$this->activeInjection = $injection;
break;
}
}
}
}
while (true) { while (true) {
$currentRules = end($this->ruleStack)->patterns; $currentRules = end($this->ruleStack)->patterns;
$currentRulesCount = count($currentRules); $currentRulesCount = count($currentRules);
for ($i = 0; $i < $currentRulesCount; $i++) { for ($i = 0; $i < $currentRulesCount; $i++) {
while (true) { while (true) {
$rule = $currentRules[$i]; $rule = $currentRules[$i];
// If the rule is a Pattern and matches the line at the offset then tokenize the // If the rule is a Pattern and matches the line at the offset then tokenize the
// matches. // matches.
if ($rule instanceof Pattern && preg_match($rule->match, $line, $match, PREG_OFFSET_CAPTURE, $this->offset)) { if ($rule instanceof Pattern && preg_match($rule->match, $line, $match, PREG_OFFSET_CAPTURE, $this->offset)) {
@ -200,7 +221,12 @@ class Tokenizer {
} }
// And remove the rule from the rule stack, too. // And remove the rule from the rule stack, too.
array_pop($this->ruleStack); $popped = array_pop($this->ruleStack);
// If what was just popped is the active injection then remove it, too.
if ($popped === $this->activeInjection) {
$this->activeInjection = null;
}
break 2; break 2;
} }
// Otherwise, if the rule is a Reference then retrieve its patterns, splice into // Otherwise, if the rule is a Reference then retrieve its patterns, splice into
@ -219,6 +245,23 @@ class Tokenizer {
} }
} }
if ($this->activeInjection === null && $this->grammar->injections !== null) {
foreach ($this->grammar->injections as $selector => $injection) {
$selector = ScopeParser::parseSelector($selector);
if ($selector->matches($this->scopeStack)) {
$prefix = $selector->getPrefix($this->scopeStack);
if ($prefix !== Filter::PREFIX_LEFT) {
$this->ruleStack[] = $injection;
$this->activeInjection = $injection;
if ($this->offset < $lineLength) {
continue 2;
}
}
}
}
}
break; break;
} }

Loading…
Cancel
Save