Browse Source

Added documentation to Scope/Data and Scope/Parser

main
Dustin Wilson 3 years ago
parent
commit
b039ced5f9
  1. 41
      lib/Grammar/Registry.php
  2. 7
      lib/Scope/Data.php
  3. 22
      lib/Scope/Parser.php

41
lib/Grammar/Registry.php

@ -9,13 +9,34 @@ namespace dW\Highlighter\Grammar;
class Registry {
protected static array $grammars = [];
public static function add(string $grammarPath): bool {
if (!file_exists($grammarPath)) {
throw new \Exception("Path \"$grammarPath\" either does not exist or you do not have permission to view the file.");
public static function clear(): bool {
self::$grammars = [];
return true;
}
public static function delete(string $scopeName): bool {
try {
unset(self::$grammars[$scopeName]);
} catch (Exception $e) {
return false;
}
return true;
}
public static function get(string $scopeName): array|bool {
foreach (self::$grammars as $grammar) {
if ($grammar['scopeName'] === $scopeName) {
return $grammar;
}
}
if (isset(self::$grammars[$grammarPath])) {
return true;
return false;
}
public static function set(string $grammarPath, bool $force = false): bool {
if (!file_exists($grammarPath)) {
throw new \Exception("Path \"$grammarPath\" either does not exist or you do not have permission to view the file.");
}
$grammar = json_decode(file_get_contents($grammarPath), true);
@ -23,7 +44,15 @@ class Registry {
throw new \Exception("\"$grammarPath\" is not a valid grammar file.");
}
self::$grammars[$grammarPath] = $grammar;
if (!isset($grammar['scopeName'])) {
throw new \Exception("\"$grammarPath\" is missing the required scopeName property.");
}
if (!$force && isset(self::$grammars[$grammar['scopeName']])) {
throw new \Exception("Grammar \"{$grammar['scopeName']}\" already exists.");
}
self::$grammars[$grammar['scopeName']] = $grammar;
return true;
}
}

7
lib/Scope/Data.php

@ -6,6 +6,10 @@
declare(strict_types=1);
namespace dW\Highlighter\Scope;
/**
* Tokenizes scope strings into an array of segments of the original string and
* provides an interface for iterating through them.
*/
class Data {
protected array $data;
@ -18,6 +22,7 @@ class Data {
$this->endPosition = count($this->data) - 1;
}
/** Moves the pointer up one position and returns the corresponding token */
public function consume(): string|bool {
if ($this->_position === $this->endPosition) {
return false;
@ -26,6 +31,7 @@ class Data {
return $this->data[++$this->_position][0];
}
/** Returns the character offset of the current token */
public function offset(): int|bool {
if ($this->_position > $this->endPosition) {
return false;
@ -34,6 +40,7 @@ class Data {
return $this->data[$this->_position][1];
}
/** Returns the next token without moving the pointer */
public function peek(): string|bool {
if ($this->_position === $this->endPosition) {
return false;

22
lib/Scope/Parser.php

@ -6,20 +6,33 @@
declare(strict_types=1);
namespace dW\Highlighter\Scope;
/** Parses scope strings into a matcher tree */
class Parser {
// When true prints out detailed data about the construction of the matcher
// tree.
public static bool $debug = false;
// The tokenized scope string
protected Data $data;
// Used for incrementing the blocks of debug information; useful for creating
// breakpoints when debugging.
protected int $debugCount = 1;
// Used for instancing data tokens in static methods.
protected static Parser $instance;
// strspn mask used to check whether a token could be a valid scope.
protected const SCOPE_MASK = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_.*';
protected function __construct(string $selector) {
$this->data = new Data($selector);
}
/**
* Static method entry point for the class. Creates the instance and parses the
* string.
*/
public static function parse(string $selector): Matcher|false {
self::$instance = new self($selector);
return self::parseSelector();
@ -76,11 +89,12 @@ class Parser {
if ($peek === '(') {
self::$instance->data->consume();
$result = self::parseGroup($prefix);
} elseif (strspn($peek, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_.*') === strlen($peek)) {
} elseif (!in_array($peek, [ '-', false ]) && strspn($peek, self::SCOPE_MASK) === strlen($peek)) {
$result = self::parsePath($prefix);
} else {
if (!in_array($peek, [ '-', false ]) && )
// TODO: Take the effort to make this more descriptive
self::throw([ 'Group', 'Path' ], $peek);
self::throw([ 'Group', 'Path', 'Scope' ], $peek);
}
if (self::$debug) {
@ -119,7 +133,7 @@ class Parser {
$result[] = self::parseScope();
$peek = self::$instance->data->peek();
while (!in_array($peek, [ '-', false ]) && strspn($peek, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_.*') === strlen($peek)) {
while (!in_array($peek, [ '-', false ]) && strspn($peek, self::SCOPE_MASK) === strlen($peek)) {
$result[] = self::parseScope();
$peek = self::$instance->data->peek();
}

Loading…
Cancel
Save