Browse Source
• Originally I had a concept of a readonly node tree for grammars with nodes owning other nodes thinking it would be necessary when tokenizing. It isn't, so they're more trouble than they're worth. • "ownership" in Grammar\Reference objects is handled by an ownerGrammarScopeName property which is then used to get the grammar from the GrammarRegistry.main
Dustin Wilson
3 years ago
15 changed files with 57 additions and 296 deletions
@ -1,61 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2021 Dustin Wilson et al. |
|
||||
* See LICENSE file for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace dW\Lit\Grammar; |
|
||||
use dW\Lit\Grammar; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Static storage for child grammars; a map of a scope string and a Grammar |
|
||||
* object and checked against an owner grammar. Exists to prevent multiple clones |
|
||||
* of the same grammar from being created and also to give weak references a |
|
||||
* place in memory to access. |
|
||||
*/ |
|
||||
class ChildGrammarRegistry { |
|
||||
protected static array $storage = []; |
|
||||
|
|
||||
public static function clear(): bool { |
|
||||
self::$storage = []; |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
public static function get(string $scopeName, Grammar $ownerGrammar): ?Grammar { |
|
||||
if (!array_key_exists($scopeName, self::$storage)) { |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
$grammars = self::$storage[$scopeName]; |
|
||||
foreach ($grammars as $g) { |
|
||||
if ($g->ownerGrammar === $ownerGrammar) { |
|
||||
return $g; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
public static function set(string $scopeName, Grammar $grammar): bool { |
|
||||
try { |
|
||||
if (!array_key_exists($scopeName, self::$storage)) { |
|
||||
self::$storage[$scopeName] = [ $grammar ]; |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
$grammars = self::$storage[$scopeName]; |
|
||||
foreach ($grammars as $key => $value) { |
|
||||
if ($value->ownerGrammar === $grammar->ownerGrammar) { |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
self::$storage[$scopeName][] = $grammar; |
|
||||
} catch (\Exception $e) { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
} |
|
@ -1,26 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2021 Dustin Wilson et al. |
|
||||
* See LICENSE file for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace dW\Lit\Grammar; |
|
||||
|
|
||||
|
|
||||
trait FauxReadOnly { |
|
||||
public function __get(string $name) { |
|
||||
$prop = "_$name"; |
|
||||
$exists = property_exists($this, $prop); |
|
||||
if ($name === 'ownerGrammar' && $exists) { |
|
||||
return $this->_ownerGrammar->get(); |
|
||||
} |
|
||||
|
|
||||
if (!$exists) { |
|
||||
$trace = debug_backtrace(); |
|
||||
trigger_error("Cannot get undefined property $name in {$trace[0]['file']} on line {$trace[0]['line']}", E_USER_NOTICE); |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
return $this->$prop; |
|
||||
} |
|
||||
} |
|
@ -1,33 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2021 Dustin Wilson et al. |
|
||||
* See LICENSE file for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace dW\Lit\Grammar; |
|
||||
use dW\Lit\FauxReadOnly; |
|
||||
|
|
||||
/** Immutable named pattern list used for repositories and injection lists. */ |
|
||||
abstract class NamedPatternList extends ImmutableList { |
|
||||
use FauxReadOnly; |
|
||||
|
|
||||
public function __construct(array $array) { |
|
||||
// This shit is here because PHP doesn't have array types or generics :) |
|
||||
foreach ($array as $k => $v) { |
|
||||
if (!is_string($k)) { |
|
||||
throw new Exception(Exception::LIST_INVALID_TYPE, 'String', 'supplied array index', gettype($k)); |
|
||||
} |
|
||||
|
|
||||
if (!$v instanceof Pattern && !$v instanceof PatternList && !$v instanceof Reference) { |
|
||||
$type = gettype($v); |
|
||||
if ($type === 'object') { |
|
||||
$type = get_class($v); |
|
||||
} |
|
||||
|
|
||||
throw new Exception(Exception::LIST_INVALID_TYPE, __NAMESPACE__.'\Pattern, '.__NAMESPACE__.'\PatternList, '.__NAMESPACE__.'\Reference', 'supplied array value', $type); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
$this->storage = $array; |
|
||||
} |
|
||||
} |
|
@ -1,16 +0,0 @@ |
|||||
<?php |
|
||||
/** @license MIT |
|
||||
* Copyright 2021 Dustin Wilson et al. |
|
||||
* See LICENSE file for details */ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace dW\Lit\Grammar; |
|
||||
use dW\Lit\Grammar; |
|
||||
|
|
||||
|
|
||||
/** Immutable list of pattern rules */ |
|
||||
class PatternList extends ImmutableList { |
|
||||
public function __construct(Pattern|Reference|\WeakReference ...$values) { |
|
||||
parent::__construct(...$values); |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue