+<?php
+namespace Graphit\Parser\EBNF;
+
+class EBNFParser
+{
+ public static function parse(string $code): ?SyntaxResult
+ {
+ $result = self::syntax($code, 0);
+ if ($result && $result->position != strlen($code)) {
+ return null;
+ }
+
+ return $result;
+ }
+
+ private static function anonymous14(string $code, int $position): ?Anonymous14Result
+ {
+ $regexp = '/^([a-z][a-z ]*[a-z]|[a-z])/';
+ if (preg_match($regexp, substr($code, $position), $matches) === 1) {
+ return new Anonymous14Result($matches[0], $position + strlen($matches[0]));
+ }
+
+ return null;
+ }
+
+ private static function anonymous16(string $code, int $position): ?Anonymous16Result
+ {
+ $regexp = '/^\'([^\']*)\'/';
+ if (preg_match($regexp, substr($code, $position), $matches) === 1) {
+ return new Anonymous16Result($matches[0], $position + strlen($matches[0]));
+ }
+
+ return null;
+ }
+
+ private static function anonymous18(string $code, int $position): ?Anonymous18Result
+ {
+ $regexp = '/^"([^"]*)"/';
+ if (preg_match($regexp, substr($code, $position), $matches) === 1) {
+ return new Anonymous18Result($matches[0], $position + strlen($matches[0]));
+ }
+
+ return null;
+ }
+
+ private static function anonymous20(string $code, int $position): ?Anonymous20Result
+ {
+ $regexp = '/^\\/\\^([^\\/\\\\]*(\\\\\\/|\\\\[^\\/])?)*\\//';
+ if (preg_match($regexp, substr($code, $position), $matches) === 1) {
+ return new Anonymous20Result($matches[0], $position + strlen($matches[0]));
+ }
+
+ return null;
+ }
+
+ private static function whitespace(string $code, int $position): ?WhitespaceResult
+ {
+ $regexp = '/^[ \\t\\r\\n]+/';
+ if (preg_match($regexp, substr($code, $position), $matches) === 1) {
+ return new WhitespaceResult($matches[0], $position + strlen($matches[0]));
+ }
+
+ return null;
+ }
+
+ private static function comment(string $code, int $position): ?CommentResult
+ {
+ $regexp = '/^(\\(\\*\\s+[^*]*\\s+\\*\\)|\\(\\* \\*\\)|\\(\\*\\*\\))/';
+ if (preg_match($regexp, substr($code, $position), $matches) === 1) {
+ return new CommentResult($matches[0], $position + strlen($matches[0]));
+ }
+
+ return null;
+ }
+
+ private static function anonymous2(string $code, int $position): ?Anonymous2Result
+ {
+ if (substr($code, $position, 1) === '=') {
+ return new Anonymous2Result('=', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous3(string $code, int $position): ?Anonymous3Result
+ {
+ if (substr($code, $position, 1) === ';') {
+ return new Anonymous3Result(';', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous7(string $code, int $position): ?Anonymous7Result
+ {
+ if (substr($code, $position, 1) === '|') {
+ return new Anonymous7Result('|', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous11(string $code, int $position): ?Anonymous11Result
+ {
+ if (substr($code, $position, 1) === ',') {
+ return new Anonymous11Result(',', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous22(string $code, int $position): ?Anonymous22Result
+ {
+ if (substr($code, $position, 1) === '(') {
+ return new Anonymous22Result('(', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous23(string $code, int $position): ?Anonymous23Result
+ {
+ if (substr($code, $position, 1) === ')') {
+ return new Anonymous23Result(')', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous25(string $code, int $position): ?Anonymous25Result
+ {
+ if (substr($code, $position, 1) === '{') {
+ return new Anonymous25Result('{', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous26(string $code, int $position): ?Anonymous26Result
+ {
+ if (substr($code, $position, 1) === '}') {
+ return new Anonymous26Result('}', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous28(string $code, int $position): ?Anonymous28Result
+ {
+ if (substr($code, $position, 1) === '[') {
+ return new Anonymous28Result('[', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function anonymous29(string $code, int $position): ?Anonymous29Result
+ {
+ if (substr($code, $position, 1) === ']') {
+ return new Anonymous29Result(']', $position + 1);
+ }
+
+ return null;
+ }
+
+ private static function term(string $code, int $position): ?TermResult
+ {
+ if ($result = self::bareword($code, $position)) {
+ return new TermResult($result, $result->position);
+ }
+ if ($result = self::sq($code, $position)) {
+ return new TermResult($result, $result->position);
+ }
+ if ($result = self::dq($code, $position)) {
+ return new TermResult($result, $result->position);
+ }
+ if ($result = self::regex($code, $position)) {
+ return new TermResult($result, $result->position);
+ }
+ if ($result = self::group($code, $position)) {
+ return new TermResult($result, $result->position);
+ }
+ if ($result = self::repetition($code, $position)) {
+ return new TermResult($result, $result->position);
+ }
+ if ($result = self::optional($code, $position)) {
+ return new TermResult($result, $result->position);
+ }
+
+ return null;
+ }
+
+ private static function anonymous31(string $code, int $position): ?Anonymous31Result
+ {
+ if ($result = self::whitespace($code, $position)) {
+ return new Anonymous31Result($result, $result->position);
+ }
+ if ($result = self::comment($code, $position)) {
+ return new Anonymous31Result($result, $result->position);
+ }
+
+ return null;
+ }
+
+ private static function syntax(string $code, int $position): ?SyntaxResult
+ {
+ $results = [];
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::rules($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new SyntaxResult($results, $position);
+ }
+
+ private static function rule(string $code, int $position): ?RuleResult
+ {
+ $results = [];
+ if ($result = self::bareword($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::anonymous2($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::alt($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::anonymous3($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new RuleResult($results, $position);
+ }
+
+ private static function alt(string $code, int $position): ?AltResult
+ {
+ $results = [];
+ if ($result = self::conc($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::pipeconclist($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new AltResult($results, $position);
+ }
+
+ private static function pipeconc(string $code, int $position): ?PipeconcResult
+ {
+ $results = [];
+ if ($result = self::anonymous7($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::conc($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new PipeconcResult($results, $position);
+ }
+
+ private static function conc(string $code, int $position): ?ConcResult
+ {
+ $results = [];
+ if ($result = self::term($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::commatermlist($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new ConcResult($results, $position);
+ }
+
+ private static function commaterm(string $code, int $position): ?CommatermResult
+ {
+ $results = [];
+ if ($result = self::anonymous11($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::term($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new CommatermResult($results, $position);
+ }
+
+ private static function bareword(string $code, int $position): ?BarewordResult
+ {
+ $results = [];
+ if ($result = self::anonymous14($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new BarewordResult($results, $position);
+ }
+
+ private static function sq(string $code, int $position): ?SqResult
+ {
+ $results = [];
+ if ($result = self::anonymous16($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new SqResult($results, $position);
+ }
+
+ private static function dq(string $code, int $position): ?DqResult
+ {
+ $results = [];
+ if ($result = self::anonymous18($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new DqResult($results, $position);
+ }
+
+ private static function regex(string $code, int $position): ?RegexResult
+ {
+ $results = [];
+ if ($result = self::anonymous20($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new RegexResult($results, $position);
+ }
+
+ private static function group(string $code, int $position): ?GroupResult
+ {
+ $results = [];
+ if ($result = self::anonymous22($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::alt($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::anonymous23($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new GroupResult($results, $position);
+ }
+
+ private static function repetition(string $code, int $position): ?RepetitionResult
+ {
+ $results = [];
+ if ($result = self::anonymous25($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::alt($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::anonymous26($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new RepetitionResult($results, $position);
+ }
+
+ private static function optional(string $code, int $position): ?OptionalResult
+ {
+ $results = [];
+ if ($result = self::anonymous28($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::alt($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::anonymous29($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+ if ($result = self::space($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ } else {
+ return null;
+ }
+
+ return new OptionalResult($results, $position);
+ }
+
+ /** @psalm-suppress LessSpecificReturnType */
+ private static function rules(string $code, int $position): ?RulesResult
+ {
+ $results = [];
+ while ($result = self::rule($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ }
+
+ return new RulesResult($results, $position);
+ }
+
+ /** @psalm-suppress LessSpecificReturnType */
+ private static function pipeconclist(string $code, int $position): ?PipeconclistResult
+ {
+ $results = [];
+ while ($result = self::pipeconc($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ }
+
+ return new PipeconclistResult($results, $position);
+ }
+
+ /** @psalm-suppress LessSpecificReturnType */
+ private static function commatermlist(string $code, int $position): ?CommatermlistResult
+ {
+ $results = [];
+ while ($result = self::commaterm($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ }
+
+ return new CommatermlistResult($results, $position);
+ }
+
+ /** @psalm-suppress LessSpecificReturnType */
+ private static function space(string $code, int $position): ?SpaceResult
+ {
+ $results = [];
+ while ($result = self::anonymous31($code, $position)) {
+ $position = $result->position;
+ $results[] = $result;
+ }
+
+ return new SpaceResult($results, $position);
+ }
+}
\ No newline at end of file