Browse Source

Working on Grammars

main
Dustin Wilson 3 years ago
parent
commit
e2cc9adbd8
  1. 7
      lib/Data.php
  2. 18
      lib/FauxReadOnly.php
  3. 92
      lib/Grammar.php
  4. 37
      lib/Grammar/ImmutableList.php
  5. 32
      lib/Grammar/Include.php
  6. 9
      lib/Grammar/InjectionList.php
  7. 18
      lib/Grammar/NamedPatternListList.php
  8. 38
      lib/Grammar/Pattern.php
  9. 13
      lib/Grammar/PatternList.php
  10. 4
      lib/Grammar/Registry.php
  11. 9
      lib/Grammar/Repository.php
  12. 14
      lib/Tokenizer.php

7
lib/Data.php

@ -8,10 +8,11 @@ namespace dW\Lit;
class Data {
public static function fileToGenerator(string $filepath): \Generator {
$lineNumber = 0;
$fp = fopen($filepath, 'r');
try {
while ($line = fgets($fp)) {
yield $line;
yield ++$lineNumber => $line;
}
} finally {
fclose($fp);
@ -20,8 +21,8 @@ class Data {
public static function stringToGenerator(string $string): \Generator {
$string = explode("\n", $string);
foreach ($string as $s) {
yield $s;
foreach ($string as $lineNumber => $line) {
yield $lineNumber + 1 => $line;
}
}
}

18
lib/FauxReadOnly.php

@ -0,0 +1,18 @@
<?php
/** @license MIT
* Copyright 2021 Dustin Wilson et al.
* See LICENSE file for details */
declare(strict_types=1);
namespace dW\Lit;
trait FauxReadOnly {
public function __get(string $name) {
if ($name[0] !== '_') {
return;
}
$name = substr($name, 1);
return $this->$name;
}
}

92
lib/Grammar.php

@ -0,0 +1,92 @@
<?php
/** @license MIT
* Copyright 2021 Dustin Wilson et al.
* See LICENSE file for details */
declare(strict_types=1);
namespace dW\Lit;
use dW\Lit\Grammar\InjectionList,
dW\Lit\Grammar\PatternList,
dW\Lit\Grammar\Repository;
class Grammar {
use FauxReadOnly;
protected string|null $_contentRegex;
protected string|null $_firstLineMatch;
protected InjectionList|null $_injections;
protected string $_name;
protected PatternList $_patterns;
protected Repository|null $_repository;
protected string $_scopeName;
public function __construct(string $name, string $scopeName, PatternList $patterns, string|null $contentRegex = null, string|null $firstLineMatch = null, InjectionList|null $injections = null, Repository|null $repository = null) {
$this->_name = $name;
$this->_scopeName = $scopeName;
$this->_patterns = $patterns;
$this->_contentRegex = $contentRegex;
$this->_firstLineMatch = $firstLineMatch;
$this->_injections = $injections;
$this->_repository = $repository;
}
public static function fromJSON(string $jsonPath): self {
assert(is_file($jsonPath), new \Exception("\"$jsonPath\" is either not a file or you do not have permission to read the file\n"));
$json = json_decode($jsonPath, true);
assert($json, new \Exception("\"$jsonPath\" is not a valid JSON file.\n"));
assert(isset($json['name']), new \Exception("\"$jsonPath\" does not have the required name property"));
assert(isset($json['scopeName']), new \Exception("\"$jsonPath\" does not have the required scopeName property"));
assert(isset($json['patterns']), new \Exception("\"$jsonPath\" does not have the required patterns property"));
$name = $json['name'];
$scopeName = $json['scopeName'];
$contentRegex = (isset($json['contentRegex'])) ? "/{$json['contentRegex']}/" : null;
$firstLineMatch = (isset($json['firstLineMatch'])) ? "/{$json['firstLineMatch']}/" : null;
$patterns = [];
foreach ($json['patterns'] as $pattern) {
foreach ($pattern as $key => $p) {
}
}
if (count($patterns) > 0) {
$patterns = new PatternList(...$patterns);
} else {
$patterns = null;
}
if (isset($json['injections'])) {
$injections = [];
foreach ($json['injections'] as $injection) {
}
if (count($injections) > 0) {
$injections = new InjectionList($injections);
} else {
$patterns = null;
}
}
if (isset($json['repository'])) {
$respository = [];
foreach ($json['repository'] as $r) {
}
if (count($repository) > 0) {
$repository = new InjectionList($repository);
} else {
$repository = null;
}
}
return new self($name, $scopeName, $patterns, $contentRegex, $firstLineMatch, $injections, $repository);
}
}

37
lib/Grammar/ImmutableList.php

@ -0,0 +1,37 @@
<?php
/** @license MIT
* Copyright 2017 , Dustin Wilson, J. King et al.
* See LICENSE and AUTHORS files for details */
declare(strict_types=1);
namespace dW\Lit\Grammar;
abstract class ImmutableList implements \ArrayAccess, \Countable {
protected $storage = [];
protected $count = 0;
public function __construct(...$values) {
$this->storage = $values;
}
public function offsetSet($offset, $value) {
throw new \Exception(__CLASS__ . "s are immutable\n");
}
public function offsetExists($offset) {
return isset($this->storage[$offset]);
}
public function offsetUnset($offset) {
throw new \Exception(__CLASS__ . "s are immutable\n");
}
public function offsetGet($offset) {
assert(isset($this->storage[$offset]), new \Exception("Invalid ImmutableList index at $offset\n"));
return $this->storage[$offset];
}
public function count(): int {
return $this->count;
}
}

32
lib/Grammar/Include.php

@ -0,0 +1,32 @@
<?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;
class Include {
use FauxReadOnly;
const REPOSITORY_TYPE = 0;
const SCOPE_TYPE = 1;
const SELF_TYPE = 2;
protected ?string $name;
protected int $type;
public function __construct(string $string) {
if ($string[0] === '#') {
$this->type = self::REPOSITORY_TYPE;
$this->name = substr($string, 1);
} elseif ($string === '$self') {
$this->type = self::SELF_TYPE;
}
$this->type = self::SCOPE_TYPE;
$this->name = $string;
}
}

9
lib/Grammar/InjectionList.php

@ -0,0 +1,9 @@
<?php
/** @license MIT
* Copyright 2021 Dustin Wilson et al.
* See LICENSE file for details */
declare(strict_types=1);
namespace dW\Lit\Grammar;
class Repository extends NamedPatternListList {}

18
lib/Grammar/NamedPatternListList.php

@ -0,0 +1,18 @@
<?php
/** @license MIT
* Copyright 2021 Dustin Wilson et al.
* See LICENSE file for details */
declare(strict_types=1);
namespace dW\Lit\Grammar;
abstract class NamedPatternListList extends ImmutableList {
public function __construct(array $array) {
foreach ($array as $k => $v) {
assert(is_string($k), new \Exception('String index expected for supplied array, found ' . gettype($k) . "\n"));
assert($v instanceof PatternList, new \Exception(__NAMESPACE__ . '\PatternList value expected for supplied array, found ' . gettype($v) . "\n"));
}
$this->storage = $array;
}
}

38
lib/Grammar/Pattern.php

@ -0,0 +1,38 @@
<?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;
use dW\Lit\Grammar;
class Pattern {
use FauxReadOnly;
protected bool $_applyEndPatternLast = false;
protected ?string $_begin;
protected ?array $_beginCaptures;
protected ?array $_captures;
protected ?string $_contentName;
protected ?string $_end;
protected ?array $_endCaptures;
protected ?string $_match;
protected ?string $_name;
protected ?PatternList $_patterns;
public function __construct(?string $name = null, ?string $contentName = null, ?string $begin = null, ?string $end = null, ?string $match = null, ?PatternList $patterns = null, ?string $include = null, ?array $captures = null, ?array $beginCaptures = null, ?array $endCaptures = null) {
$this->_name = $name;
$this->_contentName = $contentName;
$this->_begin = $begin;
$this->_end = $end;
$this->_match = $match;
$this->_patterns = $patterns;
$this->_captures = $captures;
$this->_beginCaptures = $beginCaptures;
$this->_endCaptures = $endCaptures;
}
}

13
lib/Grammar/PatternList.php

@ -0,0 +1,13 @@
<?php
/** @license MIT
* Copyright 2021 Dustin Wilson et al.
* See LICENSE file for details */
declare(strict_types=1);
namespace dW\Lit\Grammar;
class PatternList extends ImmutableList {
public function __construct(Pattern|Include ...$values) {
parent::__construct($values);
}
}

4
lib/Grammar/Registry.php

@ -17,7 +17,7 @@ class Registry {
public static function delete(string $scopeName): bool {
try {
unset(self::$grammars[$scopeName]);
} catch (Exception $e) {
} catch (\Exception $e) {
return false;
}
@ -34,8 +34,6 @@ class Registry {
return false;
}
public static function import(string $jsonPath) {}
public static function validate(string $grammar): bool {
if ($grammar === null) {
throw new \Exception("\"$jsonPath\" is not a valid grammar JSON file.".\PHP_EOL);

9
lib/Grammar/Repository.php

@ -0,0 +1,9 @@
<?php
/** @license MIT
* Copyright 2021 Dustin Wilson et al.
* See LICENSE file for details */
declare(strict_types=1);
namespace dW\Lit\Grammar;
class Repository extends NamedPatternListList {}

14
lib/Tokenizer.php

@ -6,4 +6,16 @@
declare(strict_types=1);
namespace dW\Lit;
class Tokenizer {}
class Tokenizer {
protected \Generator $data;
public function __constructor(\Generator $data) {
$this->data = $data;
}
public function tokenize(): \Generator {
foreach ($this->data as $lineNumber => $line) {
}
}
}
Loading…
Cancel
Save