diff --git a/.gitattributes b/.gitattributes index de5a88e7..fe21226b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -17,3 +17,4 @@ Makefile export-ignore phpstan-baseline.neon export-ignore phpstan.neon export-ignore phpunit.xml export-ignore +src/Parser/Generated/** linguist-generated=true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 04fb4762..89422a15 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -175,6 +175,11 @@ jobs: - name: "Install the grammar toolchain" run: "make grammars-install" + - name: "Check the generated parser is up to date" + run: | + make grammars-build + git diff --exit-code src/Parser/Generated + - name: "Tests" run: "make tests" diff --git a/Makefile b/Makefile index 40cf4820..3d0338e2 100644 --- a/Makefile +++ b/Makefile @@ -45,3 +45,9 @@ phpstan-generate-baseline: .PHONY: grammars-install grammars-install: composer install --no-interaction --working-dir tools/phplrt + +# Writes the parser of src/Parser/Generated out of doc/grammars. Run it after +# changing a grammar or a reducer of src/Parser/AstBuilder.php. +.PHONY: grammars-build +grammars-build: + php tools/phplrt/build.php diff --git a/UPGRADING.md b/UPGRADING.md index b673bccf..058d05df 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,3 +1,16 @@ +Upgrading from phpstan/phpdoc-parser 2.x to 3.0 +================================= + +### The parser is generated from the grammars + +`ConstExprParser`, `TypeParser` and `PhpDocParser` are no longer written by hand. The parser is generated from the grammars in [`doc/grammars`](doc/grammars) with [phplrt](https://github.com/phplrt/phplrt), and the AST is built by `PHPStan\PhpDocParser\Parser\AstBuilder`. The library now requires `ondrejmirtes/phplrt-runtime`. + +Their constructors and `parse()` methods (and `PhpDocParser::parseTag()`, `PhpDocParser::parseTagValue()` and `ConstExprParser::parseDoctrineString()`) are the same, and so is the AST they build. + +* Some details of a `ParserException` thrown for an invalid input may be different: the token the parser stopped at, and the token it says it expected there. +* These public methods of `TypeParser`, which were not meant to be called from the outside, are removed: `parseGeneric()`, `parseTemplateTagValue()`, `isHtml()` and `enrichWithAttributes()`. +* The `TypeParser` and `ConstExprParser` given to the constructors of `TypeParser` and `PhpDocParser` are not used anymore. + Upgrading from phpstan/phpdoc-parser 1.x to 2.0 ================================= diff --git a/composer.json b/composer.json index 8047c49e..c6c9f1ba 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,8 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "license": "MIT", "require": { - "php": "^7.4 || ^8.0" + "php": "^7.4 || ^8.0", + "ondrejmirtes/phplrt-runtime": "^4.2.4" }, "require-dev": { "doctrine/annotations": "^2.0", diff --git a/doc/grammars/README.md b/doc/grammars/README.md index 16b78bc4..9c01fbf7 100644 --- a/doc/grammars/README.md +++ b/doc/grammars/README.md @@ -36,6 +36,21 @@ run are left in `temp/fuzzy` to be looked at. That is a great deal more of the language than a hand-written corpus covers, and it is what replaced the `abnfgen`-driven fuzzer this project used before. +## The parser is generated from them + +`src/Parser/Generated/GeneratedParser.php` is the parser of `phpdoc.pp3`, and +it is written by `tools/phplrt/build.php` — never edit it by hand: + + make grammars-install # the toolchain, which asks for PHP 8.4 + make grammars-build + +Every rule is a method reading it the way the phplrt runtime would read the +compiled grammar, and building its value as it goes: the rules a node of the +AST is built out of are the ones `src/Parser/AstBuilder.php` has a `reduce` +method for, so a change of a grammar or of a reducer is followed by +`make grammars-build`. The `Grammars` job of the CI checks that the parser in +the repository is the one the grammars write. + ## What keeps them in step The fuzzer walks the grammars one way; `tests/PHPStan/Parser/GrammarSyncTest.php` @@ -110,16 +125,19 @@ most of them: - **A rule reads exactly the tokens its method reads**, down to the line breaks around it. -### The tokens are not read by phplrt +### The lexer is written out of the `%token` declarations -A grammar of this directory is not read by the lexer it declares: it is read by -the very tokens `PHPStan\PhpDocParser\Lexer\Lexer` produces, handed over by -`tools/phplrt/Fuzzer/TokenStream.php`. +`tools/phplrt/build.php` writes the pattern of `PHPStan\PhpDocParser\Lexer\Lexer` +out of the `%token` declarations of `lexemes.pp3`, in the order they are +declared, into `GeneratedParser::LEXER_PATTERN`. Each token is marked by the +identifier the grammar gives it, and `GeneratedParser::LEXER_TYPES` maps it back +to the `Lexer::TOKEN_*` type `tokenize()` returns, so the tokens are the very +ones they always were. -The `%token` declarations therefore name the tokens and document the language -without being what reads it. Some of them describe something the lexer never -reads as a token of its own, and `TokenStream` is what tells those apart in the -stream: +Some declarations describe something the lexer never reads as a token of its +own. They are left out of the pattern, and `src/Parser/Phplrt/TokenStream.php` +tells them apart in the stream the parser reads, while the PHPDoc is being +lexed: - a word the parser compares by value (`is`, `array`, `covariant`, `static`, …) — every one of them is still an ordinary name as well, which is why they are diff --git a/doc/grammars/const-expr.pp3 b/doc/grammars/const-expr.pp3 index d368bf7b..255ff0a4 100644 --- a/doc/grammars/const-expr.pp3 +++ b/doc/grammars/const-expr.pp3 @@ -88,8 +88,7 @@ ConstantArrayItem * - BAR */ ConstantFetch - : !ArrayKeyword() Identifier() ClassConstantName() - | !ArrayKeyword() Identifier() + : !ArrayKeyword() Identifier() ( ClassConstantName() )? ; /** diff --git a/doc/grammars/lexemes.pp3 b/doc/grammars/lexemes.pp3 index 7859a714..dd8367ab 100644 --- a/doc/grammars/lexemes.pp3 +++ b/doc/grammars/lexemes.pp3 @@ -3,23 +3,25 @@ * The Lexemes Of The PHPDoc Language * ----------------------------------------------------------------------------- * - * Every token the PHPDoc language is read into, written the way - * "PHPStan\PhpDocParser\Lexer\Lexer" reads it. + * Every token the PHPDoc language is read into. * - * A grammar of this directory is not read by the lexer it declares: it is read - * by the very tokens "Lexer" produces, handed over by - * "tools/phplrt/Fuzzer/TokenStream.php". The declarations below therefore - * serve three purposes: + * "PHPStan\PhpDocParser\Lexer\Lexer" is written out of these declarations by + * "tools/phplrt/build.php": every token that is not classified below becomes + * an alternative of its pattern, tried in the order written here, so the + * order is the one that decides between two tokens matching at one place. + * The declarations also serve the grammar-driven fuzzer, which writes its + * inputs out of them. * - * - they name the tokens the rules are written in terms of; - * - they document the language down to its lexical level; - * - they are what the grammar-driven fuzzer writes its inputs from. + * Every group of a pattern is non-capturing: "preg_match_all()" collects + * every capturing group for every token the lexer reads. * - * A block of tokens marked "classified" is not read as a token of its own by - * the lexer. Such a token is a T_IDENTIFIER (or a bracket, or an asterisk) - * whose surroundings or whose very value the hand-written parser asks about, - * and telling those apart in the token stream is what lets a grammar written - * without semantic predicates say the same thing. + * A classified token is not an alternative of the pattern: the keywords, the + * tags read by a rule of their own, the tokens ending in "_WS" and the "<" of + * an HTML tag. Such a token is a T_IDENTIFIER (or a tag, a bracket, or an + * asterisk) whose surroundings or whose very value the grammar asks about. + * The lexer reads it as that token, and tells it apart only in the stream it + * hands to the parser ("src/Parser/Phplrt/TokenStream.php"), which is what + * lets a grammar written without semantic predicates say the same thing. */ %pragma lexer.pcre.disable u @@ -79,8 +81,8 @@ // Literals and names // ----------------------------------------------------------------------------- -%token T_FLOAT [+\-]?(?:(?:[0-9]++(_[0-9]++)*\.[0-9]*+(_[0-9]++)*(?:e[+\-]?[0-9]++(_[0-9]++)*)?)|(?:[0-9]*+(_[0-9]++)*\.[0-9]++(_[0-9]++)*(?:e[+\-]?[0-9]++(_[0-9]++)*)?)|(?:[0-9]++(_[0-9]++)*e[+\-]?[0-9]++(_[0-9]++)*)) -%token T_INTEGER [+\-]?(?:(?:0b[0-1]++(_[0-1]++)*)|(?:0o[0-7]++(_[0-7]++)*)|(?:0x[0-9a-f]++(_[0-9a-f]++)*)|(?:[0-9]++(_[0-9]++)*)) +%token T_FLOAT [+\-]?(?:(?:[0-9]++(?:_[0-9]++)*\.[0-9]*+(?:_[0-9]++)*(?:e[+\-]?[0-9]++(?:_[0-9]++)*)?)|(?:[0-9]*+(?:_[0-9]++)*\.[0-9]++(?:_[0-9]++)*(?:e[+\-]?[0-9]++(?:_[0-9]++)*)?)|(?:[0-9]++(?:_[0-9]++)*e[+\-]?[0-9]++(?:_[0-9]++)*)) +%token T_INTEGER [+\-]?(?:(?:0b[0-1]++(?:_[0-1]++)*)|(?:0o[0-7]++(?:_[0-7]++)*)|(?:0x[0-9a-f]++(?:_[0-9a-f]++)*)|(?:[0-9]++(?:_[0-9]++)*)) %token T_SINGLE_QUOTED_STRING '(?:\\[^\r\n]|[^'\r\n\\])*+' %token T_DOUBLE_QUOTED_STRING "(?:\\[^\r\n]|[^"\r\n\\])*+" %token T_DOCTRINE_ANNOTATION_STRING "(?:""|[^"])*+" @@ -120,7 +122,6 @@ %token T_ARROW -> %token T_EQUAL = %token T_COLON : -%token T_WILDCARD \* // ----------------------------------------------------------------------------- // PHPDoc structure @@ -128,6 +129,7 @@ %token T_OPEN_PHPDOC /\*\*(?=\s)\x20?+ %token T_CLOSE_PHPDOC \*/ +%token T_WILDCARD \* /** * The tags whose value is read by a rule of its own, told apart from one diff --git a/doc/grammars/phpdoc-block.pp3 b/doc/grammars/phpdoc-block.pp3 index 9a654614..9169ccfe 100644 --- a/doc/grammars/phpdoc-block.pp3 +++ b/doc/grammars/phpdoc-block.pp3 @@ -26,13 +26,18 @@ PhpDoc : ? ( ! PhpDocChildren() )? ; +/** + * The children one after another, written as a repetition rather than as a + * rule calling itself once per child, so that a PHPDoc of many tags is read + * without nesting a rule per tag. + */ PhpDocChildren - : UnreadTagChild() ? MorePhpDocChildren()? - | PhpDocChild() ( MorePhpDocChildren()? )? + : PhpDocChildrenItem() ( ! PhpDocChildrenItem() )* ; -MorePhpDocChildren - : ! PhpDocChildren() +PhpDocChildrenItem + : UnreadTagChild() ? + | PhpDocChild() ( | & ) ; /** @@ -166,8 +171,7 @@ ParameterNameStart * space, which is what tells "@var Foo the one" from "@var Foo|the one". */ VarTagValue - : Type() VariableName() Description() - | Type() DescriptionAfterType() + : Type() ( VariableName() Description() | DescriptionAfterType() ) ; VariableName @@ -189,10 +193,13 @@ VariableName * meant. */ MethodTagValue - : StaticType() Type() Identifier() MethodTagValueTail() - | StaticType() Type() MethodTagValueTail() - | Type() Identifier() MethodTagValueTail() - | Type() MethodTagValueTail() + : StaticType() Type() MethodNameAndTail() + | Type() MethodNameAndTail() + ; + +MethodNameAndTail + : Identifier() MethodTagValueTail() + | MethodTagValueTail() ; /** @@ -354,12 +361,15 @@ DoctrineDescription * to it, while one written after it does not. */ Text - : TextLine() TextTail()? + : TextLine() TextTail()* ; +/** + * A line with something on it, along with the blank lines before it, so that + * the blank lines written after the last such line are left unread. + */ TextTail - : !TextStop() TextLineWithSomethingOnIt() TextTail()? - | !TextStop() TextTail() + : ( !TextStop() )+ TextLineWithSomethingOnIt() ; TextLine @@ -579,8 +589,7 @@ NonTagTextToken * predicate says. */ DoctrineTag - : DoctrineTagToken() DoctrineArguments() DoctrineDescription() - | DoctrineTagToken() !ParenthesesOpen() DoctrineDescription() + : DoctrineTagToken() ( DoctrineArguments() | !ParenthesesOpen() ) DoctrineDescription() | GenericTagToken() DoctrineArguments() DoctrineDescription() ; diff --git a/phpcs.xml b/phpcs.xml index f20026b1..3ab4bf67 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -8,6 +8,9 @@ + + src/Parser/Generated/* + diff --git a/phpstan.neon b/phpstan.neon index 92ffe420..cf7a8c8b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,8 +6,11 @@ parameters: - src - tests excludePaths: - - tests/PHPStan/*/data/* - - tests/PHPStan/Parser/Doctrine/ApiResource.php + analyse: + - src/Parser/Generated/* + analyseAndScan: + - tests/PHPStan/*/data/* + - tests/PHPStan/Parser/Doctrine/ApiResource.php level: 8 ignoreErrors: - '#^Dynamic call to static method PHPUnit\\Framework\\Assert#' diff --git a/src/Lexer/Lexer.php b/src/Lexer/Lexer.php index c470100c..82e16f8a 100644 --- a/src/Lexer/Lexer.php +++ b/src/Lexer/Lexer.php @@ -2,12 +2,13 @@ namespace PHPStan\PhpDocParser\Lexer; +use PHPStan\PhpDocParser\Parser\Phplrt\TokenStream; use PHPStan\PhpDocParser\ParserConfig; -use function implode; -use function preg_match_all; /** * Implementation based on Nette Tokenizer (New BSD License; https://github.com/nette/tokenizer) + * + * The pattern is written out of "doc/grammars/lexemes.pp3" by "tools/phplrt/build.php". */ class Lexer { @@ -99,110 +100,23 @@ class Lexer private ParserConfig $config; // @phpstan-ignore property.onlyWritten - private ?string $regexp = null; - public function __construct(ParserConfig $config) { $this->config = $config; } /** - * @return list + * The tokens of the pattern written out of "doc/grammars/lexemes.pp3", + * ending with TOKEN_END. + * + * The last token carries what the parsers read along: keep the tokens + * together when handing them over to a {@see TokenIterator}. + * + * @return list, 4?: list}> */ public function tokenize(string $s): array { - if ($this->regexp === null) { - $this->regexp = $this->generateRegexp(); - } - - // PREG_PATTERN_ORDER, not PREG_SET_ORDER: it collects the whole PHPDoc - // into two arrays instead of allocating one array per token. This only - // pays off while the token patterns have no capturing groups, because - // every group would get an array of its own, one entry per token. - preg_match_all($this->regexp, $s, $matches); - - $values = $matches[0]; - if ($values === []) { - return [['', self::TOKEN_END, 1]]; - } - - $marks = $matches['MARK']; - - $tokens = []; - $line = 1; - foreach ($values as $i => $value) { - $type = (int) $marks[$i]; - $tokens[] = [$value, $type, $line]; - if ($type !== self::TOKEN_PHPDOC_EOL) { - continue; - } - - $line++; - } - - $tokens[] = ['', self::TOKEN_END, $line]; - - return $tokens; - } - - private function generateRegexp(): string - { - // every group in here must be non-capturing, see tokenize() - $patterns = [ - self::TOKEN_HORIZONTAL_WS => '[\\x09\\x20]++', - - self::TOKEN_IDENTIFIER => '(?:[\\\\]?+[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF-]*+)++', - self::TOKEN_THIS_VARIABLE => '\\$this(?![0-9a-z_\\x80-\\xFF])', - self::TOKEN_VARIABLE => '\\$[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF]*+', - - // '&' followed by TOKEN_VARIADIC, TOKEN_VARIABLE, TOKEN_EQUAL, TOKEN_EQUAL or TOKEN_CLOSE_PARENTHESES - self::TOKEN_REFERENCE => '&(?=\\s*+(?:[,=)]|\\.\\.\\.|(?:\\$(?!this(?![0-9a-z_\\x80-\\xFF])))))', - self::TOKEN_UNION => '\\|', - self::TOKEN_INTERSECTION => '&', - self::TOKEN_NULLABLE => '\\?', - self::TOKEN_NEGATED => '!', - - self::TOKEN_OPEN_PARENTHESES => '\\(', - self::TOKEN_CLOSE_PARENTHESES => '\\)', - self::TOKEN_OPEN_ANGLE_BRACKET => '<', - self::TOKEN_CLOSE_ANGLE_BRACKET => '>', - self::TOKEN_OPEN_SQUARE_BRACKET => '\\[', - self::TOKEN_CLOSE_SQUARE_BRACKET => '\\]', - self::TOKEN_OPEN_CURLY_BRACKET => '\\{', - self::TOKEN_CLOSE_CURLY_BRACKET => '\\}', - - self::TOKEN_COMMA => ',', - self::TOKEN_COMMENT => '\/\/[^\\r\\n]*(?=\n|\r|\*/)', - self::TOKEN_VARIADIC => '\\.\\.\\.', - self::TOKEN_DOUBLE_COLON => '::', - self::TOKEN_DOUBLE_ARROW => '=>', - self::TOKEN_ARROW => '->', - self::TOKEN_EQUAL => '=', - self::TOKEN_COLON => ':', - - self::TOKEN_OPEN_PHPDOC => '/\\*\\*(?=\\s)\\x20?+', - self::TOKEN_CLOSE_PHPDOC => '\\*/', - self::TOKEN_PHPDOC_TAG => '@(?:[a-z][a-z0-9-\\\\]+:)?[a-z][a-z0-9-\\\\]*+', - self::TOKEN_DOCTRINE_TAG => '@[a-z_\\\\][a-z0-9_\:\\\\]*[a-z_][a-z0-9_]*', - self::TOKEN_PHPDOC_EOL => '\\r?+\\n[\\x09\\x20]*+(?:\\*(?!/)\\x20?+)?', - - self::TOKEN_FLOAT => '[+\-]?(?:(?:[0-9]++(?:_[0-9]++)*\\.[0-9]*+(?:_[0-9]++)*(?:e[+\-]?[0-9]++(?:_[0-9]++)*)?)|(?:[0-9]*+(?:_[0-9]++)*\\.[0-9]++(?:_[0-9]++)*(?:e[+\-]?[0-9]++(?:_[0-9]++)*)?)|(?:[0-9]++(?:_[0-9]++)*e[+\-]?[0-9]++(?:_[0-9]++)*))', - self::TOKEN_INTEGER => '[+\-]?(?:(?:0b[0-1]++(?:_[0-1]++)*)|(?:0o[0-7]++(?:_[0-7]++)*)|(?:0x[0-9a-f]++(?:_[0-9a-f]++)*)|(?:[0-9]++(?:_[0-9]++)*))', - self::TOKEN_SINGLE_QUOTED_STRING => '\'(?:\\\\[^\\r\\n]|[^\'\\r\\n\\\\])*+\'', - self::TOKEN_DOUBLE_QUOTED_STRING => '"(?:\\\\[^\\r\\n]|[^"\\r\\n\\\\])*+"', - self::TOKEN_DOCTRINE_ANNOTATION_STRING => '"(?:""|[^"])*+"', - - self::TOKEN_WILDCARD => '\\*', - - // anything but TOKEN_CLOSE_PHPDOC or TOKEN_HORIZONTAL_WS or TOKEN_EOL - self::TOKEN_OTHER => '(?:(?!\\*/)[^\\s])++', - ]; - - foreach ($patterns as $type => &$pattern) { - $pattern = '(?:' . $pattern . ')(*MARK:' . $type . ')'; - } - - return '~' . implode('|', $patterns) . '~Asi'; + return TokenStream::tokenize($s); } } diff --git a/src/Parser/AstBuilder.php b/src/Parser/AstBuilder.php new file mode 100644 index 00000000..07974c5f --- /dev/null +++ b/src/Parser/AstBuilder.php @@ -0,0 +1,1863 @@ + true, + Lexer::TOKEN_COMMENT => true, + Lexer::TOKEN_NULLABLE => true, + Lexer::TOKEN_DOUBLE_COLON => true, + ]; + + /** + * The tags whose description follows a type right away. + */ + private const DESCRIPTION_AFTER_TYPE = [ + 'var' => true, + 'return' => true, + 'throws' => true, + 'mixin' => true, + 'require-extends' => true, + 'require-implements' => true, + 'sealed' => true, + 'self-out' => true, + 'template' => true, + 'extends' => true, + 'implements' => true, + 'use' => true, + ]; + + private ParserConfig $config; + + private bool $useAttributes; + + /** @var list the tokens of the lexer being read */ + private array $tokens = []; + + /** the tag the tokens read begin with, which is not one of the lexer */ + private ?string $tag = null; + + /** @var array|null the position each token of the lexer is read at */ + private ?array $positions = null; + + /** @var array|null the offset of each token of the lexer, in bytes */ + private ?array $byteOffsets = null; + + /** the index of the first token of the last text read, or -1 when it is empty */ + private int $textStart = -1; + + /** @var array */ + private array $identifiers = []; + + private int $tUnion; + + private int $tIntersection; + + private int $tIs; + + private int $tNot; + + private int $tVariable; + + private int $tThis; + + private int $tColon; + + private int $tNullable; + + private int $tVariadic; + + private int $tReference; + + private int $tEqual; + + private int $tOf; + + private int $tAs; + + private int $tSuper; + + private int $tCovariant; + + private int $tContravariant; + + private int $tInteger; + + private int $tSingleQuoted; + + private int $tDoubleQuoted; + + private int $tStatic; + + private int $tNegated; + + private int $tOpenParentheses; + + private int $tOpenParenthesesWs; + + private int $tComment; + + /** @var array the kind of tag value each known tag token is read as */ + private array $tagKinds = []; + + public function __construct(ParserConfig $config) + { + $this->config = $config; + $this->useAttributes = $config->useLinesAttributes || $config->useIndexAttributes || $config->useCommentsAttributes; + + $ids = self::TOKENS; + foreach ($ids as $name => $id) { + if ($name !== 'T_IDENTIFIER' && strncmp($name, 'T_KEYWORD_', 10) !== 0) { + continue; + } + + $this->identifiers[$id] = true; + } + + $this->tUnion = $ids['T_UNION']; + $this->tIntersection = $ids['T_INTERSECTION']; + $this->tIs = $ids['T_KEYWORD_IS']; + $this->tNot = $ids['T_KEYWORD_NOT']; + $this->tVariable = $ids['T_VARIABLE']; + $this->tThis = $ids['T_THIS_VARIABLE']; + $this->tColon = $ids['T_COLON']; + $this->tNullable = $ids['T_NULLABLE']; + $this->tVariadic = $ids['T_VARIADIC']; + $this->tReference = $ids['T_REFERENCE']; + $this->tEqual = $ids['T_EQUAL']; + $this->tOf = $ids['T_KEYWORD_OF']; + $this->tAs = $ids['T_KEYWORD_AS']; + $this->tSuper = $ids['T_KEYWORD_SUPER']; + $this->tCovariant = $ids['T_KEYWORD_COVARIANT']; + $this->tContravariant = $ids['T_KEYWORD_CONTRAVARIANT']; + $this->tInteger = $ids['T_INTEGER']; + $this->tSingleQuoted = $ids['T_SINGLE_QUOTED_STRING']; + $this->tDoubleQuoted = $ids['T_DOUBLE_QUOTED_STRING']; + $this->tStatic = $ids['T_KEYWORD_STATIC']; + $this->tNegated = $ids['T_NEGATED']; + $this->tOpenParentheses = $ids['T_OPEN_PARENTHESES']; + $this->tOpenParenthesesWs = $ids['T_OPEN_PARENTHESES_WS']; + $this->tComment = $ids['T_COMMENT']; + + foreach ([ + 'T_TAG_PARAM' => 'param', + 'T_TAG_VAR' => 'var', + 'T_TAG_RETURN' => 'return', + 'T_TAG_THROWS' => 'throws', + 'T_TAG_MIXIN' => 'mixin', + 'T_TAG_REQUIRE_EXTENDS' => 'require-extends', + 'T_TAG_REQUIRE_IMPLEMENTS' => 'require-implements', + 'T_TAG_SEALED' => 'sealed', + 'T_TAG_SELF_OUT' => 'self-out', + 'T_TAG_PROPERTY' => 'property', + 'T_TAG_PARAM_OUT' => 'param-out', + 'T_TAG_PARAM_CLOSURE_THIS' => 'param-closure-this', + 'T_TAG_PARAM_IMMEDIATELY_INVOKED_CALLABLE' => 'param-immediately-invoked-callable', + 'T_TAG_PARAM_LATER_INVOKED_CALLABLE' => 'param-later-invoked-callable', + 'T_TAG_PURE_UNLESS_CALLABLE_IS_IMPURE' => 'pure-unless-callable-is-impure', + 'T_TAG_PURE_UNLESS_PARAMETER_PASSED' => 'pure-unless-parameter-passed', + 'T_TAG_DEPRECATED' => 'deprecated', + 'T_TAG_METHOD' => 'method', + 'T_TAG_TEMPLATE' => 'template', + 'T_TAG_EXTENDS' => 'extends', + 'T_TAG_IMPLEMENTS' => 'implements', + 'T_TAG_USE' => 'use', + 'T_TAG_TYPE_ALIAS' => 'type-alias', + 'T_TAG_TYPE_ALIAS_IMPORT' => 'type-alias-import', + 'T_TAG_ASSERT' => 'assert', + ] as $name => $kind) { + $this->tagKinds[$ids[$name]] = $kind; + } + } + + // ------------------------------------------------------------------------- + // Reading + // ------------------------------------------------------------------------- + + /** + * Reads what the given rule describes from the position the iterator is at, + * and moves the iterator past it. + * + * The reading may stop before the end of the tokens: whatever follows is + * left to the caller, the way it always has been. + * + * @param string|null $tag the tag the value read belongs to, which the + * tokens do not begin with + * @return mixed + * @throws ParserException + */ + public function read(TokenIterator $tokens, string $rule, ?string $tag = null) + { + $lexerTokens = $tokens->getTokens(); + $index = $tokens->currentTokenIndex(); + + $stream = TokenStream::fromTokens($lexerTokens, $index); + if ($stream !== null && $tag === null) { + [$ids, $indexes] = $stream; + } else { + $ids = []; + $indexes = []; + if ($tag !== null) { + // the value of a tag is read along with the tag it belongs to + $ids[] = TokenStream::tagId($tag); + $indexes[] = $index - 1; + } + + if ($stream !== null) { + foreach ($stream[0] as $position => $id) { + $ids[] = $id; + $indexes[] = $stream[1][$position]; + } + } else { + TokenStream::create($lexerTokens, $index, $ids, $indexes); + } + } + + // A reading is never started by another one, so the state of the last + // one is simply overwritten + $this->tokens = $lexerTokens; + $this->ids = $ids; + $this->indexes = $indexes; + $this->tag = $tag; + $this->positions = null; + $this->comments = []; + $this->byteOffsets = null; + $this->v = []; + $this->n = 0; + + if ($this->config->useCommentsAttributes) { + foreach ($ids as $position => $id) { + if ($id !== $this->tComment) { + continue; + } + + $commentIndex = $indexes[$position]; + $this->comments[$commentIndex] = new Comment($lexerTokens[$commentIndex][Lexer::VALUE_OFFSET], $lexerTokens[$commentIndex][Lexer::LINE_OFFSET], $commentIndex); + } + } + + // What has been read is given back even when the reading stops + // before the end, unless nothing at all has been built + if (!$this->parseRule(self::RULES[$rule], 0, true) || ($this->n === 0 && $this->ids[$this->p] !== -1)) { + throw $this->createException($this->failure()); + } + + $tokens->setCurrentTokenIndex($indexes[$this->p]); + + return $this->n > 0 ? $this->v[0] : []; + } + + protected function token(int $position): Token + { + $index = $this->indexes[$position]; + + return new Token( + $this->ids[$position], + $position === 0 && $this->tag !== null ? $this->tag : $this->tokens[$index][Lexer::VALUE_OFFSET], + $index, + ); + } + + /** + * Describes why the given rule cannot be read at the given token, which is + * what a node standing for something that cannot be read carries. + */ + private function explain(string $rule, int $index): ParserException + { + $state = $this->saveReading(); + try { + if (!$this->parseRule(self::RULES[$rule], $this->position($index), false) || $this->ids[$this->p] !== -1) { + return $this->createException($this->failure()); + } + + // Everything that follows has been read as well, so there is nothing + // to say but that it has to end somewhere + return $this->createExceptionAt($this->indexes[count($this->indexes) - 1], Lexer::TOKEN_END); + } finally { + $this->restoreReading($state); + } + } + + private function position(int $index): int + { + if ($this->positions === null) { + $this->positions = array_flip($this->indexes); + } + + return $this->positions[$index]; + } + + /** + * @param array{int, list} $failure the position and the tokens expected there + */ + private function createException(array $failure): ParserException + { + [$position, $expectedIds] = $failure; + + // The tokens that may only be written here, rather than the ones that + // may be written anywhere, say what has been expected; where nothing + // but those is left, a type is what has been expected + $names = []; + foreach ($expectedIds as $id) { + if (!isset(self::EXPECTATIONS[$id])) { + continue; + } + + $names[] = self::EXPECTATIONS[$id]; + } + + $expected = Lexer::TOKEN_IDENTIFIER; + $expectedValue = null; + foreach (in_array('T_IDENTIFIER', $names, true) ? [] : $names as $name) { + $type = self::lexerTokenType($name); + if ($type === null || isset(self::INCIDENTAL_TOKENS[$type])) { + continue; + } + + $expected = $type; + if (strncmp($name, 'T_KEYWORD_', 10) === 0) { + // a word compared by its value, like the "from" of an imported type + $expectedValue = strtolower(str_replace(['_ANY_CASE', '_'], ['', '-'], (string) substr($name, 10))); + } + break; + } + + return $this->createExceptionAt($this->indexes[$position], $expected, $expectedValue); + } + + private function createExceptionAt(int $index, int $expected, ?string $expectedValue = null): ParserException + { + $lexerToken = $this->tokens[$index] ?? $this->tokens[count($this->tokens) - 1]; + + if ($this->byteOffsets === null) { + $offset = 0; + $this->byteOffsets = []; + foreach ($this->tokens as $i => $t) { + $this->byteOffsets[$i] = $offset; + $offset += strlen($t[Lexer::VALUE_OFFSET]); + } + } + + return new ParserException( + $lexerToken[Lexer::VALUE_OFFSET], + $lexerToken[Lexer::TYPE_OFFSET], + $this->byteOffsets[$index] ?? 0, + $expected, + $expectedValue, + $lexerToken[Lexer::LINE_OFFSET], + ); + } + + /** + * The token of the lexer a token of the grammar is read out of. + */ + private static function lexerTokenType(string $name): ?int + { + if (strncmp($name, 'T_KEYWORD_', 10) === 0) { + return Lexer::TOKEN_IDENTIFIER; + } + + if (strncmp($name, 'T_TAG_', 6) === 0) { + return Lexer::TOKEN_PHPDOC_TAG; + } + + $name = str_replace(['_WS', '_HTML'], '', substr($name, 2)); + $constant = Lexer::class . '::TOKEN_' . $name; + + return defined($constant) ? (int) constant($constant) : null; + } + + // ------------------------------------------------------------------------- + // Attributes + // ------------------------------------------------------------------------- + + /** + * @template T of Node + * @param T $node + * @return T + */ + private function attributesAt(Node $node, int $start, int $end, bool $takesComments = false, bool $skipsLineBreaks = false): Node + { + if (!$this->useAttributes) { + return $node; + } + + if ($this->config->useLinesAttributes) { + $tokens = $this->tokens; + $last = $tokens[count($tokens) - 1][Lexer::LINE_OFFSET]; + $next = $end + 1; + if ($skipsLineBreaks) { + // the line the reading has stopped at, which is the line of the + // next token that is neither whitespace nor a line break + while (isset($tokens[$next]) && ($tokens[$next][Lexer::TYPE_OFFSET] === Lexer::TOKEN_PHPDOC_EOL || $tokens[$next][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS)) { + $next++; + } + } + + $node->setAttribute(Attribute::START_LINE, $tokens[$start][Lexer::LINE_OFFSET] ?? $last); + $node->setAttribute(Attribute::END_LINE, $tokens[$next][Lexer::LINE_OFFSET] ?? $last); + } + + if ($this->config->useIndexAttributes) { + $node->setAttribute(Attribute::START_INDEX, $start); + $node->setAttribute(Attribute::END_INDEX, $end); + } + + if ($takesComments && $this->config->useCommentsAttributes) { + // A node is given the comments read since the last node was, and + // only those: a node built again by the rule around it is given + // what that rule has read, the way it always has been + $comments = []; + foreach ($this->comments as $index => $comment) { + if ($index > $end) { + break; + } + + $comments[] = $comment; + unset($this->comments[$index]); + } + + $node->setAttribute(Attribute::COMMENTS, $comments); + } + + return $node; + } + + /** + * Forgets the comments read as text rather than as a part of a type. + */ + private function forgetComments(int $start, int $end): void + { + foreach (array_keys($this->comments) as $index) { + if ($index > $end) { + break; + } + + if ($index < $start) { + continue; + } + + unset($this->comments[$index]); + } + } + + private function nextIndex(int $index): int + { + $tokens = $this->tokens; + $index++; + while (($tokens[$index][Lexer::TYPE_OFFSET] ?? null) === Lexer::TOKEN_HORIZONTAL_WS) { + $index++; + } + + return $index; + } + + // ------------------------------------------------------------------------- + // Types + // ------------------------------------------------------------------------- + + /** + * @param list $children + */ + protected function reduceType(int $begin, int $end, $children): TypeNode + { + $types = []; + $kind = 0; + foreach ($children as $child) { + if ($child instanceof TypeNode) { + $types[] = $child; + } elseif ($child instanceof Token) { + if ($child->id === $this->tUnion) { + $kind = 1; + } elseif ($child->id === $this->tIntersection) { + $kind = 2; + } + } + } + + if ($kind === 1) { + $type = new Ast\Type\UnionTypeNode($types); + } elseif ($kind === 2) { + $type = new Ast\Type\IntersectionTypeNode($types); + } else { + $type = $types[0]; + } + + return $this->useAttributes ? $this->attributesAt($type, $begin, $end, true) : $type; + } + + /** + * @param list $children + */ + protected function reduceSubType(int $begin, int $end, $children): TypeNode + { + $types = []; + $kind = 0; + $negated = false; + $parameter = null; + foreach ($children as $child) { + if ($child instanceof TypeNode) { + $types[] = $child; + } elseif ($child instanceof Token) { + $id = $child->id; + if ($id === $this->tUnion) { + $kind = 1; + } elseif ($id === $this->tIntersection) { + $kind = 2; + } elseif ($id === $this->tIs) { + $kind = 3; + } elseif ($id === $this->tNot && $kind === 3) { + $negated = true; + } elseif ($id === $this->tVariable && $parameter === null && $kind === 0) { + $parameter = $child->value; + } + } + } + + if ($kind === 3) { + if ($parameter !== null) { + $type = new Ast\Type\ConditionalTypeForParameterNode($parameter, $types[0], $types[1], $types[2], $negated); + } else { + $type = new Ast\Type\ConditionalTypeNode($types[0], $types[1], $types[2], $types[3], $negated); + } + } elseif ($kind === 1) { + $type = new Ast\Type\UnionTypeNode($types); + } elseif ($kind === 2) { + $type = new Ast\Type\IntersectionTypeNode($types); + } else { + $type = $types[0]; + } + + return $this->useAttributes ? $this->attributesAt($type, $begin, $end, true) : $type; + } + + /** + * @param list $children + */ + protected function reduceNullable(int $begin, int $end, $children): TypeNode + { + foreach ($children as $child) { + if ($child instanceof TypeNode) { + return $this->useAttributes ? $this->attributesAt(new Ast\Type\NullableTypeNode($child), $begin, $end, true) : new Ast\Type\NullableTypeNode($child); + } + } + + throw new LogicException('A nullable type without a type'); + } + + /** + * @param list $children + */ + protected function reduceAtomic(int $begin, int $end, $children): TypeNode + { + $type = $this->assembleAtomic($children, $begin); + + return $this->useAttributes ? $this->attributesAt($type, $begin, $end, true) : $type; + } + + /** + * @param list $children + */ + protected function reduceCallableReturnType(int $begin, int $end, $children): TypeNode + { + $type = $this->assembleAtomic($children, $begin); + + return $this->useAttributes ? $this->attributesAt($type, $begin, $end, true) : $type; + } + + /** + * An atomic type, out of the name or the type it begins with and whatever + * is written right after it. + * + * @param list $children + */ + private function assembleAtomic(array $children, int $begin): TypeNode + { + $type = null; + $name = null; + + foreach ($children as $child) { + if ($child instanceof Token) { + if ($type === null && $name === null) { + if (isset($this->identifiers[$child->id])) { + $name = $child; + } elseif ($child->id === $this->tThis) { + $type = ($this->useAttributes ? $this->attributesAt(new Ast\Type\ThisTypeNode(), $child->offset, $child->offset, true) : new Ast\Type\ThisTypeNode()); + } + } + + continue; + } + + if ($child instanceof TypeNode) { + $type ??= $child; + continue; + } + + if ($child instanceof ConstExprNode) { + $type = ($this->useAttributes ? $this->attributesAt( + new Ast\Type\ConstTypeNode($child), + $child->getAttribute(Attribute::START_INDEX) ?? $begin, + $child->getAttribute(Attribute::END_INDEX) ?? $begin, + true, + ) : new Ast\Type\ConstTypeNode($child)); + continue; + } + + if (!$child instanceof Fragment) { + continue; + } + + switch ($child->kind) { + case Fragment::GENERIC: + $type = new Ast\Type\GenericTypeNode($this->identifier($name), $child->a, $child->b); + break; + case Fragment::CALLABLE: + $type = new Ast\Type\CallableTypeNode($this->identifier($name), $child->a, $child->b, $child->c); + break; + case Fragment::SHAPE: + /** @var Token $name */ + /** @var Ast\Type\ArrayShapeNode::KIND_* $kind */ + $kind = $name->value; + $type = $child->b === true + ? Ast\Type\ArrayShapeNode::createSealed($child->a, $kind) + : Ast\Type\ArrayShapeNode::createUnsealed($child->a, $child->c, $kind); + break; + case Fragment::OBJECT_SHAPE: + $type = new Ast\Type\ObjectShapeNode($child->a); + break; + case Fragment::OFFSET: + $type = new Ast\Type\OffsetAccessTypeNode($type ?? $this->identifier($name), $child->a); + break; + default: + $type = new Ast\Type\ArrayTypeNode($type ?? $this->identifier($name)); + break; + } + + $type = ($this->useAttributes ? $this->attributesAt($type, $begin, $child->end, true) : $type); + } + + return $type ?? $this->identifier($name); + } + + private function identifier(?Token $name): Ast\Type\IdentifierTypeNode + { + if ($name === null) { + throw new LogicException('A type without a name'); + } + + return $this->useAttributes ? $this->attributesAt(new Ast\Type\IdentifierTypeNode($name->value), $name->offset, $name->offset, true) : new Ast\Type\IdentifierTypeNode($name->value); + } + + /** + * @param list $children + */ + protected function reduceArrayOrOffsetAccessItem(int $begin, int $end, $children): Fragment + { + foreach ($children as $child) { + if ($child instanceof TypeNode) { + return new Fragment(Fragment::OFFSET, $end, $child); + } + } + + return new Fragment(Fragment::ARRAY, $end); + } + + /** + * @param list $children + */ + protected function reduceGeneric(int $begin, int $end, $children): Fragment + { + $types = []; + $variances = []; + foreach ($children as $child) { + if (!$child instanceof Fragment) { + continue; + } + + $types[] = $child->a; + $variances[] = $child->b; + } + + return new Fragment(Fragment::GENERIC, $end, $types, $variances); + } + + /** + * @param list $children + */ + protected function reduceGenericInReturnType(int $begin, int $end, $children): Fragment + { + return $this->reduceGeneric($begin, $end, $children); + } + + /** + * @param list $children + */ + protected function reduceGenericArgument(int $begin, int $end, $children): Fragment + { + $variance = Ast\Type\GenericTypeNode::VARIANCE_INVARIANT; + foreach ($children as $child) { + if ($child instanceof TypeNode) { + return new Fragment(Fragment::GENERIC_ARGUMENT, $end, $child, $variance); + } + + if (!$child instanceof Token) { + continue; + } + + if ($child->id === $this->tCovariant) { + $variance = Ast\Type\GenericTypeNode::VARIANCE_COVARIANT; + } elseif ($child->id === $this->tContravariant) { + $variance = Ast\Type\GenericTypeNode::VARIANCE_CONTRAVARIANT; + } else { + // the wildcard + return new Fragment( + Fragment::GENERIC_ARGUMENT, + $end, + ($this->useAttributes ? $this->attributesAt(new Ast\Type\IdentifierTypeNode('mixed'), $begin, $end, true) : new Ast\Type\IdentifierTypeNode('mixed')), + Ast\Type\GenericTypeNode::VARIANCE_BIVARIANT, + ); + } + } + + throw new LogicException('A generic argument without a type'); + } + + /** + * @param list $children + */ + protected function reduceCallable(int $begin, int $end, $children): Fragment + { + $templates = []; + $parameters = []; + $returnType = null; + foreach ($children as $child) { + if ($child instanceof Ast\Type\CallableTypeParameterNode) { + $parameters[] = $child; + } elseif ($child instanceof Ast\PhpDoc\TemplateTagValueNode) { + $templates[] = $child; + } elseif ($child instanceof TypeNode) { + $returnType = $child; + } + } + + return new Fragment(Fragment::CALLABLE, $end, $parameters, $returnType, $templates); + } + + /** + * @param list $children + */ + protected function reduceCallableWithTemplates(int $begin, int $end, $children): Fragment + { + return $this->reduceCallable($begin, $end, $children); + } + + /** + * @param list $children + */ + protected function reduceCallableTemplateArgument(int $begin, int $end, $children): Ast\PhpDoc\TemplateTagValueNode + { + return $this->attributesAt($this->template($children, ''), $begin, $end, true); + } + + /** + * @param list $children + */ + private function template(array $children, string $description): Ast\PhpDoc\TemplateTagValueNode + { + $name = null; + $upperBound = null; + $lowerBound = null; + $default = null; + $next = null; + foreach ($children as $child) { + if ($child instanceof Token) { + if ($name === null) { + $name = $child->value; + } elseif ($child->id === $this->tOf || $child->id === $this->tAs) { + $next = 'upper'; + } elseif ($child->id === $this->tSuper) { + $next = 'lower'; + } elseif ($child->id === $this->tEqual) { + $next = 'default'; + } + } elseif ($child instanceof TypeNode) { + if ($next === 'upper') { + $upperBound = $child; + } elseif ($next === 'lower') { + $lowerBound = $child; + } elseif ($next === 'default') { + $default = $child; + } + } + } + + /** @var non-empty-string $name */ + return new Ast\PhpDoc\TemplateTagValueNode($name, $upperBound, $description, $default, $lowerBound); + } + + /** + * @param list $children + */ + protected function reduceCallableParameter(int $begin, int $end, $children): Ast\Type\CallableTypeParameterNode + { + $type = null; + $isReference = false; + $isVariadic = false; + $name = ''; + $isOptional = false; + foreach ($children as $child) { + if ($child instanceof TypeNode) { + $type = $child; + } elseif ($child instanceof Token) { + $id = $child->id; + if ($id === $this->tReference) { + $isReference = true; + } elseif ($id === $this->tVariadic) { + $isVariadic = true; + } elseif ($id === $this->tVariable) { + $name = $child->value; + } elseif ($id === $this->tEqual) { + $isOptional = true; + } + } + } + + /** @var TypeNode $type */ + return $this->useAttributes ? $this->attributesAt(new Ast\Type\CallableTypeParameterNode($type, $isReference, $isVariadic, $name, $isOptional), $begin, $end, true) : new Ast\Type\CallableTypeParameterNode($type, $isReference, $isVariadic, $name, $isOptional); + } + + /** + * @param list $children + */ + protected function reduceArrayShape(int $begin, int $end, $children): Fragment + { + $items = []; + $sealed = true; + $unsealedType = null; + foreach ($children as $child) { + if ($child instanceof Ast\Type\ArrayShapeItemNode) { + $items[] = $child; + } elseif ($child instanceof Ast\Type\ArrayShapeUnsealedTypeNode) { + $unsealedType = $child; + } elseif ($child instanceof Token && $child->id === $this->tVariadic) { + $sealed = false; + } + } + + return new Fragment(Fragment::SHAPE, $end, $items, $sealed, $unsealedType); + } + + /** + * @param list $children + */ + protected function reduceListShape(int $begin, int $end, $children): Fragment + { + return $this->reduceArrayShape($begin, $end, $children); + } + + /** + * @param list $children + */ + protected function reduceArrayShapeUnsealedType(int $begin, int $end, $children): Ast\Type\ArrayShapeUnsealedTypeNode + { + $types = []; + foreach ($children as $child) { + if (!$child instanceof TypeNode) { + continue; + } + + $types[] = $child; + } + + $node = count($types) === 2 + ? new Ast\Type\ArrayShapeUnsealedTypeNode($types[1], $types[0]) + : new Ast\Type\ArrayShapeUnsealedTypeNode($types[0], null); + + return $this->useAttributes ? $this->attributesAt($node, $begin, $end, true) : $node; + } + + /** + * @param list $children + */ + protected function reduceListShapeUnsealedType(int $begin, int $end, $children): Ast\Type\ArrayShapeUnsealedTypeNode + { + return $this->reduceArrayShapeUnsealedType($begin, $end, $children); + } + + /** + * @param list $children + */ + protected function reduceArrayShapeItem(int $begin, int $end, $children): Ast\Type\ArrayShapeItemNode + { + $nodes = []; + $hasKey = false; + $optional = false; + foreach ($children as $child) { + if ($child instanceof Node) { + $nodes[] = $child; + } elseif ($child instanceof Token) { + if ($child->id === $this->tColon) { + $hasKey = true; + } elseif ($child->id === $this->tNullable) { + $optional = true; + } + } + } + + /** @var TypeNode $value */ + $value = $nodes[count($nodes) - 1]; + if ($hasKey) { + /** @var Ast\ConstExpr\ConstExprIntegerNode|Ast\ConstExpr\ConstExprStringNode|Ast\ConstExpr\ConstFetchNode|Ast\Type\IdentifierTypeNode $key */ + $key = $nodes[0]; + $item = new Ast\Type\ArrayShapeItemNode($key, $optional, $value); + } else { + $item = new Ast\Type\ArrayShapeItemNode(null, false, $value); + } + + return $this->useAttributes ? $this->attributesAt($item, $begin, $end, true) : $item; + } + + /** + * @param list $children + * @return Ast\ConstExpr\ConstExprIntegerNode|Ast\ConstExpr\ConstExprStringNode|Ast\ConstExpr\ConstFetchNode|Ast\Type\IdentifierTypeNode + */ + protected function reduceArrayShapeKey(int $begin, int $end, $children): Node + { + $first = $children[0]; + if (count($children) === 3) { + $key = new Ast\ConstExpr\ConstFetchNode($first->value, $children[2]->value); + } elseif ($first->id === $this->tInteger) { + $key = new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $first->value)); + } else { + $key = $this->stringOrIdentifier($first); + } + + return $this->useAttributes ? $this->attributesAt($key, $begin, $end, true) : $key; + } + + /** + * @return Ast\ConstExpr\ConstExprStringNode|Ast\Type\IdentifierTypeNode + */ + private function stringOrIdentifier(Token $token): Node + { + if ($token->id === $this->tSingleQuoted) { + return new Ast\ConstExpr\ConstExprStringNode(StringUnescaper::unescapeString($token->value), Ast\ConstExpr\ConstExprStringNode::SINGLE_QUOTED); + } + + if ($token->id === $this->tDoubleQuoted) { + return new Ast\ConstExpr\ConstExprStringNode(StringUnescaper::unescapeString($token->value), Ast\ConstExpr\ConstExprStringNode::DOUBLE_QUOTED); + } + + return new Ast\Type\IdentifierTypeNode($token->value); + } + + /** + * @param list $children + */ + protected function reduceObjectShape(int $begin, int $end, $children): Fragment + { + $items = []; + foreach ($children as $child) { + if (!$child instanceof Ast\Type\ObjectShapeItemNode) { + continue; + } + + $items[] = $child; + } + + return new Fragment(Fragment::OBJECT_SHAPE, $end, $items); + } + + /** + * @param list $children + */ + protected function reduceObjectShapeItem(int $begin, int $end, $children): Ast\Type\ObjectShapeItemNode + { + $key = null; + $value = null; + $optional = false; + foreach ($children as $child) { + if ($child instanceof Node) { + if ($key === null) { + $key = $child; + } else { + $value = $child; + } + } elseif ($child instanceof Token && $child->id === $this->tNullable) { + $optional = true; + } + } + + /** @var Ast\ConstExpr\ConstExprStringNode|Ast\Type\IdentifierTypeNode $key */ + /** @var TypeNode $value */ + return $this->useAttributes ? $this->attributesAt(new Ast\Type\ObjectShapeItemNode($key, $optional, $value), $begin, $end, true) : new Ast\Type\ObjectShapeItemNode($key, $optional, $value); + } + + /** + * @param list $children + * @return Ast\ConstExpr\ConstExprStringNode|Ast\Type\IdentifierTypeNode + */ + protected function reduceObjectShapeKey(int $begin, int $end, $children): Node + { + return $this->attributesAt($this->stringOrIdentifier($children[0]), $begin, $end, true); + } + + /** + * A comment read right after the comma separating the items of a shape is + * thrown away. + */ + protected function reduceDiscardedComment(int $begin, int $end): void + { + unset($this->comments[$begin]); + } + + // ------------------------------------------------------------------------- + // Constant expressions + // ------------------------------------------------------------------------- + + /** + * @param list $children + */ + protected function reduceConstantFloat(int $begin, int $end, $children): ConstExprNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprFloatNode(str_replace('_', '', $children[0]->value)), $begin, $end) : new Ast\ConstExpr\ConstExprFloatNode(str_replace('_', '', $children[0]->value)); + } + + /** + * @param list $children + */ + protected function reduceConstantInteger(int $begin, int $end, $children): ConstExprNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $children[0]->value)), $begin, $end) : new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $children[0]->value)); + } + + /** + * @param list $children + */ + protected function reduceConstantString(int $begin, int $end, $children): ConstExprNode + { + /** @var Ast\ConstExpr\ConstExprStringNode $node */ + $node = $this->stringOrIdentifier($children[0]); + + return $this->useAttributes ? $this->attributesAt($node, $begin, $end) : $node; + } + + protected function reduceConstantTrue(int $begin, int $end): ConstExprNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprTrueNode(), $begin, $end) : new Ast\ConstExpr\ConstExprTrueNode(); + } + + protected function reduceConstantFalse(int $begin, int $end): ConstExprNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprFalseNode(), $begin, $end) : new Ast\ConstExpr\ConstExprFalseNode(); + } + + protected function reduceConstantNull(int $begin, int $end): ConstExprNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprNullNode(), $begin, $end) : new Ast\ConstExpr\ConstExprNullNode(); + } + + /** + * @param list $children + */ + protected function reduceConstantArrayLiteral(int $begin, int $end, $children): ConstExprNode + { + $items = []; + foreach ($children as $child) { + if (!$child instanceof Ast\ConstExpr\ConstExprArrayItemNode) { + continue; + } + + $items[] = $child; + } + + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprArrayNode($items), $begin, $end) : new Ast\ConstExpr\ConstExprArrayNode($items); + } + + /** + * @param list $children + */ + protected function reduceConstantArrayShorthand(int $begin, int $end, $children): ConstExprNode + { + return $this->reduceConstantArrayLiteral($begin, $end, $children); + } + + /** + * @param list $children + */ + protected function reduceConstantArrayItem(int $begin, int $end, $children): ConstExprNode + { + $expressions = []; + foreach ($children as $child) { + if (!$child instanceof ConstExprNode) { + continue; + } + + $expressions[] = $child; + } + + $item = count($expressions) === 2 + ? new Ast\ConstExpr\ConstExprArrayItemNode($expressions[0], $expressions[1]) + : new Ast\ConstExpr\ConstExprArrayItemNode(null, $expressions[0]); + + return $this->useAttributes ? $this->attributesAt($item, $begin, $end) : $item; + } + + /** + * @param list $children + */ + protected function reduceConstantFetch(int $begin, int $end, $children): ConstExprNode + { + return $this->attributesAt($this->constantFetch($children), $begin, $end); + } + + /** + * @param list $children + */ + private function constantFetch(array $children): Ast\ConstExpr\ConstFetchNode + { + $first = $children[0]; + if (count($children) === 1) { + return new Ast\ConstExpr\ConstFetchNode('', $first->value); + } + + $name = ''; + for ($i = 2, $count = count($children); $i < $count; $i++) { + $name .= $children[$i]->value; + } + + return new Ast\ConstExpr\ConstFetchNode($first->value, $name); + } + + // ------------------------------------------------------------------------- + // PHPDocs + // ------------------------------------------------------------------------- + + /** + * @param list $children + */ + protected function reducePhpDoc(int $begin, int $end, $children): Ast\PhpDoc\PhpDocNode + { + $nodes = []; + foreach ($children as $child) { + if (!$child instanceof Ast\PhpDoc\PhpDocChildNode) { + continue; + } + + $nodes[] = $child; + } + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\PhpDocNode($nodes), $begin, $end) : new Ast\PhpDoc\PhpDocNode($nodes); + } + + /** + * @param list $children + */ + protected function reduceTextChild(int $begin, int $end, $children): Ast\PhpDoc\PhpDocTextNode + { + $text = ''; + foreach ($children as $child) { + if (!is_string($child)) { + continue; + } + + $text = $child; + } + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\PhpDocTextNode($text), $begin, $end) : new Ast\PhpDoc\PhpDocTextNode($text); + } + + protected function reduceText(int $begin, int $end): string + { + return $this->text($begin, $end); + } + + protected function reduceDoctrineText(int $begin, int $end): string + { + return $this->text($begin, $end); + } + + /** + * The text the rule has been read from, the way it is written save for the + * asterisks a PHPDoc starts its lines with. + */ + private function text(int $begin, int $end): string + { + if ($end < $begin) { + $this->textStart = -1; + return ''; + } + + $start = $begin; + $this->textStart = $start; + if ($this->comments !== []) { + $this->forgetComments($start, $end); + } + + return $this->textBetween($start, $end); + } + + private function textBetween(int $start, int $end): string + { + $tokens = $this->tokens; + $end++; + $text = ''; + for ($i = $start; $i < $end; $i++) { + [$value, $type] = $tokens[$i]; + if ($type === Lexer::TOKEN_PHPDOC_EOL) { + $text .= $value[0] === "\r" ? "\r\n" : "\n"; + continue; + } + + $text .= $value; + } + + return trim($text, " \t"); + } + + /** + * @param list $children + */ + private static function description(array $children): string + { + $last = $children === [] ? null : $children[array_key_last($children)]; + + return is_string($last) ? $last : ''; + } + + /** + * @param list $children + */ + protected function reduceKnownTag(int $begin, int $end, $children): Ast\PhpDoc\PhpDocTagNode + { + if ($children[0] instanceof Ast\PhpDoc\PhpDocTagNode) { + // a type alias whose type cannot be read + return $children[0]; + } + + /** @var Token $tag */ + $tag = $children[0]; + $valueStart = $this->nextIndex($tag->offset); + $value = $this->tagValue($tag, $children, $valueStart, $end); + + // A description written right after a type has to be written after a + // space, which is not something the grammar says + if ( + isset(self::DESCRIPTION_AFTER_TYPE[$this->tagKinds[$tag->id]]) + && $this->textStart > 0 + && self::description($children) !== '' + && !($value instanceof Ast\PhpDoc\VarTagValueNode && $value->variableName !== '') + ) { + $tokens = $this->tokens; + $textStart = $this->textStart; + if ( + $tokens[$textStart][Lexer::TYPE_OFFSET] !== Lexer::TOKEN_PHPDOC_EOL + && $tokens[$textStart - 1][Lexer::TYPE_OFFSET] !== Lexer::TOKEN_HORIZONTAL_WS + ) { + $value = new Ast\PhpDoc\InvalidTagValueNode( + trim($this->textBetween($valueStart, $end), " \t"), + $this->createExceptionAt($textStart, Lexer::TOKEN_HORIZONTAL_WS), + ); + } + } + + $value = ($this->useAttributes ? $this->attributesAt($value, $valueStart, $end) : $value); + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\PhpDocTagNode($tag->value, $value), $begin, $end) : new Ast\PhpDoc\PhpDocTagNode($tag->value, $value); + } + + /** + * @param list $children + */ + private function tagValue(Token $tag, array $children, int $valueStart, int $end): Ast\PhpDoc\PhpDocTagValueNode + { + $description = self::description($children); + $type = null; + $variable = null; + $isReference = false; + $isVariadic = false; + foreach ($children as $i => $child) { + if ($i === 0) { + continue; + } + + if ($child instanceof TypeNode) { + $type ??= $child; + } elseif ($child instanceof Token) { + $id = $child->id; + if ($id === $this->tVariable || $id === $this->tThis) { + $variable ??= $child->value; + } elseif ($id === $this->tReference) { + $isReference = true; + } elseif ($id === $this->tVariadic) { + $isVariadic = true; + } + } + } + + switch ($this->tagKinds[$tag->id]) { + case 'param': + /** @var string $variable */ + if ($type === null) { + return new Ast\PhpDoc\TypelessParamTagValueNode($isVariadic, $variable, $description, $isReference); + } + + return new Ast\PhpDoc\ParamTagValueNode($type, $isVariadic, $variable, $description, $isReference); + case 'var': + /** @var TypeNode $type */ + return new Ast\PhpDoc\VarTagValueNode($type, $variable ?? '', $description); + case 'return': + /** @var TypeNode $type */ + return new Ast\PhpDoc\ReturnTagValueNode($type, $description); + case 'throws': + /** @var TypeNode $type */ + return new Ast\PhpDoc\ThrowsTagValueNode($type, $description); + case 'mixin': + /** @var TypeNode $type */ + return new Ast\PhpDoc\MixinTagValueNode($type, $description); + case 'require-extends': + /** @var TypeNode $type */ + return new Ast\PhpDoc\RequireExtendsTagValueNode($type, $description); + case 'require-implements': + /** @var TypeNode $type */ + return new Ast\PhpDoc\RequireImplementsTagValueNode($type, $description); + case 'sealed': + /** @var TypeNode $type */ + return new Ast\PhpDoc\SealedTagValueNode($type, $description); + case 'self-out': + /** @var TypeNode $type */ + return new Ast\PhpDoc\SelfOutTagValueNode($type, $description); + case 'property': + /** @var TypeNode $type */ + /** @var string $variable */ + return new Ast\PhpDoc\PropertyTagValueNode($type, $variable, $description); + case 'param-out': + /** @var TypeNode $type */ + /** @var string $variable */ + return new Ast\PhpDoc\ParamOutTagValueNode($type, $variable, $description); + case 'param-closure-this': + /** @var TypeNode $type */ + /** @var string $variable */ + return new Ast\PhpDoc\ParamClosureThisTagValueNode($type, $variable, $description); + case 'param-immediately-invoked-callable': + /** @var string $variable */ + return new Ast\PhpDoc\ParamImmediatelyInvokedCallableTagValueNode($variable, $description); + case 'param-later-invoked-callable': + /** @var string $variable */ + return new Ast\PhpDoc\ParamLaterInvokedCallableTagValueNode($variable, $description); + case 'pure-unless-callable-is-impure': + /** @var string $variable */ + return new Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode($variable, $description); + case 'pure-unless-parameter-passed': + /** @var string $variable */ + return new Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode($variable, $description); + case 'deprecated': + return new Ast\PhpDoc\DeprecatedTagValueNode($description); + case 'method': + return $this->methodTagValue($children, $description, $valueStart, $end); + case 'template': + array_shift($children); + return $this->template($children, $description); + case 'extends': + case 'implements': + case 'use': + return $this->extendsTagValue($this->tagKinds[$tag->id], $children, $description, $valueStart); + case 'type-alias': + /** @var Token $alias */ + $alias = $children[1]; + /** @var TypeNode $type */ + return new Ast\PhpDoc\TypeAliasTagValueNode($alias->value, $type); + case 'type-alias-import': + /** @var Token $alias */ + $alias = $children[1]; + /** @var Token $from */ + $from = $children[3]; + $as = isset($children[5]) ? $children[5]->value : null; + + return new Ast\PhpDoc\TypeAliasImportTagValueNode( + $alias->value, + ($this->useAttributes ? $this->attributesAt(new Ast\Type\IdentifierTypeNode($from->value), $from->offset, $from->offset) : new Ast\Type\IdentifierTypeNode($from->value)), + $as, + ); + case 'assert': + return $this->assertTagValue($children, $description); + } + + throw new LogicException('Unknown tag ' . $tag->value); + } + + /** + * @param list $children + */ + private function methodTagValue(array $children, string $description, int $valueStart, int $end): Ast\PhpDoc\PhpDocTagValueNode + { + $static = null; + $type = null; + $name = null; + $templates = []; + $parameters = []; + foreach ($children as $i => $child) { + if ($i === 0) { + continue; + } + + if ($child instanceof Token) { + if ($i === 1 && $child->id === $this->tStatic) { + $static = $child; + } elseif ($type !== null && $name === null && $templates === [] && isset($this->identifiers[$child->id])) { + $name = $child; + } + } elseif ($child instanceof Ast\PhpDoc\TemplateTagValueNode) { + $templates[] = $child; + } elseif ($child instanceof Ast\PhpDoc\MethodTagValueParameterNode) { + $parameters[] = $child; + } elseif ($child instanceof TypeNode) { + $type ??= $child; + } + } + + /** @var TypeNode $type */ + if ($name !== null) { + return new Ast\PhpDoc\MethodTagValueNode($static !== null, $type, $name->value, $parameters, $description, $templates); + } + + if (!$type instanceof Ast\Type\IdentifierTypeNode) { + // A method is named by a name, never by any other type + $after = null; + $afterType = false; + foreach ($children as $child) { + if ($child === $type) { + $afterType = true; + } elseif ($afterType && $child instanceof Token) { + $after = $child; + break; + } + } + + return new Ast\PhpDoc\InvalidTagValueNode( + trim($this->textBetween($valueStart, $end), " \t"), + $this->createExceptionAt($after !== null ? $after->offset : $this->indexes[count($this->indexes) - 1], Lexer::TOKEN_IDENTIFIER), + ); + } + + $returnType = $static !== null + ? ($this->useAttributes ? $this->attributesAt(new Ast\Type\IdentifierTypeNode('static'), $static->offset, $static->offset, true) : new Ast\Type\IdentifierTypeNode('static')) + : null; + + return new Ast\PhpDoc\MethodTagValueNode(false, $returnType, $type->name, $parameters, $description, $templates); + } + + /** + * @param list $children + */ + private function extendsTagValue(string $kind, array $children, string $description, int $start): Ast\PhpDoc\PhpDocTagValueNode + { + /** @var Token $name */ + $name = $children[1]; + /** @var Fragment $generic */ + $generic = $children[2]; + $type = ($this->useAttributes ? $this->attributesAt( + new Ast\Type\GenericTypeNode($this->identifier($name), $generic->a, $generic->b), + $start, + $generic->end, + true, + ) : new Ast\Type\GenericTypeNode($this->identifier($name), $generic->a, $generic->b)); + + switch ($kind) { + case 'extends': + return new Ast\PhpDoc\ExtendsTagValueNode($type, $description); + case 'implements': + return new Ast\PhpDoc\ImplementsTagValueNode($type, $description); + default: + return new Ast\PhpDoc\UsesTagValueNode($type, $description); + } + } + + /** + * @param list $children + */ + private function assertTagValue(array $children, string $description): Ast\PhpDoc\PhpDocTagValueNode + { + $isNegated = false; + $isEquality = false; + $type = null; + $parameter = null; + $member = null; + $isMethod = false; + foreach ($children as $i => $child) { + if ($i === 0) { + continue; + } + + if ($child instanceof TypeNode) { + $type ??= $child; + } elseif ($child instanceof Token) { + $id = $child->id; + if ($type === null) { + if ($id === $this->tNegated) { + $isNegated = true; + } elseif ($id === $this->tEqual) { + $isEquality = true; + } + } elseif ($parameter === null) { + $parameter = $child->value; + } elseif ($id === $this->tOpenParentheses || $id === $this->tOpenParenthesesWs) { + $isMethod = true; + } elseif ($member === null && isset($this->identifiers[$id])) { + $member = $child->value; + } + } + } + + /** @var TypeNode $type */ + /** @var string $parameter */ + if ($member === null) { + return new Ast\PhpDoc\AssertTagValueNode($type, $parameter, $isNegated, $description, $isEquality); + } + + if ($isMethod) { + return new Ast\PhpDoc\AssertTagMethodValueNode($type, $parameter, $member, $isNegated, $description, $isEquality); + } + + return new Ast\PhpDoc\AssertTagPropertyValueNode($type, $parameter, $member, $isNegated, $description, $isEquality); + } + + /** + * @param list $children + */ + protected function reduceMethodParameter(int $begin, int $end, $children): Ast\PhpDoc\MethodTagValueParameterNode + { + $type = null; + $isReference = false; + $isVariadic = false; + $name = ''; + $default = null; + foreach ($children as $child) { + if ($child instanceof TypeNode) { + $type = $child; + } elseif ($child instanceof ConstExprNode) { + $default = $child; + } elseif ($child instanceof Token) { + $id = $child->id; + if ($id === $this->tReference) { + $isReference = true; + } elseif ($id === $this->tVariadic) { + $isVariadic = true; + } elseif ($id === $this->tVariable) { + $name = $child->value; + } + } + } + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\MethodTagValueParameterNode($type, $isReference, $isVariadic, $name, $default), $begin, $end) : new Ast\PhpDoc\MethodTagValueParameterNode($type, $isReference, $isVariadic, $name, $default); + } + + /** + * @param list $children + */ + protected function reduceGenericTag(int $begin, int $end, $children): Ast\PhpDoc\PhpDocTagNode + { + /** @var Token $tag */ + $tag = $children[0]; + $valueStart = $this->nextIndex($tag->offset); + $value = ($this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\GenericTagValueNode(self::description($children)), $valueStart, $end) : new Ast\PhpDoc\GenericTagValueNode(self::description($children))); + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\PhpDocTagNode($tag->value, $value), $begin, $end) : new Ast\PhpDoc\PhpDocTagNode($tag->value, $value); + } + + /** + * @param list $children + */ + protected function reduceDoctrineTag(int $begin, int $end, $children): Ast\PhpDoc\PhpDocTagNode + { + /** @var Token $tag */ + $tag = $children[0]; + $valueStart = $this->nextIndex($tag->offset); + + $arguments = []; + $annotationEnd = $valueStart - 1; + foreach ($children as $i => $child) { + if ($child instanceof Doctrine\DoctrineArgument) { + $arguments[] = $child; + } elseif ($i > 0 && $child instanceof Token) { + // the closing parenthesis is the last token of the arguments + $annotationEnd = $child->offset; + } + } + + $annotation = ($this->useAttributes ? $this->attributesAt(new Doctrine\DoctrineAnnotation($tag->value, $arguments), $valueStart, $annotationEnd) : new Doctrine\DoctrineAnnotation($tag->value, $arguments)); + $value = ($this->useAttributes ? $this->attributesAt( + new Doctrine\DoctrineTagValueNode($annotation, self::description($children)), + $valueStart, + $end, + ) : new Doctrine\DoctrineTagValueNode($annotation, self::description($children))); + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\PhpDocTagNode($tag->value, $value), $begin, $end) : new Ast\PhpDoc\PhpDocTagNode($tag->value, $value); + } + + /** + * A tag whose value cannot be read: the rest of its line is its value. + * + * @param list $children + */ + protected function reduceInvalidTag(int $begin, int $end, $children): Ast\PhpDoc\PhpDocTagNode + { + /** @var Token $tag */ + $tag = $children[0]; + $valueStart = $this->nextIndex($tag->offset); + + $exception = $this->explain(isset($this->tagKinds[$tag->id]) ? 'KnownTag' : 'UnreadTagChild', $tag->offset); + $value = ($this->useAttributes ? $this->attributesAt( + new Ast\PhpDoc\InvalidTagValueNode(self::description($children), $exception), + $valueStart, + $end, + ) : new Ast\PhpDoc\InvalidTagValueNode(self::description($children), $exception)); + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\PhpDocTagNode($tag->value, $value), $begin, $end) : new Ast\PhpDoc\PhpDocTagNode($tag->value, $value); + } + + /** + * A type alias whose type cannot be read. + * + * @param list $children + */ + protected function reduceInvalidTypeAliasTag(int $begin, int $end, $children): Ast\PhpDoc\PhpDocTagNode + { + /** @var Token $tag */ + $tag = $children[0]; + /** @var Token $alias */ + $alias = $children[1]; + $typeStart = $this->nextIndex($alias->offset); + if (isset($children[2]) && $children[2] instanceof Token && $children[2]->id === $this->tEqual) { + $typeStart = $this->nextIndex($children[2]->offset); + } + + $exception = $this->explainTypeAlias($typeStart); + $type = ($this->useAttributes ? $this->attributesAt(new Ast\Type\InvalidTypeNode($exception), $typeStart, $end) : new Ast\Type\InvalidTypeNode($exception)); + + $valueStart = $this->nextIndex($tag->offset); + $value = ($this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\TypeAliasTagValueNode($alias->value, $type), $valueStart, $end) : new Ast\PhpDoc\TypeAliasTagValueNode($alias->value, $type)); + + return $this->useAttributes ? $this->attributesAt(new Ast\PhpDoc\PhpDocTagNode($tag->value, $value), $begin, $end) : new Ast\PhpDoc\PhpDocTagNode($tag->value, $value); + } + + private function explainTypeAlias(int $index): ParserException + { + $state = $this->saveReading(); + try { + if (!$this->parseRule(self::RULES['Type'], $this->position($index), false)) { + return $this->createException($this->failure()); + } + + $last = count($this->indexes) - 1; + + return $this->createExceptionAt($this->indexes[$this->ids[$this->p] !== -1 ? $this->p : $last], Lexer::TOKEN_PHPDOC_EOL); + } finally { + $this->restoreReading($state); + } + } + + // ------------------------------------------------------------------------- + // Doctrine annotations + // ------------------------------------------------------------------------- + + /** + * @param list $children + */ + protected function reduceDoctrineArgument(int $begin, int $end, $children): Doctrine\DoctrineArgument + { + $key = null; + $value = null; + $hasKey = false; + foreach ($children as $child) { + if ($child instanceof Token) { + if ($child->id === $this->tEqual) { + $hasKey = true; + } + } else { + $value = $child; + } + } + + if ($hasKey) { + /** @var Token $name */ + $name = $children[0]; + $key = ($this->useAttributes ? $this->attributesAt(new Ast\Type\IdentifierTypeNode($name->value), $name->offset, $name->offset, false, true) : new Ast\Type\IdentifierTypeNode($name->value)); + } + + /** @var Doctrine\DoctrineAnnotation|Ast\Type\IdentifierTypeNode|Doctrine\DoctrineArray|ConstExprNode $value */ + return $this->useAttributes ? $this->attributesAt(new Doctrine\DoctrineArgument($key, $value), $begin, $end, false, true) : new Doctrine\DoctrineArgument($key, $value); + } + + /** + * @param list $children + */ + protected function reduceDoctrineNestedAnnotation(int $begin, int $end, $children): Doctrine\DoctrineAnnotation + { + $arguments = []; + foreach ($children as $child) { + if (!$child instanceof Doctrine\DoctrineArgument) { + continue; + } + + $arguments[] = $child; + } + + return $this->useAttributes ? $this->attributesAt(new Doctrine\DoctrineAnnotation($children[0]->value, $arguments), $begin, $end, false, true) : new Doctrine\DoctrineAnnotation($children[0]->value, $arguments); + } + + /** + * @param list $children + */ + protected function reduceDoctrineArray(int $begin, int $end, $children): Doctrine\DoctrineArray + { + $items = []; + foreach ($children as $child) { + if (!$child instanceof Doctrine\DoctrineArrayItem) { + continue; + } + + $items[] = $child; + } + + return $this->useAttributes ? $this->attributesAt(new Doctrine\DoctrineArray($items), $begin, $end, false, true) : new Doctrine\DoctrineArray($items); + } + + /** + * @param list $children + */ + protected function reduceDoctrineArrayItem(int $begin, int $end, $children): Doctrine\DoctrineArrayItem + { + $nodes = []; + foreach ($children as $child) { + if ($child instanceof Token) { + continue; + } + + $nodes[] = $child; + } + + $item = count($nodes) === 2 + ? new Doctrine\DoctrineArrayItem($nodes[0], $nodes[1]) + : new Doctrine\DoctrineArrayItem(null, $nodes[0]); + + return $this->useAttributes ? $this->attributesAt($item, $begin, $end, false, true) : $item; + } + + /** + * @param list $children + */ + protected function reduceDoctrineArrayKey(int $begin, int $end, $children): Node + { + $first = $children[0]; + if ($first instanceof Node) { + return $first; + } + + if ($first->id === $this->tInteger) { + $key = new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $first->value)); + } else { + $key = $this->stringOrIdentifier($first); + } + + return $this->useAttributes ? $this->attributesAt($key, $begin, $end, false, true) : $key; + } + + /** + * @param list $children + */ + protected function reduceDoctrineIdentifier(int $begin, int $end, $children): Ast\Type\IdentifierTypeNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\Type\IdentifierTypeNode($children[0]->value), $begin, $end, false, true) : new Ast\Type\IdentifierTypeNode($children[0]->value); + } + + /** + * @param list $children + */ + protected function reduceDoctrineConstantFetch(int $begin, int $end, $children): ConstExprNode + { + return $this->attributesAt($this->constantFetch($children), $begin, $end, false, true); + } + + /** + * @param list $children + */ + protected function reduceDoctrineFloat(int $begin, int $end, $children): ConstExprNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprFloatNode(str_replace('_', '', $children[0]->value)), $begin, $end, false, true) : new Ast\ConstExpr\ConstExprFloatNode(str_replace('_', '', $children[0]->value)); + } + + /** + * @param list $children + */ + protected function reduceDoctrineInteger(int $begin, int $end, $children): ConstExprNode + { + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $children[0]->value)), $begin, $end, false, true) : new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $children[0]->value)); + } + + /** + * @param list $children + */ + protected function reduceDoctrineString(int $begin, int $end, $children): ConstExprNode + { + $text = ''; + foreach ($children as $child) { + $text .= $child->value; + } + + return $this->useAttributes ? $this->attributesAt(new Ast\ConstExpr\DoctrineConstExprStringNode(Ast\ConstExpr\DoctrineConstExprStringNode::unescape($text)), $begin, $end, false, true) : new Ast\ConstExpr\DoctrineConstExprStringNode(Ast\ConstExpr\DoctrineConstExprStringNode::unescape($text)); + } + +} diff --git a/src/Parser/ConstExprParser.php b/src/Parser/ConstExprParser.php index dd08cfd4..a7e7c6fe 100644 --- a/src/Parser/ConstExprParser.php +++ b/src/Parser/ConstExprParser.php @@ -5,22 +5,20 @@ use PHPStan\PhpDocParser\Ast; use PHPStan\PhpDocParser\Lexer\Lexer; use PHPStan\PhpDocParser\ParserConfig; -use function str_replace; -use function strtolower; class ConstExprParser { private ParserConfig $config; - private bool $parseDoctrineStrings; + private AstBuilder $builder; public function __construct( ParserConfig $config ) { $this->config = $config; - $this->parseDoctrineStrings = false; + $this->builder = new AstBuilder($config); } /** @@ -28,202 +26,16 @@ public function __construct( */ public function toDoctrine(): self { - $self = new self($this->config); - $self->parseDoctrineStrings = true; - return $self; + return new self($this->config); } + /** + * @throws ParserException + */ public function parse(TokenIterator $tokens): Ast\ConstExpr\ConstExprNode { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_FLOAT)) { - $value = $tokens->currentTokenValue(); - $tokens->next(); - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprFloatNode(str_replace('_', '', $value)), - $startLine, - $startIndex, - ); - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) { - $value = $tokens->currentTokenValue(); - $tokens->next(); - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $value)), - $startLine, - $startIndex, - ); - } - - if ($this->parseDoctrineStrings && $tokens->isCurrentTokenType(Lexer::TOKEN_DOCTRINE_ANNOTATION_STRING)) { - $value = $tokens->currentTokenValue(); - $tokens->next(); - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\DoctrineConstExprStringNode(Ast\ConstExpr\DoctrineConstExprStringNode::unescape($value)), - $startLine, - $startIndex, - ); - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING, Lexer::TOKEN_DOUBLE_QUOTED_STRING)) { - if ($this->parseDoctrineStrings) { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) { - throw new ParserException( - $tokens->currentTokenValue(), - $tokens->currentTokenType(), - $tokens->currentTokenOffset(), - Lexer::TOKEN_DOUBLE_QUOTED_STRING, - null, - $tokens->currentTokenLine(), - ); - } - - $value = $tokens->currentTokenValue(); - $tokens->next(); - - return $this->enrichWithAttributes( - $tokens, - $this->parseDoctrineString($value, $tokens), - $startLine, - $startIndex, - ); - } - - $value = StringUnescaper::unescapeString($tokens->currentTokenValue()); - $type = $tokens->currentTokenType(); - $tokens->next(); - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprStringNode( - $value, - $type === Lexer::TOKEN_SINGLE_QUOTED_STRING - ? Ast\ConstExpr\ConstExprStringNode::SINGLE_QUOTED - : Ast\ConstExpr\ConstExprStringNode::DOUBLE_QUOTED, - ), - $startLine, - $startIndex, - ); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) { - $identifier = $tokens->currentTokenValue(); - $tokens->next(); - - switch (strtolower($identifier)) { - case 'true': - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprTrueNode(), - $startLine, - $startIndex, - ); - case 'false': - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprFalseNode(), - $startLine, - $startIndex, - ); - case 'null': - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprNullNode(), - $startLine, - $startIndex, - ); - case 'array': - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES); - return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_PARENTHESES, $startIndex); - } - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_COLON)) { - $classConstantName = ''; - $lastType = null; - while (true) { - if ($lastType !== Lexer::TOKEN_IDENTIFIER && $tokens->currentTokenType() === Lexer::TOKEN_IDENTIFIER) { - $classConstantName .= $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - $lastType = Lexer::TOKEN_IDENTIFIER; - - continue; - } - - if ($lastType !== Lexer::TOKEN_WILDCARD && $tokens->tryConsumeTokenType(Lexer::TOKEN_WILDCARD)) { - $classConstantName .= '*'; - $lastType = Lexer::TOKEN_WILDCARD; - - if ($tokens->getSkippedHorizontalWhiteSpaceIfAny() !== '') { - break; - } - - continue; - } - - if ($lastType === null) { - // trigger parse error if nothing valid was consumed - $tokens->consumeTokenType(Lexer::TOKEN_WILDCARD); - } - - break; - } - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName), - $startLine, - $startIndex, - ); - - } - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstFetchNode('', $identifier), - $startLine, - $startIndex, - ); - - } elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_SQUARE_BRACKET, $startIndex); - } - - throw new ParserException( - $tokens->currentTokenValue(), - $tokens->currentTokenType(), - $tokens->currentTokenOffset(), - Lexer::TOKEN_IDENTIFIER, - null, - $tokens->currentTokenLine(), - ); - } - - private function parseArray(TokenIterator $tokens, int $endToken, int $startIndex): Ast\ConstExpr\ConstExprArrayNode - { - $items = []; - - $startLine = $tokens->currentTokenLine(); - - if (!$tokens->tryConsumeTokenType($endToken)) { - do { - $items[] = $this->parseArrayItem($tokens); - } while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA) && !$tokens->isCurrentTokenType($endToken)); - $tokens->consumeTokenType($endToken); - } - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprArrayNode($items), - $startLine, - $startIndex, - ); + /** @var Ast\ConstExpr\ConstExprNode */ + return $this->builder->read($tokens, 'ConstantExpr'); } /** @@ -242,48 +54,4 @@ public function parseDoctrineString(string $text, TokenIterator $tokens): Ast\Co return new Ast\ConstExpr\DoctrineConstExprStringNode(Ast\ConstExpr\DoctrineConstExprStringNode::unescape($text)); } - private function parseArrayItem(TokenIterator $tokens): Ast\ConstExpr\ConstExprArrayItemNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - $expr = $this->parse($tokens); - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_ARROW)) { - $key = $expr; - $value = $this->parse($tokens); - - } else { - $key = null; - $value = $expr; - } - - return $this->enrichWithAttributes( - $tokens, - new Ast\ConstExpr\ConstExprArrayItemNode($key, $value), - $startLine, - $startIndex, - ); - } - - /** - * @template T of Ast\ConstExpr\ConstExprNode - * @param T $node - * @return T - */ - private function enrichWithAttributes(TokenIterator $tokens, Ast\ConstExpr\ConstExprNode $node, int $startLine, int $startIndex): Ast\ConstExpr\ConstExprNode - { - if ($this->config->useLinesAttributes) { - $node->setAttribute(Ast\Attribute::START_LINE, $startLine); - $node->setAttribute(Ast\Attribute::END_LINE, $tokens->currentTokenLine()); - } - - if ($this->config->useIndexAttributes) { - $node->setAttribute(Ast\Attribute::START_INDEX, $startIndex); - $node->setAttribute(Ast\Attribute::END_INDEX, $tokens->endIndexOfLastRelevantToken()); - } - - return $node; - } - } diff --git a/src/Parser/Generated/GeneratedParser.php b/src/Parser/Generated/GeneratedParser.php new file mode 100644 index 00000000..ba820105 --- /dev/null +++ b/src/Parser/Generated/GeneratedParser.php @@ -0,0 +1,23304 @@ + the identifier of each rule a reading may start at */ + public const RULES = ['PhpDoc' => 0, 'UnreadTagChild' => 10, 'PhpDocChild' => 189, 'KnownTag' => 190, 'Type' => 199, 'ConstantExpr' => 340]; + + /** @var array the identifier of each token */ + public const TOKENS = ['T_HORIZONTAL_WS' => 0, 'T_KEYWORD_CONTRAVARIANT' => 1, 'T_KEYWORD_COVARIANT' => 2, 'T_KEYWORD_NON_EMPTY_ARRAY' => 3, 'T_KEYWORD_NON_EMPTY_LIST' => 4, 'T_KEYWORD_SUPER' => 5, 'T_KEYWORD_OBJECT' => 6, 'T_KEYWORD_ARRAY' => 7, 'T_KEYWORD_LIST' => 8, 'T_KEYWORD_STATIC' => 9, 'T_KEYWORD_FROM' => 10, 'T_KEYWORD_NOT' => 11, 'T_KEYWORD_IS' => 12, 'T_KEYWORD_OF' => 13, 'T_KEYWORD_AS' => 14, 'T_KEYWORD_FALSE' => 15, 'T_KEYWORD_TRUE' => 16, 'T_KEYWORD_NULL' => 17, 'T_KEYWORD_ARRAY_ANY_CASE' => 18, 'T_FLOAT' => 19, 'T_INTEGER' => 20, 'T_SINGLE_QUOTED_STRING' => 21, 'T_DOUBLE_QUOTED_STRING' => 22, 'T_DOCTRINE_ANNOTATION_STRING' => 23, 'T_IDENTIFIER' => 24, 'T_THIS_VARIABLE' => 25, 'T_VARIABLE' => 26, 'T_REFERENCE' => 27, 'T_UNION' => 28, 'T_INTERSECTION' => 29, 'T_NULLABLE' => 30, 'T_NEGATED' => 31, 'T_OPEN_PARENTHESES' => 32, 'T_CLOSE_PARENTHESES' => 33, 'T_OPEN_ANGLE_BRACKET' => 34, 'T_CLOSE_ANGLE_BRACKET' => 35, 'T_OPEN_SQUARE_BRACKET' => 36, 'T_CLOSE_SQUARE_BRACKET' => 37, 'T_OPEN_CURLY_BRACKET' => 38, 'T_CLOSE_CURLY_BRACKET' => 39, 'T_COMMA' => 40, 'T_COMMENT' => 41, 'T_VARIADIC' => 42, 'T_DOUBLE_COLON' => 43, 'T_DOUBLE_ARROW' => 44, 'T_ARROW' => 45, 'T_EQUAL' => 46, 'T_COLON' => 47, 'T_OPEN_PHPDOC' => 48, 'T_CLOSE_PHPDOC' => 49, 'T_WILDCARD' => 50, 'T_TAG_PARAM_IMMEDIATELY_INVOKED_CALLABLE' => 51, 'T_TAG_PURE_UNLESS_CALLABLE_IS_IMPURE' => 52, 'T_TAG_PURE_UNLESS_PARAMETER_PASSED' => 53, 'T_TAG_PARAM_LATER_INVOKED_CALLABLE' => 54, 'T_TAG_PARAM_CLOSURE_THIS' => 55, 'T_TAG_REQUIRE_IMPLEMENTS' => 56, 'T_TAG_REQUIRE_EXTENDS' => 57, 'T_TAG_TYPE_ALIAS_IMPORT' => 58, 'T_TAG_ASSERT' => 59, 'T_TAG_SELF_OUT' => 60, 'T_TAG_SEALED' => 61, 'T_TAG_TEMPLATE' => 62, 'T_TAG_PROPERTY' => 63, 'T_TAG_IMPLEMENTS' => 64, 'T_TAG_DEPRECATED' => 65, 'T_TAG_TYPE_ALIAS' => 66, 'T_TAG_PARAM_OUT' => 67, 'T_TAG_EXTENDS' => 68, 'T_TAG_METHOD' => 69, 'T_TAG_RETURN' => 70, 'T_TAG_THROWS' => 71, 'T_TAG_PARAM' => 72, 'T_TAG_MIXIN' => 73, 'T_TAG_USE' => 74, 'T_TAG_VAR' => 75, 'T_PHPDOC_TAG_WS' => 76, 'T_PHPDOC_TAG' => 77, 'T_DOCTRINE_TAG_WS' => 78, 'T_DOCTRINE_TAG' => 79, 'T_PHPDOC_EOL' => 80, 'T_OTHER' => 81, 'T_OPEN_PARENTHESES_WS' => 82, 'T_OPEN_CURLY_BRACKET_WS' => 83, 'T_OPEN_SQUARE_BRACKET_WS' => 84, 'T_WILDCARD_WS' => 85, 'T_OPEN_ANGLE_BRACKET_HTML' => 86]; + + /** @var array the name each token is expected by */ + public const EXPECTATIONS = ['T_HORIZONTAL_WS', 'T_KEYWORD_CONTRAVARIANT', 'T_KEYWORD_COVARIANT', 'T_KEYWORD_NON_EMPTY_ARRAY', 'T_KEYWORD_NON_EMPTY_LIST', 'T_KEYWORD_SUPER', 'T_KEYWORD_OBJECT', 'T_KEYWORD_ARRAY', 'T_KEYWORD_LIST', 'T_KEYWORD_STATIC', 'T_KEYWORD_FROM', 'T_KEYWORD_NOT', 'T_KEYWORD_IS', 'T_KEYWORD_OF', 'T_KEYWORD_AS', 'T_KEYWORD_FALSE', 'T_KEYWORD_TRUE', 'T_KEYWORD_NULL', 'T_KEYWORD_ARRAY_ANY_CASE', 'T_FLOAT', 'T_INTEGER', 'T_SINGLE_QUOTED_STRING', 'T_DOUBLE_QUOTED_STRING', 'T_DOCTRINE_ANNOTATION_STRING', 'T_IDENTIFIER', 'T_THIS_VARIABLE', 'T_VARIABLE', 'T_REFERENCE', 'T_UNION', 'T_INTERSECTION', 'T_NULLABLE', 'T_NEGATED', 'T_OPEN_PARENTHESES', 'T_CLOSE_PARENTHESES', 'T_OPEN_ANGLE_BRACKET', 'T_CLOSE_ANGLE_BRACKET', 'T_OPEN_SQUARE_BRACKET', 'T_CLOSE_SQUARE_BRACKET', 'T_OPEN_CURLY_BRACKET', 'T_CLOSE_CURLY_BRACKET', 'T_COMMA', 'T_COMMENT', 'T_VARIADIC', 'T_DOUBLE_COLON', 'T_DOUBLE_ARROW', 'T_ARROW', 'T_EQUAL', 'T_COLON', 'T_OPEN_PHPDOC', 'T_CLOSE_PHPDOC', 'T_WILDCARD', 'T_TAG_PARAM_IMMEDIATELY_INVOKED_CALLABLE', 'T_TAG_PURE_UNLESS_CALLABLE_IS_IMPURE', 'T_TAG_PURE_UNLESS_PARAMETER_PASSED', 'T_TAG_PARAM_LATER_INVOKED_CALLABLE', 'T_TAG_PARAM_CLOSURE_THIS', 'T_TAG_REQUIRE_IMPLEMENTS', 'T_TAG_REQUIRE_EXTENDS', 'T_TAG_TYPE_ALIAS_IMPORT', 'T_TAG_ASSERT', 'T_TAG_SELF_OUT', 'T_TAG_SEALED', 'T_TAG_TEMPLATE', 'T_TAG_PROPERTY', 'T_TAG_IMPLEMENTS', 'T_TAG_DEPRECATED', 'T_TAG_TYPE_ALIAS', 'T_TAG_PARAM_OUT', 'T_TAG_EXTENDS', 'T_TAG_METHOD', 'T_TAG_RETURN', 'T_TAG_THROWS', 'T_TAG_PARAM', 'T_TAG_MIXIN', 'T_TAG_USE', 'T_TAG_VAR', 'T_PHPDOC_TAG_WS', 'T_PHPDOC_TAG', 'T_DOCTRINE_TAG_WS', 'T_DOCTRINE_TAG', 'T_PHPDOC_EOL', 'T_OTHER', 'T_OPEN_PARENTHESES_WS', 'T_OPEN_CURLY_BRACKET_WS', 'T_OPEN_SQUARE_BRACKET_WS', 'T_WILDCARD_WS', 'T_OPEN_ANGLE_BRACKET_HTML', '/[^\\s]++/']; + + /** the pattern of the lexer, marking each token by its identifier */ + public const LEXER_PATTERN = '~(?:[\\x09\\x20]++)(*MARK:0)|(?:[+\\-]?(?:(?:[0-9]++(?:_[0-9]++)*\\.[0-9]*+(?:_[0-9]++)*(?:e[+\\-]?[0-9]++(?:_[0-9]++)*)?)|(?:[0-9]*+(?:_[0-9]++)*\\.[0-9]++(?:_[0-9]++)*(?:e[+\\-]?[0-9]++(?:_[0-9]++)*)?)|(?:[0-9]++(?:_[0-9]++)*e[+\\-]?[0-9]++(?:_[0-9]++)*)))(*MARK:19)|(?:[+\\-]?(?:(?:0b[0-1]++(?:_[0-1]++)*)|(?:0o[0-7]++(?:_[0-7]++)*)|(?:0x[0-9a-f]++(?:_[0-9a-f]++)*)|(?:[0-9]++(?:_[0-9]++)*)))(*MARK:20)|(?:\'(?:\\\\[^\\r\\n]|[^\'\\r\\n\\\\])*+\')(*MARK:21)|(?:"(?:\\\\[^\\r\\n]|[^"\\r\\n\\\\])*+")(*MARK:22)|(?:"(?:""|[^"])*+")(*MARK:23)|(?:(?:[\\\\]?+[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF-]*+)++)(*MARK:24)|(?:\\$this(?![0-9a-z_\\x80-\\xFF]))(*MARK:25)|(?:\\$[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF]*+)(*MARK:26)|(?:&(?=\\s*+(?:[,=)]|\\.\\.\\.|(?:\\$(?!this(?![0-9a-z_\\x80-\\xFF]))))))(*MARK:27)|(?:\\|)(*MARK:28)|(?:&)(*MARK:29)|(?:\\?)(*MARK:30)|(?:!)(*MARK:31)|(?:\\()(*MARK:32)|(?:\\))(*MARK:33)|(?:<)(*MARK:34)|(?:>)(*MARK:35)|(?:\\[)(*MARK:36)|(?:\\])(*MARK:37)|(?:\\{)(*MARK:38)|(?:\\})(*MARK:39)|(?:,)(*MARK:40)|(?://[^\\r\\n]*(?=\\n|\\r|\\*/))(*MARK:41)|(?:\\.\\.\\.)(*MARK:42)|(?:::)(*MARK:43)|(?:=>)(*MARK:44)|(?:->)(*MARK:45)|(?:=)(*MARK:46)|(?::)(*MARK:47)|(?:/\\*\\*(?=\\s)\\x20?+)(*MARK:48)|(?:\\*/)(*MARK:49)|(?:\\*)(*MARK:50)|(?:@(?:[a-z][a-z0-9-\\\\]+:)?[a-z][a-z0-9-\\\\]*+)(*MARK:77)|(?:@[a-z_\\\\][a-z0-9_:\\\\]*[a-z_][a-z0-9_]*)(*MARK:79)|(?:\\r?+\\n[\\x09\\x20]*+(?:\\*(?!/)\\x20?+)?)(*MARK:80)|(?:(?:(?!\\*/)[^\\s])++)(*MARK:81)~Asi'; + + /** @var array the type of the lexer each token it reads is, by the identifier */ + public const LEXER_TYPES = [0 => 27, 19 => 19, 20 => 20, 21 => 21, 22 => 22, 23 => 23, 24 => 24, 25 => 25, 26 => 26, 27 => 0, 28 => 1, 29 => 2, 30 => 3, 31 => 35, 32 => 4, 33 => 5, 34 => 6, 35 => 7, 36 => 8, 37 => 9, 38 => 33, 39 => 34, 40 => 10, 41 => 37, 42 => 11, 43 => 12, 44 => 13, 45 => 36, 46 => 14, 47 => 31, 48 => 15, 49 => 16, 50 => 32, 77 => 17, 79 => 18, 80 => 28, 81 => 29]; + + private const T00b73ddb = [7=>true,15=>true,16=>true,17=>true,18=>true]; + private const T02ca7bff = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,24=>true,32=>true,34=>true,82=>true,86=>true]; + private const T05cf281c = [1=>true,2=>true]; + private const T0979f8dc = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,23=>true,24=>true,25=>true,26=>true,27=>true,28=>true,29=>true,30=>true,31=>true,32=>true,33=>true,34=>true,35=>true,36=>true,37=>true,38=>true,39=>true,40=>true,41=>true,42=>true,43=>true,44=>true,45=>true,46=>true,47=>true,48=>true,50=>true,81=>true,82=>true,83=>true,84=>true,85=>true,86=>true]; + private const T1ad6c327 = [7=>true,18=>true]; + private const T1e2ed78c = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,22=>true,23=>true,24=>true,38=>true,51=>true,52=>true,53=>true,54=>true,55=>true,56=>true,57=>true,58=>true,59=>true,60=>true,61=>true,62=>true,63=>true,64=>true,65=>true,66=>true,67=>true,68=>true,69=>true,70=>true,71=>true,72=>true,73=>true,74=>true,75=>true,76=>true,77=>true,78=>true,79=>true,83=>true]; + private const T1e81050f = [7=>true,18=>true,36=>true,84=>true]; + private const T3bf4df75 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true,25=>true,26=>true,27=>true,30=>true,32=>true,42=>true,82=>true]; + private const T4d756b3a = [50=>true,85=>true]; + private const T7dfbf2bf = [22=>true,23=>true]; + private const T29c7f960 = [25=>true,26=>true]; + private const T34c34eee = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,24=>true,30=>true,32=>true,82=>true]; + private const T46ee5f48 = [78=>true,79=>true]; + private const T50fd39f8 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true,25=>true,30=>true,32=>true,42=>true,82=>true]; + private const T53b29bff = [49=>true,80=>true]; + private const T61cd0e44 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,23=>true,24=>true,25=>true,26=>true,27=>true,28=>true,29=>true,30=>true,31=>true,32=>true,33=>true,34=>true,35=>true,36=>true,37=>true,38=>true,39=>true,40=>true,41=>true,42=>true,43=>true,44=>true,45=>true,46=>true,47=>true,48=>true,50=>true,51=>true,52=>true,53=>true,54=>true,55=>true,56=>true,57=>true,58=>true,59=>true,60=>true,61=>true,62=>true,63=>true,64=>true,65=>true,66=>true,67=>true,68=>true,69=>true,70=>true,71=>true,72=>true,73=>true,74=>true,75=>true,76=>true,77=>true,78=>true,79=>true,81=>true,82=>true,83=>true,84=>true,85=>true,86=>true]; + private const T69bf8cc4 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true,36=>true,84=>true]; + private const T83e30518 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,24=>true]; + private const T195b3f33 = [49=>true,51=>true,52=>true,53=>true,54=>true,55=>true,56=>true,57=>true,58=>true,59=>true,60=>true,61=>true,62=>true,63=>true,64=>true,65=>true,66=>true,67=>true,68=>true,69=>true,70=>true,71=>true,72=>true,73=>true,74=>true,75=>true,76=>true,77=>true,78=>true,79=>true]; + private const T553dc07b = [26=>true,27=>true,42=>true]; + private const T648acf56 = [28=>true,29=>true,32=>true,34=>true,36=>true,41=>true,43=>true,80=>true,82=>true,84=>true]; + private const T885cd349 = [36=>true,84=>true]; + private const T977f027a = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true,25=>true,32=>true,82=>true]; + private const T1490fe7f = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,23=>true,24=>true,38=>true,51=>true,52=>true,53=>true,54=>true,55=>true,56=>true,57=>true,58=>true,59=>true,60=>true,61=>true,62=>true,63=>true,64=>true,65=>true,66=>true,67=>true,68=>true,69=>true,70=>true,71=>true,72=>true,73=>true,74=>true,75=>true,76=>true,77=>true,78=>true,79=>true,83=>true]; + private const T4546fd6c = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true]; + private const T5448ab4c = [41=>true,80=>true]; + private const T7680fe2e = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true,25=>true,30=>true,32=>true,82=>true]; + private const T7726a0df = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,20=>true,21=>true,22=>true,23=>true,24=>true]; + private const T8458d590 = [28=>true,29=>true,41=>true,80=>true]; + private const T34048a70 = [38=>true,83=>true]; + private const T942497bd = [76=>true,77=>true,78=>true,79=>true]; + private const T9373805c = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,24=>true,26=>true,27=>true,30=>true,32=>true,42=>true,82=>true]; + private const T96867045 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,24=>true]; + private const Ta8d79561 = [3=>true,4=>true,8=>true]; + private const Ta7068161 = [46=>true,47=>true]; + private const Tb3a20a39 = [76=>true,78=>true]; + private const Tb3cd2a63 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true,25=>true,30=>true,32=>true,50=>true,82=>true,85=>true]; + private const Tb46fb4f7 = [34=>true,86=>true]; + private const Tc8c984b6 = [28=>true,29=>true]; + private const Tc8cfa1df = [32=>true,82=>true]; + private const Tcd64b9c0 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,19=>true,20=>true,21=>true,22=>true,24=>true,25=>true,26=>true,30=>true,32=>true,82=>true]; + private const Tce49e0fc = [51=>true,52=>true,53=>true,54=>true,55=>true,56=>true,57=>true,58=>true,59=>true,60=>true,61=>true,62=>true,63=>true,64=>true,65=>true,66=>true,67=>true,68=>true,69=>true,70=>true,71=>true,72=>true,73=>true,74=>true,75=>true]; + private const Tce797685 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,20=>true,21=>true,22=>true,24=>true]; + private const Td08a6883 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,24=>true]; + private const Td08f0236 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,24=>true,50=>true,85=>true]; + private const Td8017923 = [1=>true,2=>true,3=>true,4=>true,5=>true,6=>true,7=>true,8=>true,9=>true,10=>true,11=>true,12=>true,13=>true,14=>true,15=>true,16=>true,17=>true,18=>true,21=>true,22=>true,24=>true]; + private const Tf4b693bf = [51=>true,52=>true,53=>true,54=>true,55=>true,56=>true,57=>true,58=>true,59=>true,60=>true,61=>true,62=>true,63=>true,64=>true,65=>true,66=>true,67=>true,68=>true,69=>true,70=>true,71=>true,72=>true,73=>true,74=>true,75=>true,76=>true,77=>true,78=>true,79=>true]; + private const Tf6aec6a4 = [76=>true,77=>true]; + private const Tf86de613 = [32=>true,34=>true,82=>true,86=>true]; + + /** the tokens each rule is expected to begin with */ + private const EXPECTED = [0=>[48],1=>[48],3=>[80],7=>[49],8=>[76,77,78,79],9=>[76,77,78,79],10=>[76,77,78,79],11=>[76,77],12=>[76,77],13=>[77],14=>[76],16=>[32,82],17=>[32],18=>[82],21=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,81,82,83,84,85,86],22=>[24],23=>[12],24=>[11],25=>[9],26=>[10],27=>[13],28=>[14],29=>[5],30=>[2],31=>[1],32=>[7],33=>[18],34=>[8],35=>[3],36=>[4],37=>[6],38=>[16],39=>[15],40=>[17],41=>[19],42=>[20],43=>[21],44=>[22],45=>[23],46=>[25],47=>[26],48=>[27],49=>[28],50=>[29],51=>[30],52=>[31],53=>[33],54=>[34],55=>[86],56=>[35],57=>[36],58=>[84],59=>[37],60=>[38],61=>[83],62=>[39],63=>[40],64=>[41],65=>[42],66=>[43],67=>[44],68=>[45],69=>[46],70=>[47],71=>[50],72=>[85],73=>[81],74=>[76,78],76=>[49,80],77=>[49,80],78=>[80],79=>[80],81=>[49,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],82=>[79],83=>[78],84=>[72],85=>[51],86=>[54],87=>[55],88=>[52],89=>[53],90=>[75],91=>[70],92=>[71],93=>[73],94=>[57],95=>[56],96=>[61],97=>[65],98=>[63],99=>[69],100=>[62],101=>[68],102=>[64],103=>[74],104=>[66],105=>[58],106=>[59],107=>[60],108=>[67],109=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,81,82,83,84,85,86],110=>[80],111=>[80],113=>[80],114=>[80],115=>[80],116=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,81,82,83,84,85,86],118=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],119=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],121=>[76,78],123=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75],124=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75],128=>[80],129=>[80],130=>[80],131=>[80],132=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,81,82,83,84,85,86],133=>[76,78],134=>[76,77,78,79],135=>[78,79],136=>[78,79],137=>[32,82],138=>[32,82],141=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],142=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],143=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],144=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],145=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],146=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],148=>[38,83],149=>[38,83],151=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],152=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],153=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,23,24],154=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,23,24],155=>[22,23],156=>[22],158=>[22,23],159=>[22,23],160=>[1,2,3,4,5,6,8,9,10,11,12,13,14,24],162=>[7,15,16,17,18],163=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,50,85],164=>[50],166=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],168=>[50,85],169=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],171=>[46,47],172=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],173=>[19],174=>[20],176=>[40],177=>[40],178=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,38,39,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],179=>[39],180=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],182=>[40],183=>[40],184=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,33,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],185=>[33],186=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,38,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,83],187=>[76,77],189=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],190=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75],191=>[72],192=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,30,32,42,82],193=>[26,27,42],194=>[26,27,42],195=>[26,27,42],198=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],199=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],200=>[30],201=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,32,82],202=>[32,82],204=>[41,80],205=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,30,32,82],206=>[26],208=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,32,82],209=>[12],210=>[12],213=>[28,29],214=>[28],215=>[28],216=>[28],218=>[29],219=>[29],220=>[29],223=>[36,84],224=>[36,84],225=>[36],227=>[36,84],228=>[36,84],229=>[25],230=>[7],231=>[38],233=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,42,82],234=>[42],235=>[34,86],236=>[34,86],237=>[34,86],238=>[34,86],240=>[40],243=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],244=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],245=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,24],246=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,22,24],247=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],249=>[43],252=>[40],254=>[41],255=>[3,4,8],256=>[3,4,8],257=>[38],259=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,42,82],260=>[42],261=>[34,86],262=>[34,86],263=>[34,86],264=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],266=>[40],267=>[6],268=>[38],270=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,24],271=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,24],272=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,24],274=>[40],275=>[40],276=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,24,39],277=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,22,24],278=>[3,4,6,7,8],279=>[3,4,6,7,8],281=>[32,34,36,82,84],282=>[34],283=>[34],284=>[34],285=>[34],286=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],287=>[13,14],288=>[13],289=>[14],293=>[5],294=>[5],296=>[46],297=>[46],300=>[40],301=>[40],302=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,35],303=>[35],304=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],306=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],307=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],311=>[40],312=>[40],313=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,33,82],314=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],315=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],316=>[32,82],317=>[3,4,6,7,8],318=>[34,36,84,86],319=>[34,86],320=>[34,86],321=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,50,82,85],322=>[1,2],323=>[1,2],324=>[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],327=>[40],328=>[40],329=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,35,50,82,85],330=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,50,82,85],331=>[1,2,5,9,10,11,12,13,14,15,16,17,18,24],332=>[1,2,5,9,10,11,12,13,14,15,16,17,18,24],333=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24],335=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24],337=>[7,18,36,84],338=>[7,18],339=>[7,18],340=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,36,84],341=>[19],342=>[20],343=>[21,22],344=>[16],345=>[15],346=>[17],347=>[7,18],349=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,36,84],350=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,36,84],351=>[44],352=>[44],355=>[40],356=>[40],357=>[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,24],360=>[43],361=>[36,84],362=>[34],363=>[34],364=>[32,82],366=>[1,2,5,9,10,11,12,13,14,15,16,17,18,24],367=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,32,82],368=>[28,29,41,80],369=>[28,29,41,80],370=>[28,29],371=>[28],372=>[28],373=>[28],376=>[28],377=>[29],378=>[29],379=>[29],382=>[29],384=>[75],385=>[25,26],386=>[25,26],387=>[25,26],390=>[70],391=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],392=>[71],393=>[73],394=>[57],395=>[56],396=>[61],397=>[60],398=>[63],399=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],400=>[67],401=>[55],402=>[51],403=>[26],404=>[54],405=>[52],406=>[53],407=>[65],408=>[69],409=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],410=>[9],412=>[28,29,32,34,36,41,43,80,82,84],413=>[28,29,41,80],414=>[28,29],415=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,32,34,82,86],416=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],417=>[32,34,82,86],418=>[34,86],419=>[34,86],421=>[40],422=>[40],424=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,26,27,30,32,42,82],425=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,26,27,30,32,42,82],426=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,30,32,82],427=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,30,32,82],428=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24,30,32,82],429=>[46],430=>[46],431=>[26,27,42],433=>[40],434=>[40],435=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,30,32,82],436=>[62],437=>[68],438=>[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,24],439=>[64],440=>[74],441=>[66],442=>[66],443=>[58],444=>[14],445=>[14],446=>[59],448=>[25,26],449=>[45],450=>[45],451=>[32,82],452=>[32,82],454=>[51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79],458=>[49,80],459=>[49]]; + + /** @var array the identifier of the token at each position, the last one being -1 */ + protected array $ids = []; + + /** @var array the index of the token of the lexer at each position */ + protected array $indexes = []; + + /** the position the reading is at */ + protected int $p = 0; + + /** @var array the values built, as a stack */ + protected array $v = []; + + /** the size of the stack of values */ + protected int $n = 0; + + /** @var array the comments read and not given to any node yet, by their index */ + protected array $comments = []; + + /** the furthest position a failure has been recorded at */ + private int $f = -1; + + /** @var list the rules recorded as failed at the furthest position */ + private array $er = []; + + abstract protected function token(int $position): Token; + + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceType(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceSubType(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceNullable(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceAtomic(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceCallableReturnType(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceArrayOrOffsetAccessItem(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceGeneric(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceGenericInReturnType(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceGenericArgument(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceCallable(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceCallableWithTemplates(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceCallableTemplateArgument(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceCallableParameter(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceArrayShape(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceListShape(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceArrayShapeUnsealedType(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceListShapeUnsealedType(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceArrayShapeItem(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceArrayShapeKey(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceObjectShape(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceObjectShapeItem(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceObjectShapeKey(int $begin, int $end, $children); + + abstract protected function reduceDiscardedComment(int $begin, int $end): void; + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceConstantFloat(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceConstantInteger(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceConstantString(int $begin, int $end, $children); + + /** + * @return mixed + */ + abstract protected function reduceConstantTrue(int $begin, int $end); + + /** + * @return mixed + */ + abstract protected function reduceConstantFalse(int $begin, int $end); + + /** + * @return mixed + */ + abstract protected function reduceConstantNull(int $begin, int $end); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceConstantArrayLiteral(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceConstantArrayShorthand(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceConstantArrayItem(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceConstantFetch(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reducePhpDoc(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceTextChild(int $begin, int $end, $children); + + /** + * @return mixed + */ + abstract protected function reduceText(int $begin, int $end); + + /** + * @return mixed + */ + abstract protected function reduceDoctrineText(int $begin, int $end); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceKnownTag(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceMethodParameter(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceGenericTag(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineTag(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceInvalidTag(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceInvalidTypeAliasTag(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineArgument(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineNestedAnnotation(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineArray(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineArrayItem(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineArrayKey(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineIdentifier(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineConstantFetch(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineFloat(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineInteger(int $begin, int $end, $children); + + /** + * @param list $children + * @return mixed + */ + abstract protected function reduceDoctrineString(int $begin, int $end, $children); + + /** + * Where the last reading has failed, along with the tokens expected there. + * + * @return array{int, list} + */ + protected function failure(): array + { + if ($this->f === -1 || $this->f < $this->p) { + return [$this->p, []]; + } + + $expected = []; + foreach ($this->er as $rule) { + foreach (self::EXPECTED[$rule] ?? [] as $token) { + $expected[$token] = true; + } + } + + ksort($expected); + + return [$this->f, array_keys($expected)]; + } + + /** + * Saves the state of the reading, so that a reading may be started in the + * middle of another one. + * + * @return array{int, int, list} + */ + protected function saveReading(): array + { + return [$this->p, $this->f, $this->er]; + } + + /** + * @param array{int, int, list} $state + */ + protected function restoreReading(array $state): void + { + [$this->p, $this->f, $this->er] = $state; + } + + private function rec(int $rule): void + { + $position = $this->p; + if ($position > $this->f) { + $this->f = $position; + $this->er = [$rule]; + return; + } + + if ($position !== $this->f || isset($this->er[3])) { + return; + } + + $this->er[] = $rule; + } + + /** + * Reads the given rule from the given position. + * + * @phpstan-impure + */ + protected function parseRule(int $rule, int $position, bool $build): bool + { + $this->p = $position; + $this->f = -1; + $this->er = []; + + switch ($rule) { + case 0: // PhpDoc + return $build ? $this->b0() : $this->s0(); + case 10: // UnreadTagChild + return $build ? $this->b10() : $this->s10(); + case 189: // PhpDocChild + return $build ? $this->b189() : $this->s189(); + case 190: // KnownTag + return $build ? $this->b190() : $this->s190(); + case 199: // Type + return $build ? $this->b199() : $this->s199(); + case 340: // ConstantExpr + return $build ? $this->b340() : $this->s340(); + default: + throw new \LogicException('Not an entrypoint: ' . $rule); + } + } + + private function b0(): bool + { + if (!($this->ids[$this->p] === 48)) { + if ($this->p > $this->f) { + $this->rec(0); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->p++; + if (($this->ids[$this->p] === 80)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(3); + } + if (!$this->b5()) { + goto n2;} + n2: + if (!($this->ids[$this->p] === 49)) { + if ($this->p >= $this->f) { + $this->rec(7); + } + + goto f1;} + + $this->p++; + goto k1; + f1: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1: + $this->v[$m1] = $this->reducePhpDoc(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b5(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (($this->ids[$this->p] === 49)) { + if (($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f218;} + } + if (!$this->b8()) { + goto f218;} + // b460 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + // b461 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (($this->ids[$this->p] === 49)) { + if (($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f221;} + } + if (!$this->b8()) { + goto f221;} + goto k221; + f221: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto e220; + k221: + if ($this->p === $b2) { + goto e220; + } + } + e220: + goto k218; + f218: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k218: + + return true; + } + + private function b8(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + // b188 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b189()) { + goto f504;} + // b458 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 49: + if (!($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->rec(7); + } + + goto n507;} + goto a506; + n507: + break; + case 80: + $this->p++; + goto a506; + break; + } + + if ($this->p > $this->f) { + $this->rec(458); + } + + goto f505; + a506: + goto k505; + f505: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f504; + k505: + goto k504; + f504: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n503; + k504: + goto a502; + n503: + break; + case 76: + case 77: + case 78: + case 79: + // b9 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b10()) { + goto f509;} + if (($this->ids[$this->p] === 80)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(3); + } + goto k509; + f509: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n508; + k509: + goto a502; + n508: + // b188 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b189()) { + goto f511;} + // b458 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 49: + if (!($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->rec(7); + } + + goto n514;} + goto a513; + n514: + break; + case 80: + $this->p++; + goto a513; + break; + } + + if ($this->p > $this->f) { + $this->rec(458); + } + + goto f512; + a513: + goto k512; + f512: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f511; + k512: + goto k511; + f511: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n510; + k511: + goto a502; + n510: + break; + } + + if ($this->p > $this->f) { + $this->rec(8); + } + + goto f501; + a502: + goto k501; + f501: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k501: + + return true; + } + + private function b10(): bool + { + if (!isset(self::T942497bd[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(10); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 76: + case 77: + if (!$this->b11()) { + goto n11;} + goto a10; + n11: + if (!$this->b134()) { + goto n12;} + goto a10; + n12: + break; + case 78: + case 79: + if (!$this->b134()) { + goto n13;} + goto a10; + n13: + break; + } + + if ($this->p > $this->f) { + $this->rec(10); + } + + goto f9; + a10: + goto k9; + f9: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k9: + + return true; + } + + private function b11(): bool + { + if (!isset(self::Tf6aec6a4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(11); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f235;} + } + // b19 + $o2 = $this->p; + // s19 + $o3 = $this->p; + // s20 + $o4 = $this->p; + while (true) { + $b4 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b4 > $this->f) { + $this->rec(21); + } + + goto e239; + } + + $this->p++; + } + e239: + if (!$this->s74()) { + goto f237;} + goto k237; + f237: + $this->p = $o3; + goto f235; + k237: + $this->v[$this->n++] = $this->reduceDoctrineText(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1))); + goto k235; + f235: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k235: + $this->v[$m1] = $this->reduceGenericTag(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b125(): bool + { + $o1 = $this->p; + if (!$this->s125()) { + return false;} + $this->v[$this->n++] = $this->reduceText(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1))); + + return true; + } + + private function b134(): bool + { + if (!isset(self::T942497bd[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(134); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 76: + case 77: + // b187 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b138()) { + goto f243;} + // b19 + $o3 = $this->p; + // s19 + $o4 = $this->p; + // s20 + $o5 = $this->p; + while (true) { + $b5 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b5 > $this->f) { + $this->rec(21); + } + + goto e247; + } + + $this->p++; + } + e247: + if (!$this->s74()) { + goto f245;} + goto k245; + f245: + $this->p = $o4; + goto f243; + k245: + $this->v[$this->n++] = $this->reduceDoctrineText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k243; + f243: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n242; + k243: + goto a241; + n242: + break; + case 78: + case 79: + // b135 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b137()) { + goto f249;} + // b19 + $o3 = $this->p; + // s19 + $o4 = $this->p; + // s20 + $o5 = $this->p; + while (true) { + $b5 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b5 > $this->f) { + $this->rec(21); + } + + goto e253; + } + + $this->p++; + } + e253: + if (!$this->s74()) { + goto f251;} + goto k251; + f251: + $this->p = $o4; + goto f249; + k251: + $this->v[$this->n++] = $this->reduceDoctrineText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k249; + f249: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n248; + k249: + goto a241; + n248: + break; + } + + if ($this->p > $this->f) { + $this->rec(134); + } + + goto f240; + a241: + goto k240; + f240: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k240: + $this->v[$m1] = $this->reduceDoctrineTag(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b137(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n526;} + goto a525; + n526: + break; + case 32: + case 82: + if (!$this->b138()) { + goto n527;} + goto a525; + n527: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n528;} + goto a525; + n528: + break; + } + + if ($this->p > $this->f) { + $this->rec(137); + } + + goto f524; + a525: + goto k524; + f524: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k524: + + return true; + } + + private function b138(): bool + { + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(138); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b139 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e518; + } + + $this->p++; + } + e518: + if (isset(self::T1e2ed78c[$this->ids[$this->p]])) { + // b141 + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(141); + } + + goto n519;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b142()) { + goto f520;} + // b139 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e522; + } + + $this->p++; + } + e522: + if (($this->ids[$this->p] === 40)) { + if (!$this->b182()) { + goto n523;} + n523: + } elseif ($this->p > $this->f) { + $this->rec(182); + } + goto k520; + f520: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n519; + k520: + n519: + } elseif ($this->p > $this->f) { + $this->rec(141); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f516;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k516; + f516: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k516: + + return true; + } + + private function b142(): bool + { + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(142); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + // b146 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if (!$this->b138()) { + goto n787;} + n787: + } elseif ($this->p > $this->f) { + $this->rec(138); + } + $this->v[$m2] = $this->reduceDoctrineNestedAnnotation(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a784; + n785: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + if (!$this->b143()) { + goto n788;} + goto a784; + n788: + // b172 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f790;} + } + goto k790; + f790: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n789; + k790: + $this->v[$m2] = $this->reduceDoctrineIdentifier(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a784; + n789: + if (!$this->b160()) { + goto n791;} + goto a784; + n791: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + if (!$this->b143()) { + goto n792;} + goto a784; + n792: + // b172 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f794;} + } + goto k794; + f794: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n793; + k794: + $this->v[$m2] = $this->reduceDoctrineIdentifier(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a784; + n793: + break; + case 22: + case 23: + if (!$this->b155()) { + goto n795;} + goto a784; + n795: + break; + case 38: + case 83: + if (!$this->b148()) { + goto n796;} + goto a784; + n796: + break; + case 19: + $this->v[$this->n++] = $this->reduceDoctrineFloat($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a784; + break; + case 20: + $this->v[$this->n++] = $this->reduceDoctrineInteger($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a784; + break; + } + + if ($this->p > $this->f) { + $this->rec(142); + } + + goto f783; + a784: + goto k783; + f783: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k783: + $this->v[$m1] = $this->reduceDoctrineArgument(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b143(): bool + { + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(143); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b139 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e1055; + } + + $this->p++; + } + e1055: + if (!($this->ids[$this->p] === 46)) { + if ($this->p >= $this->f) { + $this->rec(69); + } + + goto f1053;} + + $this->v[$this->n++] = $this->token($this->p++); + // b139 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e1057; + } + + $this->p++; + } + e1057: + if (!$this->b145()) { + goto f1053;} + goto k1053; + f1053: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1053: + + return true; + } + + private function b145(): bool + { + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(145); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + // b146 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if (!$this->b138()) { + goto n1337;} + n1337: + } elseif ($this->p > $this->f) { + $this->rec(138); + } + $this->v[$m2] = $this->reduceDoctrineNestedAnnotation(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a1334; + n1335: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + // b172 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1339;} + } + goto k1339; + f1339: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1338; + k1339: + $this->v[$m2] = $this->reduceDoctrineIdentifier(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a1334; + n1338: + if (!$this->b160()) { + goto n1340;} + goto a1334; + n1340: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + // b172 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1342;} + } + goto k1342; + f1342: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1341; + k1342: + $this->v[$m2] = $this->reduceDoctrineIdentifier(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a1334; + n1341: + break; + case 22: + case 23: + if (!$this->b155()) { + goto n1343;} + goto a1334; + n1343: + break; + case 38: + case 83: + if (!$this->b148()) { + goto n1344;} + goto a1334; + n1344: + break; + case 19: + $this->v[$this->n++] = $this->reduceDoctrineFloat($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a1334; + break; + case 20: + $this->v[$this->n++] = $this->reduceDoctrineInteger($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a1334; + break; + } + + if ($this->p > $this->f) { + $this->rec(145); + } + + goto f1333; + a1334: + goto k1333; + f1333: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1333: + + return true; + } + + private function b148(): bool + { + if (!isset(self::T34048a70[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(148); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b139 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e1068; + } + + $this->p++; + } + e1068: + if (isset(self::T1490fe7f[$this->ids[$this->p]])) { + // b151 + if (!isset(self::T1490fe7f[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(151); + } + + goto n1069;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b152()) { + goto f1070;} + // b139 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1072; + } + + $this->p++; + } + e1072: + if (($this->ids[$this->p] === 40)) { + if (!$this->b176()) { + goto n1073;} + n1073: + } elseif ($this->p > $this->f) { + $this->rec(176); + } + goto k1070; + f1070: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1069; + k1070: + n1069: + } elseif ($this->p > $this->f) { + $this->rec(151); + } + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f1066;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k1066; + f1066: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1066: + $this->v[$m1] = $this->reduceDoctrineArray(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b152(): bool + { + if (!isset(self::T1490fe7f[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(152); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + // b146 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if (!$this->b138()) { + goto n1349;} + n1349: + } elseif ($this->p > $this->f) { + $this->rec(138); + } + $this->v[$m2] = $this->reduceDoctrineNestedAnnotation(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a1346; + n1347: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + if (!$this->b153()) { + goto n1350;} + goto a1346; + n1350: + // b172 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1352;} + } + goto k1352; + f1352: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1351; + k1352: + $this->v[$m2] = $this->reduceDoctrineIdentifier(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a1346; + n1351: + if (!$this->b160()) { + goto n1353;} + goto a1346; + n1353: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + if (!$this->b153()) { + goto n1354;} + goto a1346; + n1354: + // b172 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1356;} + } + goto k1356; + f1356: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1355; + k1356: + $this->v[$m2] = $this->reduceDoctrineIdentifier(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a1346; + n1355: + break; + case 22: + case 23: + if (!$this->b153()) { + goto n1357;} + goto a1346; + n1357: + if (!$this->b155()) { + goto n1358;} + goto a1346; + n1358: + break; + case 38: + case 83: + if (!$this->b148()) { + goto n1359;} + goto a1346; + n1359: + break; + case 19: + $this->v[$this->n++] = $this->reduceDoctrineFloat($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a1346; + break; + case 20: + if (!$this->b153()) { + goto n1360;} + goto a1346; + n1360: + $this->v[$this->n++] = $this->reduceDoctrineInteger($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a1346; + break; + case 21: + if (!$this->b153()) { + goto n1361;} + goto a1346; + n1361: + break; + } + + if ($this->p > $this->f) { + $this->rec(152); + } + + goto f1345; + a1346: + goto k1345; + f1345: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1345: + $this->v[$m1] = $this->reduceDoctrineArrayItem(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b153(): bool + { + if (!isset(self::T7726a0df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(153); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b154()) { + goto f1605;} + // b139 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e1607; + } + + $this->p++; + } + e1607: + if (!isset(self::Ta7068161[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(171); + } + + goto f1605;} + + $this->v[$this->n++] = $this->token($this->p++); + // b139 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e1609; + } + + $this->p++; + } + e1609: + if (!$this->b145()) { + goto f1605;} + goto k1605; + f1605: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1605: + + return true; + } + + private function b154(): bool + { + if (!isset(self::T7726a0df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(154); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + if (!$this->b160()) { + goto n1723;} + goto a1722; + n1723: + // b169 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1725;} + } + goto k1725; + f1725: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1724; + k1725: + goto a1722; + n1724: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + // b169 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1727;} + } + goto k1727; + f1727: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1726; + k1727: + goto a1722; + n1726: + break; + case 22: + case 23: + if (!$this->b155()) { + goto n1728;} + goto a1722; + n1728: + break; + case 20: + $this->v[$this->n++] = $this->token($this->p++); + goto a1722; + break; + case 21: + $this->v[$this->n++] = $this->token($this->p++); + goto a1722; + break; + } + + if ($this->p > $this->f) { + $this->rec(154); + } + + goto f1721; + a1722: + goto k1721; + f1721: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1721: + $this->v[$m1] = $this->reduceDoctrineArrayKey(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b155(): bool + { + if (!isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(155); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 22: + // b156 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + // b158 + if (!isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(158); + } + + goto n1063;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(159); + } + + goto e1065; + } + + $this->v[$this->n++] = $this->token($this->p++); + + $k3++; + } + e1065: + + if ($k3 < 1) { + goto f1064; + } + goto k1064; + f1064: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto n1063; + k1064: + n1063: + } elseif ($this->p > $this->f) { + $this->rec(158); + } + goto a1060; + n1061: + break; + case 23: + $this->v[$this->n++] = $this->token($this->p++); + goto a1060; + break; + } + + if ($this->p > $this->f) { + $this->rec(155); + } + + goto f1059; + a1060: + goto k1059; + f1059: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1059: + $this->v[$m1] = $this->reduceDoctrineString(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b160(): bool + { + if (!isset(self::T96867045[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(160); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1058;} + } + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f1058;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 43)) { + if ($this->p >= $this->f) { + $this->rec(66); + } + + goto f1058;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b163()) { + goto f1058;} + goto k1058; + f1058: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1058: + $this->v[$m1] = $this->reduceDoctrineConstantFetch(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b163(): bool + { + if (!isset(self::Td08f0236[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(163); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + if (!$this->b166()) { + goto n753;} + goto a752; + n753: + break; + case 50: + // b164 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T83e30518[$this->ids[$this->p]])) { + if (!$this->b166()) { + goto n756;} + n756: + } elseif ($this->p > $this->f) { + $this->rec(166); + } + goto a752; + n754: + break; + case 85: + $this->v[$this->n++] = $this->token($this->p++); + goto a752; + break; + } + + if ($this->p > $this->f) { + $this->rec(163); + } + + goto f751; + a752: + goto k751; + f751: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k751: + + return true; + } + + private function b166(): bool + { + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(166); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T4d756b3a[$this->ids[$this->p]])) { + if (!$this->b168()) { + goto n1044;} + n1044: + } elseif ($this->p > $this->f) { + $this->rec(168); + } + + return true; + } + + private function b168(): bool + { + if (!isset(self::T4d756b3a[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(168); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 50: + // b164 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T83e30518[$this->ids[$this->p]])) { + // b166 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(166); + } + + goto n1330;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T4d756b3a[$this->ids[$this->p]])) { + if (!$this->b168()) { + goto n1332;} + n1332: + } elseif ($this->p > $this->f) { + $this->rec(168); + } + n1330: + } elseif ($this->p > $this->f) { + $this->rec(166); + } + goto a1327; + n1328: + break; + case 85: + $this->v[$this->n++] = $this->token($this->p++); + goto a1327; + break; + } + + if ($this->p > $this->f) { + $this->rec(168); + } + + goto f1326; + a1327: + goto k1326; + f1326: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1326: + + return true; + } + + private function b176(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(176); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(177); + } + + goto e1363; + } + + // b177 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(177); + } + + goto e1363;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b139 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1366; + } + + $this->p++; + } + e1366: + if (!$this->b178()) { + goto f1364;} + goto k1364; + f1364: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto e1363; + k1364: + if ($this->p === $b1) { + $k1 = 1; + goto e1363; + } + + $k1++; + } + e1363: + + if ($k1 < 1) { + goto f1362; + } + goto k1362; + f1362: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1362: + + return true; + } + + private function b178(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + // b180 + if (!isset(self::T1490fe7f[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(180); + } + + goto n1612;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b152()) { + goto f1613;} + // b139 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1615; + } + + $this->p++; + } + e1615: + goto k1613; + f1613: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1612; + k1613: + goto a1611; + n1612: + break; + case 0: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 80: + case 81: + case 82: + case 84: + case 85: + case 86: + case -1: + break; + case 39: + if (!($this->ids[$this->p] === 39)) { + if ($this->p > $this->f) { + $this->rec(62); + } + + goto n1616;} + goto a1611; + n1616: + break; + } + + if ($this->p > $this->f) { + $this->rec(178); + } + + goto f1610; + a1611: + goto k1610; + f1610: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1610: + + return true; + } + + private function b182(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(182); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(183); + } + + goto e798; + } + + // b183 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(183); + } + + goto e798;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b139 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e801; + } + + $this->p++; + } + e801: + if (!$this->b184()) { + goto f799;} + goto k799; + f799: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto e798; + k799: + if ($this->p === $b1) { + $k1 = 1; + goto e798; + } + + $k1++; + } + e798: + + if ($k1 < 1) { + goto f797; + } + goto k797; + f797: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k797: + + return true; + } + + private function b184(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + // b186 + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(186); + } + + goto n1076;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b142()) { + goto f1077;} + // b139 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1079; + } + + $this->p++; + } + e1079: + goto k1077; + f1077: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1076; + k1077: + goto a1075; + n1076: + break; + case 0: + case 21: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 34: + case 35: + case 36: + case 37: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 80: + case 81: + case 82: + case 84: + case 85: + case 86: + case -1: + break; + case 33: + if (!($this->ids[$this->p] === 33)) { + if ($this->p > $this->f) { + $this->rec(53); + } + + goto n1080;} + goto a1075; + n1080: + break; + } + + if ($this->p > $this->f) { + $this->rec(184); + } + + goto f1074; + a1075: + goto k1074; + f1074: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1074: + + return true; + } + + private function b189(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (!$this->b455()) { + goto n33;} + goto a32; + n33: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + if (!$this->b190()) { + goto n34;} + goto a32; + n34: + // b454 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o3 = $this->p; + if (!$this->s125()) { + goto f36;} + $this->v[$this->n++] = $this->reduceText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k36; + f36: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n35; + k36: + $this->v[$m2] = $this->reduceInvalidTag(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a32; + n35: + if (!$this->b455()) { + goto n38;} + goto a32; + n38: + break; + case 76: + case 77: + case 78: + case 79: + // b454 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o3 = $this->p; + if (!$this->s125()) { + goto f40;} + $this->v[$this->n++] = $this->reduceText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k40; + f40: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n39; + k40: + $this->v[$m2] = $this->reduceInvalidTag(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a32; + n39: + if (!$this->b455()) { + goto n42;} + goto a32; + n42: + break; + } + + if ($this->p > $this->f) { + $this->rec(189); + } + + goto f31; + a32: + goto k31; + f31: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k31: + + return true; + } + + private function b190(): bool + { + if (!isset(self::Tce49e0fc[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(190); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + // b402 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f60;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b125()) { + goto f61;} + goto k61; + f61: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f60; + k61: + goto k60; + f60: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n59; + k60: + goto a58; + n59: + break; + case 52: + // b405 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f63;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b125()) { + goto f64;} + goto k64; + f64: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f63; + k64: + goto k63; + f63: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n62; + k63: + goto a58; + n62: + break; + case 53: + // b406 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f66;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b125()) { + goto f67;} + goto k67; + f67: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f66; + k67: + goto k66; + f66: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n65; + k66: + goto a58; + n65: + break; + case 54: + // b404 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f69;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b125()) { + goto f70;} + goto k70; + f70: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f69; + k70: + goto k69; + f69: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n68; + k69: + goto a58; + n68: + break; + case 55: + // b401 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b399 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(399); + } + + goto f72;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f73;} + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f73;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b125()) { + goto f73;} + goto k73; + f73: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f72; + k73: + goto k72; + f72: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n71; + k72: + goto a58; + n71: + break; + case 56: + // b395 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b391 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + goto f75;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f76;} + if (!$this->b388()) { + goto f76;} + goto k76; + f76: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f75; + k76: + goto k75; + f75: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n74; + k75: + goto a58; + n74: + break; + case 57: + // b394 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b391 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + goto f78;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f79;} + if (!$this->b388()) { + goto f79;} + goto k79; + f79: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f78; + k79: + goto k78; + f78: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n77; + k78: + goto a58; + n77: + break; + case 58: + // b443 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f81;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 10)) { + if ($this->p >= $this->f) { + $this->rec(26); + } + + goto f81;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f81;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b444()) { + goto f81;} + goto k81; + f81: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n80; + k81: + goto a58; + n80: + break; + case 59: + if (!$this->b446()) { + goto n82;} + goto a58; + n82: + break; + case 60: + // b397 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b391 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + goto f84;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f85;} + if (!$this->b388()) { + goto f85;} + goto k85; + f85: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f84; + k85: + goto k84; + f84: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n83; + k84: + goto a58; + n83: + break; + case 61: + // b396 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b391 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + goto f87;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f88;} + if (!$this->b388()) { + goto f88;} + goto k88; + f88: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f87; + k88: + goto k87; + f87: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n86; + k87: + goto a58; + n86: + break; + case 62: + if (!$this->b436()) { + goto n89;} + goto a58; + n89: + break; + case 63: + // b398 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b399 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(399); + } + + goto f91;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f92;} + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f92;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b125()) { + goto f92;} + goto k92; + f92: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f91; + k92: + goto k91; + f91: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n90; + k91: + goto a58; + n90: + break; + case 64: + // b439 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b438 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(438); + } + + goto f94;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b320()) { + goto f95;} + if (!$this->b388()) { + goto f95;} + goto k95; + f95: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f94; + k95: + goto k94; + f94: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n93; + k94: + goto a58; + n93: + break; + case 65: + // b407 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o3 = $this->p; + if (!$this->s125()) { + goto f97;} + $this->v[$this->n++] = $this->reduceText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k97; + f97: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n96; + k97: + goto a58; + n96: + break; + case 66: + // b441 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f100;} + + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 46)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + if (!$this->b199()) { + goto f100;} + if (!isset(self::T53b29bff[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(77); + } + + goto f100;} + goto k100; + f100: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n99; + k100: + goto a58; + n99: + if (!$this->b442()) { + goto n101;} + goto a58; + n101: + break; + case 67: + if (!$this->b400()) { + goto n102;} + goto a58; + n102: + break; + case 68: + // b437 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b438 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(438); + } + + goto f104;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b320()) { + goto f105;} + if (!$this->b388()) { + goto f105;} + goto k105; + f105: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f104; + k105: + goto k104; + f104: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n103; + k104: + goto a58; + n103: + break; + case 69: + // b408 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b409()) { + goto f107;} + goto k107; + f107: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n106; + k107: + goto a58; + n106: + break; + case 70: + // b390 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b391 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + goto f109;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f110;} + if (!$this->b388()) { + goto f110;} + goto k110; + f110: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f109; + k110: + goto k109; + f109: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n108; + k109: + goto a58; + n108: + break; + case 71: + // b392 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b391 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + goto f112;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f113;} + if (!$this->b388()) { + goto f113;} + goto k113; + f113: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f112; + k113: + goto k112; + f112: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n111; + k112: + goto a58; + n111: + break; + case 72: + // b191 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b192()) { + goto f115;} + goto k115; + f115: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n114; + k115: + goto a58; + n114: + break; + case 73: + // b393 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b391 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + goto f117;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + if (!$this->b199()) { + goto f118;} + if (!$this->b388()) { + goto f118;} + goto k118; + f118: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f117; + k118: + goto k117; + f117: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n116; + k117: + goto a58; + n116: + break; + case 74: + // b440 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b438 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(438); + } + + goto f120;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b320()) { + goto f121;} + if (!$this->b388()) { + goto f121;} + goto k121; + f121: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f120; + k121: + goto k120; + f120: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n119; + k120: + goto a58; + n119: + break; + case 75: + // b384 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f123;} + if (!$this->b385()) { + goto f123;} + goto k123; + f123: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n122; + k123: + goto a58; + n122: + break; + } + + if ($this->p > $this->f) { + $this->rec(190); + } + + goto f57; + a58: + goto k57; + f57: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k57: + $this->v[$m1] = $this->reduceKnownTag(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b192(): bool + { + if (!isset(self::T3bf4df75[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(192); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + if (!$this->b198()) { + goto n323;} + goto a322; + n323: + break; + case 26: + case 27: + case 42: + if (!$this->b193()) { + goto n324;} + goto a322; + n324: + break; + } + + if ($this->p > $this->f) { + $this->rec(192); + } + + goto f321; + a322: + goto k321; + f321: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k321: + + return true; + } + + private function b193(): bool + { + if (!isset(self::T553dc07b[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(193); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!isset(self::T553dc07b[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(195); + } + + goto f615;} + if (($this->ids[$this->p] === 27)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f615;} + + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o2 = $this->p; + if (!$this->s125()) { + goto f615;} + $this->v[$this->n++] = $this->reduceText(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1))); + goto k615; + f615: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k615: + + return true; + } + + private function b198(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(198); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b199()) { + goto f613;} + if (($this->ids[$this->p] === 27)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f613;} + + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o2 = $this->p; + if (!$this->s125()) { + goto f613;} + $this->v[$this->n++] = $this->reduceText(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1))); + goto k613; + f613: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k613: + + return true; + } + + private function b199(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(199); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 32: + case 82: + // b367 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b201()) { + goto f186;} + if (!$this->b368()) { + goto f186;} + goto k186; + f186: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n185; + k186: + goto a184; + n185: + break; + case 30: + // b200 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b201()) { + goto f188;} + goto k188; + f188: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n187; + k188: + $this->v[$m2] = $this->reduceNullable(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a184; + n187: + break; + } + + if ($this->p > $this->f) { + $this->rec(199); + } + + goto f183; + a184: + goto k183; + f183: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k183: + $this->v[$m1] = $this->reduceType(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b201(): bool + { + if (!isset(self::T977f027a[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(201); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 5: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // b366 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f389;} + } + if (!$this->b281()) { + goto f389;} + goto k389; + f389: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n388; + k389: + goto a387; + n388: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f391;} + } + if (!$this->b335()) { + goto f391;} + goto k391; + f391: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n390; + k391: + goto a387; + n390: + break; + case 19: + case 20: + case 21: + case 22: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f394;} + } + if (!$this->b335()) { + goto f394;} + goto k394; + f394: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n393; + k394: + goto a387; + n393: + break; + case 3: + case 4: + case 8: + if (!$this->b255()) { + goto n396;} + goto a387; + n396: + // b278 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f398;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f398;} + } + if (!$this->b281()) { + goto f398;} + goto k398; + f398: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n397; + k398: + goto a387; + n397: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f400;} + } + if (!$this->b335()) { + goto f400;} + goto k400; + f400: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n399; + k400: + goto a387; + n399: + break; + case 32: + case 82: + if (!$this->b202()) { + goto n402;} + goto a387; + n402: + break; + case 6: + if (!$this->b267()) { + goto n403;} + goto a387; + n403: + // b278 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f405;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f405;} + } + if (!$this->b281()) { + goto f405;} + goto k405; + f405: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n404; + k405: + goto a387; + n404: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f407;} + } + if (!$this->b335()) { + goto f407;} + goto k407; + f407: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n406; + k407: + goto a387; + n406: + break; + case 7: + if (!$this->b230()) { + goto n409;} + goto a387; + n409: + // b278 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f411;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f411;} + } + if (!$this->b281()) { + goto f411;} + goto k411; + f411: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n410; + k411: + goto a387; + n410: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f413;} + } + if (!$this->b335()) { + goto f413;} + goto k413; + f413: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n412; + k413: + goto a387; + n412: + break; + case 25: + if (!$this->b229()) { + goto n415;} + goto a387; + n415: + break; + } + + if ($this->p > $this->f) { + $this->rec(201); + } + + goto f386; + a387: + goto k386; + f386: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k386: + $this->v[$m1] = $this->reduceAtomic(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b202(): bool + { + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(202); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e676; + } + + $this->p++; + } + e676: + if (!$this->b205()) { + goto f674;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e678; + } + + $this->p++; + } + e678: + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f674;} + + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n679;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e681; + } + + if (!$this->b224()) { + goto e681;} + if ($this->p === $b2) { + $k2 = 1; + goto e681; + } + + $k2++; + } + e681: + + if ($k2 < 1) { + goto f680; + } + goto k680; + f680: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n679; + k680: + n679: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k674; + f674: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k674: + + return true; + } + + private function b205(): bool + { + if (!isset(self::Tcd64b9c0[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(205); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 32: + case 82: + // b208 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b201()) { + goto f935;} + if (!$this->b209()) { + goto f935;} + goto k935; + f935: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n934; + k935: + goto a933; + n934: + break; + case 26: + if (!$this->b206()) { + goto n936;} + goto a933; + n936: + break; + case 30: + // b200 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b201()) { + goto f938;} + goto k938; + f938: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n937; + k938: + $this->v[$m2] = $this->reduceNullable(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a933; + n937: + break; + } + + if ($this->p > $this->f) { + $this->rec(205); + } + + goto f932; + a933: + goto k932; + f932: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k932: + $this->v[$m1] = $this->reduceSubType(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b206(): bool + { + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(206); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 12)) { + if ($this->p >= $this->f) { + $this->rec(23); + } + + goto f1229;} + + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 11)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(24); + } + if (!$this->b199()) { + goto f1229;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1231; + } + + $this->p++; + } + e1231: + if (!($this->ids[$this->p] === 30)) { + if ($this->p >= $this->f) { + $this->rec(51); + } + + goto f1229;} + + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1233; + } + + $this->p++; + } + e1233: + if (!$this->b199()) { + goto f1229;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1235; + } + + $this->p++; + } + e1235: + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1229;} + + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1237; + } + + $this->p++; + } + e1237: + if (!$this->b205()) { + goto f1229;} + goto k1229; + f1229: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1229: + + return true; + } + + private function b209(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + // b211 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1221; + } + + $this->p++; + } + e1221: + if (isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if (!$this->b213()) { + goto n1222;} + n1222: + } elseif ($this->p > $this->f) { + $this->rec(213); + } + goto a1217; + n1218: + break; + case 12: + if (!$this->b210()) { + goto n1223;} + goto a1217; + n1223: + // b211 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1227; + } + + $this->p++; + } + e1227: + if (isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if (!$this->b213()) { + goto n1228;} + n1228: + } elseif ($this->p > $this->f) { + $this->rec(213); + } + goto a1217; + n1224: + break; + } + + if ($this->p > $this->f) { + $this->rec(209); + } + + goto f1216; + a1217: + goto k1216; + f1216: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1216: + + return true; + } + + private function b210(): bool + { + if (!($this->ids[$this->p] === 12)) { + if ($this->p > $this->f) { + $this->rec(210); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 11)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(24); + } + if (!$this->b199()) { + goto f1504;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1506; + } + + $this->p++; + } + e1506: + if (!($this->ids[$this->p] === 30)) { + if ($this->p >= $this->f) { + $this->rec(51); + } + + goto f1504;} + + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1508; + } + + $this->p++; + } + e1508: + if (!$this->b199()) { + goto f1504;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1510; + } + + $this->p++; + } + e1510: + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1504;} + + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1512; + } + + $this->p++; + } + e1512: + if (!$this->b205()) { + goto f1504;} + goto k1504; + f1504: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1504: + + return true; + } + + private function b213(): bool + { + if (!isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(213); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 28: + // b214 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b215 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 28)) { + if ($b3 > $this->f) { + $this->rec(216); + } + + goto e1499; + } + + if (!$this->b216()) { + goto e1499;} + if ($this->p === $b3) { + $k3 = 1; + goto e1499; + } + + $k3++; + } + e1499: + + if ($k3 < 1) { + goto f1498; + } + goto k1498; + f1498: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f1497; + k1498: + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1497;} + } + goto k1497; + f1497: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1496; + k1497: + goto a1495; + n1496: + break; + case 29: + // b218 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b219 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 29)) { + if ($b3 > $this->f) { + $this->rec(220); + } + + goto e1503; + } + + if (!$this->b220()) { + goto e1503;} + if ($this->p === $b3) { + $k3 = 1; + goto e1503; + } + + $k3++; + } + e1503: + + if ($k3 < 1) { + goto f1502; + } + goto k1502; + f1502: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f1501; + k1502: + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1501;} + } + goto k1501; + f1501: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1500; + k1501: + goto a1495; + n1500: + break; + } + + if ($this->p > $this->f) { + $this->rec(213); + } + + goto f1494; + a1495: + goto k1494; + f1494: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1494: + + return true; + } + + private function b216(): bool + { + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(216); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1663; + } + + $this->p++; + } + e1663: + if (!$this->b201()) { + goto f1661;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1665; + } + + $this->p++; + } + e1665: + goto k1661; + f1661: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1661: + + return true; + } + + private function b220(): bool + { + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(220); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1668; + } + + $this->p++; + } + e1668: + if (!$this->b201()) { + goto f1666;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1670; + } + + $this->p++; + } + e1670: + goto k1666; + f1666: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1666: + + return true; + } + + private function b224(): bool + { + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(224); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 36: + // b225 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 37)) { + if (($this->ids[$this->p] === 37)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f893;} + } + if (!$this->b199()) { + goto f893;} + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f893;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k893; + f893: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n892; + k893: + goto a891; + n892: + // b227 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f895;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k895; + f895: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n894; + k895: + goto a891; + n894: + break; + case 84: + // b227 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f897;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k897; + f897: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n896; + k897: + goto a891; + n896: + break; + } + + if ($this->p > $this->f) { + $this->rec(224); + } + + goto f890; + a891: + goto k890; + f890: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k890: + $this->v[$m1] = $this->reduceArrayOrOffsetAccessItem(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b229(): bool + { + if (!($this->ids[$this->p] === 25)) { + if ($this->p > $this->f) { + $this->rec(229); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n691;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e693; + } + + if (!$this->b224()) { + goto e693;} + if ($this->p === $b2) { + $k2 = 1; + goto e693; + } + + $k2++; + } + e693: + + if ($k2 < 1) { + goto f692; + } + goto k692; + f692: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n691; + k692: + n691: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + + return true; + } + + private function b230(): bool + { + if (!($this->ids[$this->p] === 7)) { + if ($this->p > $this->f) { + $this->rec(230); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f686;} + } + if (!$this->b231()) { + goto f686;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n687;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e689; + } + + if (!$this->b224()) { + goto e689;} + if ($this->p === $b2) { + $k2 = 1; + goto e689; + } + + $k2++; + } + e689: + + if ($k2 < 1) { + goto f688; + } + goto k688; + f688: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n687; + k688: + n687: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k686; + f686: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k686: + + return true; + } + + private function b231(): bool + { + if (!($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->rec(231); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e949; + } + + $this->p++; + } + e949: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + if (!$this->b233()) { + goto n950;} + n950: + } elseif ($this->p > $this->f) { + $this->rec(233); + } + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e952; + } + + $this->p++; + } + e952: + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f947;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k947; + f947: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k947: + $this->v[$m1] = $this->reduceArrayShape(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b233(): bool + { + if (!isset(self::T50fd39f8[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(233); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + if (!$this->b243()) { + goto n1246;} + goto a1245; + n1246: + break; + case 42: + // b234 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1250; + } + + $this->p++; + } + e1250: + if (!$this->b235()) { + goto f1248;} + if (($this->ids[$this->p] === 40)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(63); + } + goto k1248; + f1248: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1247; + k1248: + goto a1245; + n1247: + break; + } + + if ($this->p > $this->f) { + $this->rec(233); + } + + goto f1244; + a1245: + goto k1244; + f1244: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1244: + + return true; + } + + private function b235(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1532;} + goto a1531; + n1532: + break; + case 34: + case 86: + // b236 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b237()) { + goto f1534;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1536; + } + + $this->p++; + } + e1536: + goto k1534; + f1534: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1533; + k1534: + goto a1531; + n1533: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1537;} + goto a1531; + n1537: + break; + } + + if ($this->p > $this->f) { + $this->rec(235); + } + + goto f1530; + a1531: + goto k1530; + f1530: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1530: + + return true; + } + + private function b237(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(237); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1673; + } + + $this->p++; + } + e1673: + if (!$this->b199()) { + goto f1671;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1675; + } + + $this->p++; + } + e1675: + if (($this->ids[$this->p] === 40)) { + if (!$this->b240()) { + goto n1676;} + n1676: + } elseif ($this->p > $this->f) { + $this->rec(240); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1671;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k1671; + f1671: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1671: + $this->v[$m1] = $this->reduceArrayShapeUnsealedType(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b240(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(240); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1731; + } + + $this->p++; + } + e1731: + if (!$this->b199()) { + goto f1729;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1733; + } + + $this->p++; + } + e1733: + goto k1729; + f1729: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1729: + + return true; + } + + private function b243(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(243); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b244()) { + goto f1522;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1524; + } + + $this->p++; + } + e1524: + if (($this->ids[$this->p] === 40)) { + // b252 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(252); + } + + goto n1525;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 41)) { + $this->reduceDiscardedComment($this->indexes[$this->p], $this->indexes[$this->p]); + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(254); + } + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1528; + } + + $this->p++; + } + e1528: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + if (!$this->b233()) { + goto n1529;} + n1529: + } elseif ($this->p > $this->f) { + $this->rec(233); + } + n1525: + } elseif ($this->p > $this->f) { + $this->rec(252); + } + goto k1522; + f1522: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1522: + + return true; + } + + private function b244(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(244); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 20: + case 21: + case 22: + case 24: + // b245 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b246()) { + goto f1476;} + if (($this->ids[$this->p] === 30)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(51); + } + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1476;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f1476;} + goto k1476; + f1476: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1475; + k1476: + goto a1474; + n1475: + if (!$this->b199()) { + goto n1477;} + goto a1474; + n1477: + break; + case 19: + case 25: + case 30: + case 32: + case 82: + if (!$this->b199()) { + goto n1478;} + goto a1474; + n1478: + break; + } + + if ($this->p > $this->f) { + $this->rec(244); + } + + goto f1473; + a1474: + goto k1473; + f1473: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1473: + $this->v[$m1] = $this->reduceArrayShapeItem(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b246(): bool + { + if (!isset(self::Tce797685[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(246); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // b247 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + // b249 + if (!($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->rec(249); + } + + goto n1654;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f1655;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k1655; + f1655: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto n1654; + k1655: + n1654: + } elseif ($this->p > $this->f) { + $this->rec(249); + } + goto a1651; + n1652: + break; + case 20: + $this->v[$this->n++] = $this->token($this->p++); + goto a1651; + break; + case 21: + $this->v[$this->n++] = $this->token($this->p++); + goto a1651; + break; + case 22: + $this->v[$this->n++] = $this->token($this->p++); + goto a1651; + break; + } + + if ($this->p > $this->f) { + $this->rec(246); + } + + goto f1650; + a1651: + goto k1650; + f1650: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1650: + $this->v[$m1] = $this->reduceArrayShapeKey(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b255(): bool + { + if (!isset(self::Ta8d79561[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(255); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f670;} + } + if (!$this->b257()) { + goto f670;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n671;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e673; + } + + if (!$this->b224()) { + goto e673;} + if ($this->p === $b2) { + $k2 = 1; + goto e673; + } + + $k2++; + } + e673: + + if ($k2 < 1) { + goto f672; + } + goto k672; + f672: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n671; + k672: + n671: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k670; + f670: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k670: + + return true; + } + + private function b257(): bool + { + if (!($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->rec(257); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e924; + } + + $this->p++; + } + e924: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + // b259 + if (!isset(self::T50fd39f8[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(259); + } + + goto n925;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + if (!$this->b264()) { + goto n928;} + goto a927; + n928: + break; + case 42: + if (!$this->b260()) { + goto n929;} + goto a927; + n929: + break; + } + + if ($this->p > $this->f) { + $this->rec(259); + } + + goto f926; + a927: + goto k926; + f926: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n925; + k926: + n925: + } elseif ($this->p > $this->f) { + $this->rec(259); + } + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e931; + } + + $this->p++; + } + e931: + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f922;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k922; + f922: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k922: + $this->v[$m1] = $this->reduceListShape(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b259(): bool + { + if (!isset(self::T50fd39f8[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(259); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + if (!$this->b264()) { + goto n1481;} + goto a1480; + n1481: + break; + case 42: + // b260 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1485; + } + + $this->p++; + } + e1485: + if (!$this->b261()) { + goto f1483;} + if (($this->ids[$this->p] === 40)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(63); + } + goto k1483; + f1483: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1482; + k1483: + goto a1480; + n1482: + break; + } + + if ($this->p > $this->f) { + $this->rec(259); + } + + goto f1479; + a1480: + goto k1479; + f1479: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1479: + + return true; + } + + private function b260(): bool + { + if (!($this->ids[$this->p] === 42)) { + if ($this->p > $this->f) { + $this->rec(260); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1215; + } + + $this->p++; + } + e1215: + if (!$this->b261()) { + goto f1213;} + if (($this->ids[$this->p] === 40)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(63); + } + goto k1213; + f1213: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1213: + + return true; + } + + private function b261(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1488;} + goto a1487; + n1488: + break; + case 34: + case 86: + // b262 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b263()) { + goto f1490;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1492; + } + + $this->p++; + } + e1492: + goto k1490; + f1490: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1489; + k1490: + goto a1487; + n1489: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1493;} + goto a1487; + n1493: + break; + } + + if ($this->p > $this->f) { + $this->rec(261); + } + + goto f1486; + a1487: + goto k1486; + f1486: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1486: + + return true; + } + + private function b263(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(263); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1658; + } + + $this->p++; + } + e1658: + if (!$this->b199()) { + goto f1656;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1660; + } + + $this->p++; + } + e1660: + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1656;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k1656; + f1656: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1656: + $this->v[$m1] = $this->reduceListShapeUnsealedType(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b264(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(264); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b244()) { + goto f1205;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1207; + } + + $this->p++; + } + e1207: + if (($this->ids[$this->p] === 40)) { + // b266 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(266); + } + + goto n1208;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 41)) { + $this->reduceDiscardedComment($this->indexes[$this->p], $this->indexes[$this->p]); + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(254); + } + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1211; + } + + $this->p++; + } + e1211: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + if (!$this->b259()) { + goto n1212;} + n1212: + } elseif ($this->p > $this->f) { + $this->rec(259); + } + n1208: + } elseif ($this->p > $this->f) { + $this->rec(266); + } + goto k1205; + f1205: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1205: + + return true; + } + + private function b267(): bool + { + if (!($this->ids[$this->p] === 6)) { + if ($this->p > $this->f) { + $this->rec(267); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f682;} + } + if (!$this->b268()) { + goto f682;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n683;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e685; + } + + if (!$this->b224()) { + goto e685;} + if ($this->p === $b2) { + $k2 = 1; + goto e685; + } + + $k2++; + } + e685: + + if ($k2 < 1) { + goto f684; + } + goto k684; + f684: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n683; + k684: + n683: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k682; + f682: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k682: + + return true; + } + + private function b268(): bool + { + if (!($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->rec(268); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e941; + } + + $this->p++; + } + e941: + if (isset(self::Td8017923[$this->ids[$this->p]])) { + // b270 + if (!isset(self::Td8017923[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(270); + } + + goto n942;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b271()) { + goto f943;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e945; + } + + $this->p++; + } + e945: + if (($this->ids[$this->p] === 40)) { + if (!$this->b274()) { + goto n946;} + n946: + } elseif ($this->p > $this->f) { + $this->rec(274); + } + goto k943; + f943: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n942; + k943: + n942: + } elseif ($this->p > $this->f) { + $this->rec(270); + } + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f939;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k939; + f939: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k939: + $this->v[$m1] = $this->reduceObjectShape(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b271(): bool + { + if (!isset(self::Td8017923[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(271); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b272()) { + goto f1238;} + if (($this->ids[$this->p] === 30)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(51); + } + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1238;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f1238;} + goto k1238; + f1238: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1238: + $this->v[$m1] = $this->reduceObjectShapeItem(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b272(): bool + { + if (!isset(self::Td8017923[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(272); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 2: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 3: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 4: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 5: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 6: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 7: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 8: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 9: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 10: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 11: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 12: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 13: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 14: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 15: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 16: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 17: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 18: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 21: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 22: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + case 24: + $this->v[$this->n++] = $this->token($this->p++); + goto a1514; + break; + } + + if ($this->p > $this->f) { + $this->rec(272); + } + + goto f1513; + a1514: + goto k1513; + f1513: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1513: + $this->v[$m1] = $this->reduceObjectShapeKey(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b274(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(274); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(275); + } + + goto e1240; + } + + // b275 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(275); + } + + goto e1240;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1243; + } + + $this->p++; + } + e1243: + if (!$this->b276()) { + goto f1241;} + goto k1241; + f1241: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto e1240; + k1241: + if ($this->p === $b1) { + $k1 = 1; + goto e1240; + } + + $k1++; + } + e1240: + + if ($k1 < 1) { + goto f1239; + } + goto k1239; + f1239: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1239: + + return true; + } + + private function b276(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 21: + case 22: + case 24: + // b277 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b271()) { + goto f1518;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1520; + } + + $this->p++; + } + e1520: + goto k1518; + f1518: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1517; + k1518: + goto a1516; + n1517: + break; + case 39: + if (!($this->ids[$this->p] === 39)) { + if ($this->p > $this->f) { + $this->rec(62); + } + + goto n1521;} + goto a1516; + n1521: + break; + } + + if ($this->p > $this->f) { + $this->rec(276); + } + + goto f1515; + a1516: + goto k1515; + f1515: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1515: + + return true; + } + + private function b281(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n650;} + goto a649; + n650: + break; + case 32: + case 82: + if (!$this->b364()) { + goto n651;} + goto a649; + n651: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n652;} + goto a649; + n652: + break; + case 36: + case 84: + // b223 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e655; + } + + if (!$this->b224()) { + goto e655;} + if ($this->p === $b2) { + $k2 = 1; + goto e655; + } + + $k2++; + } + e655: + + if ($k2 < 1) { + goto f654; + } + goto k654; + f654: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n653; + k654: + goto a649; + n653: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n656;} + goto a649; + n656: + break; + case 34: + // b282 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(54); + } + + goto f658;} + // b284 + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(284); + } + + goto f658;} + + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 34: + if (!$this->b285()) { + goto n661;} + goto a660; + n661: + if (!$this->b362()) { + goto n662;} + goto a660; + n662: + break; + } + + if ($this->p > $this->f) { + $this->rec(284); + } + + goto f659; + a660: + goto k659; + f659: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f658; + k659: + goto k658; + f658: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n657; + k658: + goto a649; + n657: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n663;} + goto a649; + n663: + break; + } + + if ($this->p > $this->f) { + $this->rec(281); + } + + goto f648; + a649: + goto k648; + f648: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k648: + + return true; + } + + private function b285(): bool + { + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(285); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e900; + } + + $this->p++; + } + e900: + // b286 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(286); + } + + goto f898;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b287()) { + goto f901;} + if (!$this->b293()) { + goto f901;} + if (!$this->b296()) { + goto f901;} + goto k901; + f901: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f898; + k901: + $this->v[$m2] = $this->reduceCallableTemplateArgument(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e903; + } + + $this->p++; + } + e903: + if (($this->ids[$this->p] === 40)) { + // b300 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(300); + } + + goto n904;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(301); + } + + goto e906; + } + + if (!$this->b301()) { + goto e906;} + if ($this->p === $b2) { + $k2 = 1; + goto e906; + } + + $k2++; + } + e906: + + if ($k2 < 1) { + goto f905; + } + goto k905; + f905: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n904; + k905: + n904: + } elseif ($this->p > $this->f) { + $this->rec(300); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f898;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f898;} + + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e908; + } + + $this->p++; + } + e908: + if (isset(self::T7680fe2e[$this->ids[$this->p]])) { + // b306 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(306); + } + + goto n909;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b307()) { + goto f910;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e912; + } + + $this->p++; + } + e912: + if (($this->ids[$this->p] === 40)) { + if (!$this->b311()) { + goto n913;} + n913: + } elseif ($this->p > $this->f) { + $this->rec(311); + } + goto k910; + f910: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n909; + k910: + n909: + } elseif ($this->p > $this->f) { + $this->rec(306); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f898;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f898;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b315()) { + goto f898;} + goto k898; + f898: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k898: + $this->v[$m1] = $this->reduceCallableWithTemplates(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b287(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + // b290 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (($this->ids[$this->p] === 13)) { + if (($this->ids[$this->p] === 13)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f570;} + } + if (($this->ids[$this->p] === 14)) { + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f570;} + } + goto k570; + f570: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n569; + k570: + goto a568; + n569: + break; + case 13: + // b288 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f572;} + goto k572; + f572: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n571; + k572: + goto a568; + n571: + // b290 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (($this->ids[$this->p] === 13)) { + if (($this->ids[$this->p] === 13)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f574;} + } + if (($this->ids[$this->p] === 14)) { + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f574;} + } + goto k574; + f574: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n573; + k574: + goto a568; + n573: + break; + case 14: + // b289 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f576;} + goto k576; + f576: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n575; + k576: + goto a568; + n575: + // b290 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (($this->ids[$this->p] === 13)) { + if (($this->ids[$this->p] === 13)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f578;} + } + if (($this->ids[$this->p] === 14)) { + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f578;} + } + goto k578; + f578: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n577; + k578: + goto a568; + n577: + break; + } + + if ($this->p > $this->f) { + $this->rec(287); + } + + goto f567; + a568: + goto k567; + f567: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k567: + + return true; + } + + private function b293(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 5)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n581;} + goto a580; + n581: + break; + case 5: + // b294 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f583;} + goto k583; + f583: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n582; + k583: + goto a580; + n582: + if (($this->ids[$this->p] === 5)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n584;} + goto a580; + n584: + break; + } + + if ($this->p > $this->f) { + $this->rec(293); + } + + goto f579; + a580: + goto k579; + f579: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k579: + + return true; + } + + private function b296(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n587;} + goto a586; + n587: + break; + case 46: + // b297 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f589;} + goto k589; + f589: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n588; + k589: + goto a586; + n588: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n590;} + goto a586; + n590: + break; + } + + if ($this->p > $this->f) { + $this->rec(296); + } + + goto f585; + a586: + goto k585; + f585: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k585: + + return true; + } + + private function b301(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(301); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1194; + } + + $this->p++; + } + e1194: + // b302 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + if (!$this->b304()) { + goto n1197;} + goto a1196; + n1197: + break; + case 35: + if (!($this->ids[$this->p] === 35)) { + if ($this->p > $this->f) { + $this->rec(56); + } + + goto n1198;} + goto a1196; + n1198: + break; + } + + if ($this->p > $this->f) { + $this->rec(302); + } + + goto f1195; + a1196: + goto k1195; + f1195: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f1192; + k1195: + goto k1192; + f1192: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1192: + + return true; + } + + private function b304(): bool + { + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(304); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + // b286 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b287()) { + goto f1470;} + if (!$this->b293()) { + goto f1470;} + if (!$this->b296()) { + goto f1470;} + goto k1470; + f1470: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f1469; + k1470: + $this->v[$m2] = $this->reduceCallableTemplateArgument(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1472; + } + + $this->p++; + } + e1472: + goto k1469; + f1469: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1469: + + return true; + } + + private function b307(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(307); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b199()) { + goto f1154;} + if (($this->ids[$this->p] === 27)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (($this->ids[$this->p] === 26)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(47); + } + if (($this->ids[$this->p] === 46)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + goto k1154; + f1154: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1154: + $this->v[$m1] = $this->reduceCallableParameter(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b311(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(311); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(312); + } + + goto e1156; + } + + // b312 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(312); + } + + goto e1156;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1159; + } + + $this->p++; + } + e1159: + if (!$this->b313()) { + goto f1157;} + goto k1157; + f1157: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto e1156; + k1157: + if ($this->p === $b1) { + $k1 = 1; + goto e1156; + } + + $k1++; + } + e1156: + + if ($k1 < 1) { + goto f1155; + } + goto k1155; + f1155: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1155: + + return true; + } + + private function b313(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + // b314 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b307()) { + goto f1452;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1454; + } + + $this->p++; + } + e1454: + goto k1452; + f1452: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1451; + k1452: + goto a1450; + n1451: + break; + case 33: + if (!($this->ids[$this->p] === 33)) { + if ($this->p > $this->f) { + $this->rec(53); + } + + goto n1455;} + goto a1450; + n1455: + break; + } + + if ($this->p > $this->f) { + $this->rec(313); + } + + goto f1449; + a1450: + goto k1449; + f1449: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1449: + + return true; + } + + private function b315(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(315); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 5: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // b331 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1163;} + } + if (!$this->b318()) { + goto f1163;} + goto k1163; + f1163: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1162; + k1163: + goto a1161; + n1162: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1165;} + } + if (!$this->b335()) { + goto f1165;} + goto k1165; + f1165: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1164; + k1165: + goto a1161; + n1164: + break; + case 19: + case 20: + case 21: + case 22: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1168;} + } + if (!$this->b335()) { + goto f1168;} + goto k1168; + f1168: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1167; + k1168: + goto a1161; + n1167: + break; + case 3: + case 4: + case 8: + if (!$this->b255()) { + goto n1170;} + goto a1161; + n1170: + // b317 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1172;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1172;} + } + if (!$this->b318()) { + goto f1172;} + goto k1172; + f1172: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1171; + k1172: + goto a1161; + n1171: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1174;} + } + if (!$this->b335()) { + goto f1174;} + goto k1174; + f1174: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1173; + k1174: + goto a1161; + n1173: + break; + case 32: + case 82: + if (!$this->b316()) { + goto n1176;} + goto a1161; + n1176: + break; + case 6: + if (!$this->b267()) { + goto n1177;} + goto a1161; + n1177: + // b317 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1179;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1179;} + } + if (!$this->b318()) { + goto f1179;} + goto k1179; + f1179: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1178; + k1179: + goto a1161; + n1178: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1181;} + } + if (!$this->b335()) { + goto f1181;} + goto k1181; + f1181: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1180; + k1181: + goto a1161; + n1180: + break; + case 7: + if (!$this->b230()) { + goto n1183;} + goto a1161; + n1183: + // b317 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1185;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1185;} + } + if (!$this->b318()) { + goto f1185;} + goto k1185; + f1185: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1184; + k1185: + goto a1161; + n1184: + // b333 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1187;} + } + if (!$this->b335()) { + goto f1187;} + goto k1187; + f1187: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1186; + k1187: + goto a1161; + n1186: + break; + case 25: + if (!$this->b229()) { + goto n1189;} + goto a1161; + n1189: + break; + case 30: + // b200 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b201()) { + goto f1191;} + goto k1191; + f1191: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1190; + k1191: + $this->v[$m2] = $this->reduceNullable(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a1161; + n1190: + break; + } + + if ($this->p > $this->f) { + $this->rec(315); + } + + goto f1160; + a1161: + goto k1160; + f1160: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1160: + $this->v[$m1] = $this->reduceCallableReturnType(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b316(): bool + { + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(316); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b205()) { + goto f1465;} + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f1465;} + + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n1466;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e1468; + } + + if (!$this->b224()) { + goto e1468;} + if ($this->p === $b2) { + $k2 = 1; + goto e1468; + } + + $k2++; + } + e1468: + + if ($k2 < 1) { + goto f1467; + } + goto k1467; + f1467: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1466; + k1467: + n1466: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k1465; + f1465: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1465: + + return true; + } + + private function b318(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1458;} + goto a1457; + n1458: + break; + case 34: + case 86: + if (!$this->b319()) { + goto n1459;} + goto a1457; + n1459: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1460;} + goto a1457; + n1460: + break; + case 36: + case 84: + // b223 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e1463; + } + + if (!$this->b224()) { + goto e1463;} + if ($this->p === $b2) { + $k2 = 1; + goto e1463; + } + + $k2++; + } + e1463: + + if ($k2 < 1) { + goto f1462; + } + goto k1462; + f1462: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1461; + k1462: + goto a1457; + n1461: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1464;} + goto a1457; + n1464: + break; + } + + if ($this->p > $this->f) { + $this->rec(318); + } + + goto f1456; + a1457: + goto k1456; + f1456: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1456: + + return true; + } + + private function b319(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(319); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b320()) { + goto f1646;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n1647;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e1649; + } + + if (!$this->b224()) { + goto e1649;} + if ($this->p === $b2) { + $k2 = 1; + goto e1649; + } + + $k2++; + } + e1649: + + if ($k2 < 1) { + goto f1648; + } + goto k1648; + f1648: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1647; + k1648: + n1647: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k1646; + f1646: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1646: + + return true; + } + + private function b320(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(320); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e303; + } + + $this->p++; + } + e303: + if (!$this->b321()) { + goto f301;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e305; + } + + $this->p++; + } + e305: + if (($this->ids[$this->p] === 40)) { + if (!$this->b327()) { + goto n306;} + n306: + } elseif ($this->p > $this->f) { + $this->rec(327); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f301;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k301; + f301: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k301: + $this->v[$m1] = $this->reduceGenericInReturnType(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b321(): bool + { + if (!isset(self::Tb3cd2a63[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(321); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + // b324 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (isset(self::T05cf281c[$this->ids[$this->p]])) { + if (isset(self::T05cf281c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f594;} + } + if (!$this->b199()) { + goto f594;} + goto k594; + f594: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n593; + k594: + goto a592; + n593: + break; + case 1: + case 2: + // b322 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b199()) { + goto f596;} + goto k596; + f596: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n595; + k596: + goto a592; + n595: + break; + case 50: + $this->v[$this->n++] = $this->token($this->p++); + goto a592; + break; + case 85: + $this->v[$this->n++] = $this->token($this->p++); + goto a592; + break; + } + + if ($this->p > $this->f) { + $this->rec(321); + } + + goto f591; + a592: + goto k591; + f591: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k591: + $this->v[$m1] = $this->reduceGenericArgument(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b327(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(327); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(328); + } + + goto e598; + } + + // b328 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(328); + } + + goto e598;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e601; + } + + $this->p++; + } + e601: + if (!$this->b329()) { + goto f599;} + goto k599; + f599: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto e598; + k599: + if ($this->p === $b1) { + $k1 = 1; + goto e598; + } + + $k1++; + } + e598: + + if ($k1 < 1) { + goto f597; + } + goto k597; + f597: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k597: + + return true; + } + + private function b329(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 50: + case 82: + case 85: + // b330 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b321()) { + goto f857;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e859; + } + + $this->p++; + } + e859: + goto k857; + f857: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n856; + k857: + goto a855; + n856: + break; + case 35: + if (!($this->ids[$this->p] === 35)) { + if ($this->p > $this->f) { + $this->rec(56); + } + + goto n860;} + goto a855; + n860: + break; + } + + if ($this->p > $this->f) { + $this->rec(329); + } + + goto f854; + a855: + goto k854; + f854: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k854: + + return true; + } + + private function b335(): bool + { + if (!isset(self::T4546fd6c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(335); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (isset(self::T1e81050f[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s337(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f665;} + } + if (!$this->b340()) { + goto f665;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n667;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e669; + } + + if (!$this->b224()) { + goto e669;} + if ($this->p === $b2) { + $k2 = 1; + goto e669; + } + + $k2++; + } + e669: + + if ($k2 < 1) { + goto f668; + } + goto k668; + f668: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n667; + k668: + n667: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k665; + f665: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k665: + + return true; + } + + private function b340(): bool + { + if (!isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(340); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + if (!$this->b357()) { + goto n197;} + goto a196; + n197: + break; + case 7: + case 18: + if (!$this->b347()) { + goto n198;} + goto a196; + n198: + break; + case 21: + case 22: + // b343 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 21: + $this->v[$this->n++] = $this->token($this->p++); + goto a201; + break; + case 22: + $this->v[$this->n++] = $this->token($this->p++); + goto a201; + break; + } + + if ($this->p > $this->f) { + $this->rec(343); + } + + goto f200; + a201: + goto k200; + f200: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n199; + k200: + $this->v[$m2] = $this->reduceConstantString(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto a196; + n199: + break; + case 36: + case 84: + if (!$this->b361()) { + goto n202;} + goto a196; + n202: + break; + case 15: + $this->v[$this->n++] = $this->reduceConstantFalse($this->indexes[$this->p], $this->indexes[$this->p]); + $this->p++; + goto a196; + break; + case 16: + $this->v[$this->n++] = $this->reduceConstantTrue($this->indexes[$this->p], $this->indexes[$this->p]); + $this->p++; + goto a196; + break; + case 17: + $this->v[$this->n++] = $this->reduceConstantNull($this->indexes[$this->p], $this->indexes[$this->p]); + $this->p++; + goto a196; + break; + case 19: + $this->v[$this->n++] = $this->reduceConstantFloat($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a196; + break; + case 20: + $this->v[$this->n++] = $this->reduceConstantInteger($this->indexes[$this->p], $this->indexes[$this->p], [$this->token($this->p)]); + $this->p++; + goto a196; + break; + } + + if ($this->p > $this->f) { + $this->rec(340); + } + + goto f195; + a196: + goto k195; + f195: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k195: + + return true; + } + + private function b347(): bool + { + if (!isset(self::T1ad6c327[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(347); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f474;} + + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if (!$this->b349()) { + goto n475;} + n475: + } elseif ($this->p > $this->f) { + $this->rec(349); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f474;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k474; + f474: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k474: + $this->v[$m1] = $this->reduceConstantArrayLiteral(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b349(): bool + { + if (!isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(349); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + // b350 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b340()) { + goto f758;} + if (!$this->b351()) { + goto f758;} + goto k758; + f758: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f757; + k758: + $this->v[$m2] = $this->reduceConstantArrayItem(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + if (($this->ids[$this->p] === 40)) { + // b355 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(355); + } + + goto n759;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(356); + } + + goto e761; + } + + if (!$this->b356()) { + goto e761;} + if ($this->p === $b2) { + $k2 = 1; + goto e761; + } + + $k2++; + } + e761: + + if ($k2 < 1) { + goto f760; + } + goto k760; + f760: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n759; + k760: + n759: + } elseif ($this->p > $this->f) { + $this->rec(355); + } + if (($this->ids[$this->p] === 40)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(63); + } + goto k757; + f757: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k757: + + return true; + } + + private function b351(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 44)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1047;} + goto a1046; + n1047: + break; + case 44: + // b352 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b340()) { + goto f1049;} + goto k1049; + f1049: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1048; + k1049: + goto a1046; + n1048: + if (($this->ids[$this->p] === 44)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1050;} + goto a1046; + n1050: + break; + } + + if ($this->p > $this->f) { + $this->rec(351); + } + + goto f1045; + a1046: + goto k1045; + f1045: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1045: + + return true; + } + + private function b356(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(356); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b350 + if (!isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(350); + } + + goto f1051;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b340()) { + goto f1052;} + if (!$this->b351()) { + goto f1052;} + goto k1052; + f1052: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f1051; + k1052: + $this->v[$m2] = $this->reduceConstantArrayItem(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto k1051; + f1051: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1051: + + return true; + } + + private function b357(): bool + { + if (!isset(self::Td08a6883[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(357); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (isset(self::T1ad6c327[$this->ids[$this->p]])) { + if (isset(self::T1ad6c327[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f471;} + } + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f471;} + + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 43)) { + // b360 + if (!($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->rec(360); + } + + goto n472;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b163()) { + goto f473;} + goto k473; + f473: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n472; + k473: + n472: + } elseif ($this->p > $this->f) { + $this->rec(360); + } + goto k471; + f471: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k471: + $this->v[$m1] = $this->reduceConstantFetch(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b361(): bool + { + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(361); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if (!$this->b349()) { + goto n477;} + n477: + } elseif ($this->p > $this->f) { + $this->rec(349); + } + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f476;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k476; + f476: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k476: + $this->v[$m1] = $this->reduceConstantArrayShorthand(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b362(): bool + { + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(362); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (!$this->b363()) { + goto f914;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // b223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n915;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e917; + } + + if (!$this->b224()) { + goto e917;} + if ($this->p === $b2) { + $k2 = 1; + goto e917; + } + + $k2++; + } + e917: + + if ($k2 < 1) { + goto f916; + } + goto k916; + f916: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n915; + k916: + n915: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k914; + f914: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k914: + + return true; + } + + private function b363(): bool + { + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(363); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1201; + } + + $this->p++; + } + e1201: + if (!$this->b321()) { + goto f1199;} + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1203; + } + + $this->p++; + } + e1203: + if (($this->ids[$this->p] === 40)) { + if (!$this->b327()) { + goto n1204;} + n1204: + } elseif ($this->p > $this->f) { + $this->rec(327); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1199;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k1199; + f1199: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1199: + $this->v[$m1] = $this->reduceGeneric(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b364(): bool + { + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(364); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e884; + } + + $this->p++; + } + e884: + if (isset(self::T7680fe2e[$this->ids[$this->p]])) { + // b306 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(306); + } + + goto n885;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b307()) { + goto f886;} + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e888; + } + + $this->p++; + } + e888: + if (($this->ids[$this->p] === 40)) { + if (!$this->b311()) { + goto n889;} + n889: + } elseif ($this->p > $this->f) { + $this->rec(311); + } + goto k886; + f886: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n885; + k886: + n885: + } elseif ($this->p > $this->f) { + $this->rec(306); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f882;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f882;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b315()) { + goto f882;} + goto k882; + f882: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k882: + $this->v[$m1] = $this->reduceCallable(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b368(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + // b383 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f419;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f419;} + } + goto k419; + f419: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n418; + k419: + goto a417; + n418: + break; + case 28: + case 29: + case 41: + case 80: + if (!$this->b369()) { + goto n420;} + goto a417; + n420: + // b383 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f422;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f422;} + } + goto k422; + f422: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n421; + k422: + goto a417; + n421: + break; + } + + if ($this->p > $this->f) { + $this->rec(368); + } + + goto f416; + a417: + goto k416; + f416: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k416: + + return true; + } + + private function b369(): bool + { + if (!isset(self::T8458d590[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(369); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + // b203 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e696; + } + + $this->p++; + } + e696: + if (!$this->b370()) { + goto f694;} + goto k694; + f694: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k694: + + return true; + } + + private function b370(): bool + { + if (!isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(370); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 28: + // b371 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b372 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 28)) { + if ($b3 > $this->f) { + $this->rec(373); + } + + goto e958; + } + + if (!$this->b373()) { + goto e958;} + if ($this->p === $b3) { + $k3 = 1; + goto e958; + } + + $k3++; + } + e958: + + if ($k3 < 1) { + goto f957; + } + goto k957; + f957: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f956; + k957: + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f956;} + } + goto k956; + f956: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n955; + k956: + goto a954; + n955: + break; + case 29: + // b377 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b378 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 29)) { + if ($b3 > $this->f) { + $this->rec(379); + } + + goto e962; + } + + if (!$this->b379()) { + goto e962;} + if ($this->p === $b3) { + $k3 = 1; + goto e962; + } + + $k3++; + } + e962: + + if ($k3 < 1) { + goto f961; + } + goto k961; + f961: + $this->p = $o3; + $this->n = $m3; + $this->comments = $cs3; + goto f960; + k961: + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f960;} + } + goto k960; + f960: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n959; + k960: + goto a954; + n959: + break; + } + + if ($this->p > $this->f) { + $this->rec(370); + } + + goto f953; + a954: + goto k953; + f953: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k953: + + return true; + } + + private function b373(): bool + { + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(373); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b201()) { + goto f1251;} + // b375 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1255; + } + + $this->p++; + } + e1255: + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(49); + } + + goto f1253;} + goto k1253; + f1253: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1252; + k1253: + n1252: + goto k1251; + f1251: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1251: + + return true; + } + + private function b379(): bool + { + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(379); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b201()) { + goto f1256;} + // b381 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b203 + $o3 = $this->p; + $m3 = $this->n; + $cs3 = $this->comments; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1260; + } + + $this->p++; + } + e1260: + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(50); + } + + goto f1258;} + goto k1258; + f1258: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1257; + k1258: + n1257: + goto k1256; + f1256: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1256: + + return true; + } + + private function b385(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (!$this->b388()) { + goto n327;} + goto a326; + n327: + break; + case 25: + case 26: + // b386 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o3 = $this->p; + if (!$this->s125()) { + goto f329;} + $this->v[$this->n++] = $this->reduceText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k329; + f329: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n328; + k329: + goto a326; + n328: + if (!$this->b388()) { + goto n331;} + goto a326; + n331: + break; + } + + if ($this->p > $this->f) { + $this->rec(385); + } + + goto f325; + a326: + goto k325; + f325: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k325: + + return true; + } + + private function b388(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f290;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f290;} + } + if (($this->ids[$this->p] === 32)) { + if (($this->ids[$this->p] === 32)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f290;} + } + // b125 + $o2 = $this->p; + if (!$this->s125()) { + goto f290;} + $this->v[$this->n++] = $this->reduceText(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1))); + goto k290; + f290: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k290: + + return true; + } + + private function b400(): bool + { + if (!($this->ids[$this->p] === 67)) { + if ($this->p > $this->f) { + $this->rec(400); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b399 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(399); + } + + goto f309;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b199()) { + goto f310;} + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f310;} + + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o3 = $this->p; + if (!$this->s125()) { + goto f310;} + $this->v[$this->n++] = $this->reduceText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k310; + f310: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f309; + k310: + goto k309; + f309: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k309: + + return true; + } + + private function b409(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(409); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + // b435 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b199()) { + goto f315;} + if (!$this->b415()) { + goto f315;} + goto k315; + f315: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n314; + k315: + goto a313; + n314: + break; + case 9: + // b410 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T648acf56[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s412(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f317;} + } + if (!$this->b199()) { + goto f317;} + if (!$this->b415()) { + goto f317;} + goto k317; + f317: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n316; + k317: + goto a313; + n316: + // b435 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b199()) { + goto f320;} + if (!$this->b415()) { + goto f320;} + goto k320; + f320: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n319; + k320: + goto a313; + n319: + break; + } + + if ($this->p > $this->f) { + $this->rec(409); + } + + goto f312; + a313: + goto k312; + f312: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k312: + + return true; + } + + private function b415(): bool + { + if (!isset(self::T02ca7bff[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(415); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // b416 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b417()) { + goto f605;} + goto k605; + f605: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n604; + k605: + goto a603; + n604: + break; + case 32: + case 34: + case 82: + case 86: + if (!$this->b417()) { + goto n606;} + goto a603; + n606: + break; + } + + if ($this->p > $this->f) { + $this->rec(415); + } + + goto f602; + a603: + goto k602; + f602: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k602: + + return true; + } + + private function b417(): bool + { + if (!isset(self::Tf86de613[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(417); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + // b418 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n864;} + goto a863; + n864: + break; + case 34: + case 86: + if (!$this->b419()) { + goto n865;} + goto a863; + n865: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n866;} + goto a863; + n866: + break; + } + + if ($this->p > $this->f) { + $this->rec(418); + } + + goto f862; + a863: + goto k862; + f862: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f861; + k862: + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f861;} + + $this->v[$this->n++] = $this->token($this->p++); + if (isset(self::T9373805c[$this->ids[$this->p]])) { + // b424 + if (!isset(self::T9373805c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(424); + } + + goto n867;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!$this->b425()) { + goto f868;} + if (($this->ids[$this->p] === 40)) { + if (!$this->b433()) { + goto n869;} + n869: + } elseif ($this->p > $this->f) { + $this->rec(433); + } + goto k868; + f868: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n867; + k868: + n867: + } elseif ($this->p > $this->f) { + $this->rec(424); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f861;} + + $this->v[$this->n++] = $this->token($this->p++); + // b125 + $o2 = $this->p; + if (!$this->s125()) { + goto f861;} + $this->v[$this->n++] = $this->reduceText(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1))); + goto k861; + f861: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k861: + + return true; + } + + private function b419(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(419); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b286 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(286); + } + + goto f1120;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b287()) { + goto f1121;} + if (!$this->b293()) { + goto f1121;} + if (!$this->b296()) { + goto f1121;} + goto k1121; + f1121: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f1120; + k1121: + $this->v[$m2] = $this->reduceCallableTemplateArgument(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + if (($this->ids[$this->p] === 40)) { + // b421 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(421); + } + + goto n1122;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(422); + } + + goto e1124; + } + + if (!$this->b422()) { + goto e1124;} + if ($this->p === $b2) { + $k2 = 1; + goto e1124; + } + + $k2++; + } + e1124: + + if ($k2 < 1) { + goto f1123; + } + goto k1123; + f1123: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1122; + k1123: + n1122: + } elseif ($this->p > $this->f) { + $this->rec(421); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1120;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k1120; + f1120: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1120: + + return true; + } + + private function b422(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(422); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + // b286 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(286); + } + + goto f1417;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b287()) { + goto f1418;} + if (!$this->b293()) { + goto f1418;} + if (!$this->b296()) { + goto f1418;} + goto k1418; + f1418: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f1417; + k1418: + $this->v[$m2] = $this->reduceCallableTemplateArgument(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto k1417; + f1417: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1417: + + return true; + } + + private function b425(): bool + { + if (!isset(self::T9373805c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(425); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + case 30: + case 32: + case 82: + // b426 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (!isset(self::T34c34eee[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(428); + } + + goto f1128;} + if (!$this->b199()) { + goto f1128;} + if (($this->ids[$this->p] === 27)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f1128;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b429()) { + goto f1128;} + goto k1128; + f1128: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1127; + k1128: + goto a1126; + n1127: + break; + case 26: + case 27: + case 42: + // b431 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + if (($this->ids[$this->p] === 27)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f1130;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b429()) { + goto f1130;} + goto k1130; + f1130: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1129; + k1130: + goto a1126; + n1129: + break; + } + + if ($this->p > $this->f) { + $this->rec(425); + } + + goto f1125; + a1126: + goto k1125; + f1125: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1125: + $this->v[$m1] = $this->reduceMethodParameter(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b429(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1421;} + goto a1420; + n1421: + break; + case 46: + // b430 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b340()) { + goto f1423;} + goto k1423; + f1423: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n1422; + k1423: + goto a1420; + n1422: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1424;} + goto a1420; + n1424: + break; + } + + if ($this->p > $this->f) { + $this->rec(429); + } + + goto f1419; + a1420: + goto k1419; + f1419: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1419: + + return true; + } + + private function b433(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(433); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(434); + } + + goto e1132; + } + + // b434 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(434); + } + + goto e1132;} + + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b425()) { + goto f1133;} + goto k1133; + f1133: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto e1132; + k1133: + if ($this->p === $b1) { + $k1 = 1; + goto e1132; + } + + $k1++; + } + e1132: + + if ($k1 < 1) { + goto f1131; + } + goto k1131; + f1131: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k1131: + + return true; + } + + private function b436(): bool + { + if (!($this->ids[$this->p] === 62)) { + if ($this->p > $this->f) { + $this->rec(436); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f300;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b287()) { + goto f300;} + if (!$this->b293()) { + goto f300;} + if (!$this->b296()) { + goto f300;} + if (!$this->b388()) { + goto f300;} + goto k300; + f300: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k300: + + return true; + } + + private function b442(): bool + { + if (!($this->ids[$this->p] === 66)) { + if ($this->p > $this->f) { + $this->rec(442); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f307;} + + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 46)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + // b125 + $o2 = $this->p; + if (!$this->s125()) { + goto f307;} + $this->v[$this->n++] = $this->reduceText(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1))); + goto k307; + f307: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k307: + $this->v[$m1] = $this->reduceInvalidTypeAliasTag(($o1 < $this->p ? $this->indexes[$o1] : ($o1 > 0 ? $this->indexes[$o1 - 1] + 1 : 0)), ($o1 < $this->p ? $this->indexes[$this->p - 1] : ($o1 > 0 ? $this->indexes[$o1 - 1] : -1)), $this->n === $m1 + 1 ? [$this->v[$m1]] : \array_slice($this->v, $m1, $this->n - $m1)); + $this->n = $m1 + 1; + + return true; + } + + private function b444(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n294;} + goto a293; + n294: + break; + case 14: + // b445 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f296;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k296; + f296: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n295; + k296: + goto a293; + n295: + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n297;} + goto a293; + n297: + break; + } + + if ($this->p > $this->f) { + $this->rec(444); + } + + goto f292; + a293: + goto k292; + f292: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k292: + + return true; + } + + private function b446(): bool + { + if (!($this->ids[$this->p] === 59)) { + if ($this->p > $this->f) { + $this->rec(446); + } + + return false;} + + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (($this->ids[$this->p] === 31)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(52); + } + if (($this->ids[$this->p] === 46)) { + $this->v[$this->n++] = $this->token($this->p++); + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + if (!$this->b199()) { + goto f298;} + if (!isset(self::T29c7f960[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(448); + } + + goto f298;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b449()) { + goto f298;} + // b125 + $o2 = $this->p; + if (!$this->s125()) { + goto f298;} + $this->v[$this->n++] = $this->reduceText(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1))); + goto k298; + f298: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k298: + + return true; + } + + private function b449(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 45)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n563;} + goto a562; + n563: + break; + case 45: + // b450 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f565;} + + $this->v[$this->n++] = $this->token($this->p++); + if (!$this->b451()) { + goto f565;} + goto k565; + f565: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n564; + k565: + goto a562; + n564: + if (($this->ids[$this->p] === 45)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n566;} + goto a562; + n566: + break; + } + + if ($this->p > $this->f) { + $this->rec(449); + } + + goto f561; + a562: + goto k561; + f561: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k561: + + return true; + } + + private function b451(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n850;} + goto a849; + n850: + break; + case 32: + case 82: + // b452 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + $this->v[$this->n++] = $this->token($this->p++); + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f852;} + + $this->v[$this->n++] = $this->token($this->p++); + goto k852; + f852: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto n851; + k852: + goto a849; + n851: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n853;} + goto a849; + n853: + break; + } + + if ($this->p > $this->f) { + $this->rec(451); + } + + goto f848; + a849: + goto k848; + f848: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k848: + + return true; + } + + private function b455(): bool + { + $o1 = $this->p; + $m1 = $this->n; + $cs1 = $this->comments; + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f279;} + } + // b457 + $o2 = $this->p; + $m2 = $this->n; + $cs2 = $this->comments; + // b125 + $o3 = $this->p; + if (!$this->s125()) { + goto f280;} + $this->v[$this->n++] = $this->reduceText(($o3 < $this->p ? $this->indexes[$o3] : ($o3 > 0 ? $this->indexes[$o3 - 1] + 1 : 0)), ($o3 < $this->p ? $this->indexes[$this->p - 1] : ($o3 > 0 ? $this->indexes[$o3 - 1] : -1))); + goto k280; + f280: + $this->p = $o2; + $this->n = $m2; + $this->comments = $cs2; + goto f279; + k280: + $this->v[$m2] = $this->reduceTextChild(($o2 < $this->p ? $this->indexes[$o2] : ($o2 > 0 ? $this->indexes[$o2 - 1] + 1 : 0)), ($o2 < $this->p ? $this->indexes[$this->p - 1] : ($o2 > 0 ? $this->indexes[$o2 - 1] : -1)), $this->n === $m2 + 1 ? [$this->v[$m2]] : \array_slice($this->v, $m2, $this->n - $m2)); + $this->n = $m2 + 1; + goto k279; + f279: + $this->p = $o1; + $this->n = $m1; + $this->comments = $cs1; + return false; + k279: + + return true; + } + + private function s0(): bool + { + if (!($this->ids[$this->p] === 48)) { + if ($this->p > $this->f) { + $this->rec(0); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 80)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(3); + } + // s5 + $o2 = $this->p; + if (($this->ids[$this->p] === 49)) { + if (($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f5;} + } + if (!$this->s8()) { + goto f5;} + // s460 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + // s461 + $o4 = $this->p; + if (($this->ids[$this->p] === 49)) { + if (($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f8;} + } + if (!$this->s8()) { + goto f8;} + goto k8; + f8: + $this->p = $o4; + goto e7; + k8: + if ($this->p === $b3) { + goto e7; + } + } + e7: + goto k5; + f5: + $this->p = $o2; + goto n4; + k5: + n4: + if (!($this->ids[$this->p] === 49)) { + if ($this->p >= $this->f) { + $this->rec(7); + } + + goto f3;} + + $this->p++; + goto k3; + f3: + $this->p = $o1; + return false; + k3: + + return true; + } + + private function s8(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s188 + $o2 = $this->p; + if (!$this->s189()) { + goto f225;} + // s458 + $o3 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 49: + if (!($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->rec(7); + } + + goto n228;} + goto a227; + n228: + break; + case 80: + $this->p++; + goto a227; + break; + } + + if ($this->p > $this->f) { + $this->rec(458); + } + + goto f226; + a227: + goto k226; + f226: + $this->p = $o3; + goto f225; + k226: + goto k225; + f225: + $this->p = $o2; + goto n224; + k225: + goto a223; + n224: + break; + case 76: + case 77: + case 78: + case 79: + if (!$this->s9()) { + goto n229;} + goto a223; + n229: + // s188 + $o2 = $this->p; + if (!$this->s189()) { + goto f231;} + // s458 + $o3 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 49: + if (!($this->ids[$this->p] === 49)) { + if ($this->p > $this->f) { + $this->rec(7); + } + + goto n234;} + goto a233; + n234: + break; + case 80: + $this->p++; + goto a233; + break; + } + + if ($this->p > $this->f) { + $this->rec(458); + } + + goto f232; + a233: + goto k232; + f232: + $this->p = $o3; + goto f231; + k232: + goto k231; + f231: + $this->p = $o2; + goto n230; + k231: + goto a223; + n230: + break; + } + + if ($this->p > $this->f) { + $this->rec(8); + } + + goto f222; + a223: + goto k222; + f222: + $this->p = $o1; + return false; + k222: + + return true; + } + + private function s9(): bool + { + if (!isset(self::T942497bd[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(9); + } + + return false;} + + $o1 = $this->p; + if (!$this->s10()) { + goto f515;} + if (($this->ids[$this->p] === 80)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(3); + } + goto k515; + f515: + $this->p = $o1; + return false; + k515: + + return true; + } + + private function s10(): bool + { + if (!isset(self::T942497bd[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(10); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 76: + case 77: + // s11 + $o2 = $this->p; + $this->p++; + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f17;} + } + // s19 + $o3 = $this->p; + // s20 + $o4 = $this->p; + while (true) { + $b4 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b4 > $this->f) { + $this->rec(21); + } + + goto e20; + } + + $this->p++; + } + e20: + if (!$this->s74()) { + goto f18;} + goto k18; + f18: + $this->p = $o3; + goto f17; + k18: + goto k17; + f17: + $this->p = $o2; + goto n16; + k17: + goto a15; + n16: + // s134 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 76: + case 77: + if (!$this->s187()) { + goto n24;} + goto a23; + n24: + break; + case 78: + case 79: + if (!$this->s135()) { + goto n25;} + goto a23; + n25: + break; + } + + if ($this->p > $this->f) { + $this->rec(134); + } + + goto f22; + a23: + goto k22; + f22: + $this->p = $o2; + goto n21; + k22: + goto a15; + n21: + break; + case 78: + case 79: + // s134 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 76: + case 77: + if (!$this->s187()) { + goto n29;} + goto a28; + n29: + break; + case 78: + case 79: + if (!$this->s135()) { + goto n30;} + goto a28; + n30: + break; + } + + if ($this->p > $this->f) { + $this->rec(134); + } + + goto f27; + a28: + goto k27; + f27: + $this->p = $o2; + goto n26; + k27: + goto a15; + n26: + break; + } + + if ($this->p > $this->f) { + $this->rec(10); + } + + goto f14; + a15: + goto k14; + f14: + $this->p = $o1; + return false; + k14: + + return true; + } + + private function s74(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s75 + $o2 = $this->p; + if (!isset(self::T53b29bff[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(77); + } + + goto f257;} + if (!$this->s78()) { + goto f257;} + goto k257; + f257: + $this->p = $o2; + goto n256; + k257: + goto a255; + n256: + // s117 + $o2 = $this->p; + if (!isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(119); + } + + goto f259;} + if (isset(self::Tb3a20a39[$this->ids[$this->p]])) { + if (isset(self::Tb3a20a39[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f259;} + } + if (isset(self::Tce49e0fc[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s123(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f259;} + } + if (!$this->s125()) { + goto f259;} + goto k259; + f259: + $this->p = $o2; + goto n258; + k259: + goto a255; + n258: + break; + case 76: + case 78: + // s75 + $o2 = $this->p; + if (!isset(self::T53b29bff[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(77); + } + + goto f262;} + if (!$this->s78()) { + goto f262;} + goto k262; + f262: + $this->p = $o2; + goto n261; + k262: + goto a255; + n261: + // s117 + $o2 = $this->p; + if (!isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(119); + } + + goto f264;} + if (isset(self::Tb3a20a39[$this->ids[$this->p]])) { + if (isset(self::Tb3a20a39[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f264;} + } + if (isset(self::Tce49e0fc[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s123(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f264;} + } + if (!$this->s125()) { + goto f264;} + goto k264; + f264: + $this->p = $o2; + goto n263; + k264: + goto a255; + n263: + if (!isset(self::Tb3a20a39[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(121); + } + + goto n266;} + goto a255; + n266: + break; + } + + if ($this->p > $this->f) { + $this->rec(74); + } + + goto f254; + a255: + goto k254; + f254: + $this->p = $o1; + return false; + k254: + + return true; + } + + private function s78(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 80)) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s113(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n531;} + } + goto a530; + n531: + break; + case 80: + // s79 + $o2 = $this->p; + $this->p++; + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f534;} + } + // s109 + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(109); + } + + goto f534;} + + $o3 = $this->p; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(21); + } + + goto e536; + } + + $this->p++; + + $k3++; + } + e536: + + if ($k3 < 1) { + goto f535; + } + goto k535; + f535: + $this->p = $o3; + goto f534; + k535: + if (!$this->s74()) { + goto f534;} + goto k534; + f534: + $this->p = $o2; + goto n533; + k534: + goto a530; + n533: + // s110 + $o2 = $this->p; + $this->p++; + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f538;} + } + if (!$this->s111()) { + goto f538;} + goto k538; + f538: + $this->p = $o2; + goto n537; + k538: + goto a530; + n537: + if (($this->ids[$this->p] === 80)) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s113(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n539;} + } + goto a530; + n539: + break; + } + + if ($this->p > $this->f) { + $this->rec(78); + } + + goto f529; + a530: + goto k529; + f529: + $this->p = $o1; + return false; + k529: + + return true; + } + + private function s111(): bool + { + if (!($this->ids[$this->p] === 80)) { + if ($this->p > $this->f) { + $this->rec(111); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 80: + // s79 + $o2 = $this->p; + $this->p++; + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f811;} + } + // s109 + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(109); + } + + goto f811;} + + $o3 = $this->p; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(21); + } + + goto e813; + } + + $this->p++; + + $k3++; + } + e813: + + if ($k3 < 1) { + goto f812; + } + goto k812; + f812: + $this->p = $o3; + goto f811; + k812: + if (!$this->s74()) { + goto f811;} + goto k811; + f811: + $this->p = $o2; + goto n810; + k811: + goto a809; + n810: + // s110 + $o2 = $this->p; + $this->p++; + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f815;} + } + if (!$this->s111()) { + goto f815;} + goto k815; + f815: + $this->p = $o2; + goto n814; + k815: + goto a809; + n814: + break; + } + + if ($this->p > $this->f) { + $this->rec(111); + } + + goto f808; + a809: + goto k808; + f808: + $this->p = $o1; + return false; + k808: + + return true; + } + + private function s113(): bool + { + if (!($this->ids[$this->p] === 80)) { + if ($this->p > $this->f) { + $this->rec(113); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 80: + // s114 + $o2 = $this->p; + $this->p++; + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f805;} + } + if (!$this->s113()) { + goto f805;} + goto k805; + f805: + $this->p = $o2; + goto n804; + k805: + goto a803; + n804: + // s115 + $o2 = $this->p; + $this->p++; + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f807;} + } + if (!isset(self::T61cd0e44[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(116); + } + + goto f807;} + + $this->p++; + goto k807; + f807: + $this->p = $o2; + goto n806; + k807: + goto a803; + n806: + break; + } + + if ($this->p > $this->f) { + $this->rec(113); + } + + goto f802; + a803: + goto k802; + f802: + $this->p = $o1; + return false; + k802: + + return true; + } + + private function s123(): bool + { + if (!isset(self::Tce49e0fc[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(123); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f541;} + + $this->p++; + goto k541; + f541: + $this->p = $o1; + return false; + k541: + + return true; + } + + private function s125(): bool + { + $o1 = $this->p; + // s126 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T61cd0e44[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(116); + } + + goto e284; + } + + $this->p++; + } + e284: + if (($this->ids[$this->p] === 80)) { + // s128 + if (!($this->ids[$this->p] === 80)) { + if ($this->p > $this->f) { + $this->rec(128); + } + + goto n285;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 > $this->f) { + $this->rec(129); + } + + goto e287; + } + + if (!$this->s129()) { + goto e287;} + if ($this->p === $b2) { + $k2 = 1; + goto e287; + } + + $k2++; + } + e287: + + if ($k2 < 1) { + goto f286; + } + goto k286; + f286: + $this->p = $o2; + goto n285; + k286: + n285: + } elseif ($this->p > $this->f) { + $this->rec(128); + } + + return true; + } + + private function s129(): bool + { + if (!($this->ids[$this->p] === 80)) { + if ($this->p > $this->f) { + $this->rec(129); + } + + return false;} + + $o1 = $this->p; + // s130 + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 > $this->f) { + $this->rec(131); + } + + goto e557; + } + + // s131 + if (!($this->ids[$this->p] === 80)) { + if ($this->p > $this->f) { + $this->rec(131); + } + + goto e557;} + + $o3 = $this->p; + $this->p++; + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if (isset(self::T195b3f33[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f558;} + } + goto k558; + f558: + $this->p = $o3; + goto e557; + k558: + if ($this->p === $b2) { + $k2 = 1; + goto e557; + } + + $k2++; + } + e557: + + if ($k2 < 1) { + goto f556; + } + goto k556; + f556: + $this->p = $o2; + goto f555; + k556: + // s132 + if (!isset(self::T61cd0e44[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(132); + } + + goto f555;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T61cd0e44[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(116); + } + + goto e560; + } + + $this->p++; + + $k2++; + } + e560: + + if ($k2 < 1) { + goto f559; + } + goto k559; + f559: + $this->p = $o2; + goto f555; + k559: + goto k555; + f555: + $this->p = $o1; + return false; + k555: + + return true; + } + + private function s135(): bool + { + if (!isset(self::T46ee5f48[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(135); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!$this->s137()) { + goto f275;} + // s19 + $o2 = $this->p; + // s20 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(21); + } + + goto e278; + } + + $this->p++; + } + e278: + if (!$this->s74()) { + goto f276;} + goto k276; + f276: + $this->p = $o2; + goto f275; + k276: + goto k275; + f275: + $this->p = $o1; + return false; + k275: + + return true; + } + + private function s137(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n548;} + goto a547; + n548: + break; + case 32: + case 82: + // s138 + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e552; + } + + $this->p++; + } + e552: + if (isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if (!$this->s141()) { + goto n553;} + n553: + } elseif ($this->p > $this->f) { + $this->rec(141); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f550;} + + $this->p++; + goto k550; + f550: + $this->p = $o2; + goto n549; + k550: + goto a547; + n549: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n554;} + goto a547; + n554: + break; + } + + if ($this->p > $this->f) { + $this->rec(137); + } + + goto f546; + a547: + goto k546; + f546: + $this->p = $o1; + return false; + k546: + + return true; + } + + private function s141(): bool + { + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(141); + } + + return false;} + + $o1 = $this->p; + if (!$this->s142()) { + goto f542;} + // s139 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e544; + } + + $this->p++; + } + e544: + if (($this->ids[$this->p] === 40)) { + if (!$this->s182()) { + goto n545;} + n545: + } elseif ($this->p > $this->f) { + $this->rec(182); + } + goto k542; + f542: + $this->p = $o1; + return false; + k542: + + return true; + } + + private function s142(): bool + { + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(142); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + if (!$this->s146()) { + goto n818;} + goto a817; + n818: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + // s143 + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e822; + } + + $this->p++; + } + e822: + if (!($this->ids[$this->p] === 46)) { + if ($this->p >= $this->f) { + $this->rec(69); + } + + goto f820;} + + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e824; + } + + $this->p++; + } + e824: + if (!$this->s145()) { + goto f820;} + goto k820; + f820: + $this->p = $o2; + goto n819; + k820: + goto a817; + n819: + // s172 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f826;} + } + goto k826; + f826: + $this->p = $o2; + goto n825; + k826: + goto a817; + n825: + // s160 + $o2 = $this->p; + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f828;} + } + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f828;} + + $this->p++; + if (!($this->ids[$this->p] === 43)) { + if ($this->p >= $this->f) { + $this->rec(66); + } + + goto f828;} + + $this->p++; + if (!$this->s163()) { + goto f828;} + goto k828; + f828: + $this->p = $o2; + goto n827; + k828: + goto a817; + n827: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + // s143 + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e832; + } + + $this->p++; + } + e832: + if (!($this->ids[$this->p] === 46)) { + if ($this->p >= $this->f) { + $this->rec(69); + } + + goto f830;} + + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e834; + } + + $this->p++; + } + e834: + if (!$this->s145()) { + goto f830;} + goto k830; + f830: + $this->p = $o2; + goto n829; + k830: + goto a817; + n829: + // s172 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f836;} + } + goto k836; + f836: + $this->p = $o2; + goto n835; + k836: + goto a817; + n835: + break; + case 22: + case 23: + if (!$this->s155()) { + goto n837;} + goto a817; + n837: + break; + case 38: + case 83: + // s148 + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e841; + } + + $this->p++; + } + e841: + if (isset(self::T1490fe7f[$this->ids[$this->p]])) { + if (!$this->s151()) { + goto n842;} + n842: + } elseif ($this->p > $this->f) { + $this->rec(151); + } + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f839;} + + $this->p++; + goto k839; + f839: + $this->p = $o2; + goto n838; + k839: + goto a817; + n838: + break; + case 19: + $this->p++; + goto a817; + break; + case 20: + $this->p++; + goto a817; + break; + } + + if ($this->p > $this->f) { + $this->rec(142); + } + + goto f816; + a817: + goto k816; + f816: + $this->p = $o1; + return false; + k816: + + return true; + } + + private function s145(): bool + { + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(145); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + if (!$this->s146()) { + goto n1089;} + goto a1088; + n1089: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + // s172 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1091;} + } + goto k1091; + f1091: + $this->p = $o2; + goto n1090; + k1091: + goto a1088; + n1090: + // s160 + $o2 = $this->p; + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1093;} + } + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f1093;} + + $this->p++; + if (!($this->ids[$this->p] === 43)) { + if ($this->p >= $this->f) { + $this->rec(66); + } + + goto f1093;} + + $this->p++; + if (!$this->s163()) { + goto f1093;} + goto k1093; + f1093: + $this->p = $o2; + goto n1092; + k1093: + goto a1088; + n1092: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + // s172 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1095;} + } + goto k1095; + f1095: + $this->p = $o2; + goto n1094; + k1095: + goto a1088; + n1094: + break; + case 22: + case 23: + if (!$this->s155()) { + goto n1096;} + goto a1088; + n1096: + break; + case 38: + case 83: + // s148 + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1100; + } + + $this->p++; + } + e1100: + if (isset(self::T1490fe7f[$this->ids[$this->p]])) { + if (!$this->s151()) { + goto n1101;} + n1101: + } elseif ($this->p > $this->f) { + $this->rec(151); + } + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f1098;} + + $this->p++; + goto k1098; + f1098: + $this->p = $o2; + goto n1097; + k1098: + goto a1088; + n1097: + break; + case 19: + $this->p++; + goto a1088; + break; + case 20: + $this->p++; + goto a1088; + break; + } + + if ($this->p > $this->f) { + $this->rec(145); + } + + goto f1087; + a1088: + goto k1087; + f1087: + $this->p = $o1; + return false; + k1087: + + return true; + } + + private function s146(): bool + { + if (!isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(146); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + // s138 + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(138); + } + + goto n1082;} + + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1085; + } + + $this->p++; + } + e1085: + if (isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if (!$this->s141()) { + goto n1086;} + n1086: + } elseif ($this->p > $this->f) { + $this->rec(141); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f1083;} + + $this->p++; + goto k1083; + f1083: + $this->p = $o2; + goto n1082; + k1083: + n1082: + } elseif ($this->p > $this->f) { + $this->rec(138); + } + + return true; + } + + private function s151(): bool + { + if (!isset(self::T1490fe7f[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(151); + } + + return false;} + + $o1 = $this->p; + if (!$this->s152()) { + goto f1109;} + // s139 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b2 >= $this->f) { + $this->rec(3); + } + + goto e1111; + } + + $this->p++; + } + e1111: + if (($this->ids[$this->p] === 40)) { + if (!$this->s176()) { + goto n1112;} + n1112: + } elseif ($this->p > $this->f) { + $this->rec(176); + } + goto k1109; + f1109: + $this->p = $o1; + return false; + k1109: + + return true; + } + + private function s152(): bool + { + if (!isset(self::T1490fe7f[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(152); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + if (!$this->s146()) { + goto n1369;} + goto a1368; + n1369: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + // s153 + $o2 = $this->p; + if (!$this->s154()) { + goto f1371;} + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1373; + } + + $this->p++; + } + e1373: + if (!isset(self::Ta7068161[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(171); + } + + goto f1371;} + + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1375; + } + + $this->p++; + } + e1375: + if (!$this->s145()) { + goto f1371;} + goto k1371; + f1371: + $this->p = $o2; + goto n1370; + k1371: + goto a1368; + n1370: + // s172 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1377;} + } + goto k1377; + f1377: + $this->p = $o2; + goto n1376; + k1377: + goto a1368; + n1376: + // s160 + $o2 = $this->p; + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1379;} + } + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f1379;} + + $this->p++; + if (!($this->ids[$this->p] === 43)) { + if ($this->p >= $this->f) { + $this->rec(66); + } + + goto f1379;} + + $this->p++; + if (!$this->s163()) { + goto f1379;} + goto k1379; + f1379: + $this->p = $o2; + goto n1378; + k1379: + goto a1368; + n1378: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + // s153 + $o2 = $this->p; + if (!$this->s154()) { + goto f1381;} + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1383; + } + + $this->p++; + } + e1383: + if (!isset(self::Ta7068161[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(171); + } + + goto f1381;} + + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1385; + } + + $this->p++; + } + e1385: + if (!$this->s145()) { + goto f1381;} + goto k1381; + f1381: + $this->p = $o2; + goto n1380; + k1381: + goto a1368; + n1380: + // s172 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1387;} + } + goto k1387; + f1387: + $this->p = $o2; + goto n1386; + k1387: + goto a1368; + n1386: + break; + case 22: + case 23: + // s153 + $o2 = $this->p; + if (!$this->s154()) { + goto f1389;} + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1391; + } + + $this->p++; + } + e1391: + if (!isset(self::Ta7068161[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(171); + } + + goto f1389;} + + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1393; + } + + $this->p++; + } + e1393: + if (!$this->s145()) { + goto f1389;} + goto k1389; + f1389: + $this->p = $o2; + goto n1388; + k1389: + goto a1368; + n1388: + if (!$this->s155()) { + goto n1394;} + goto a1368; + n1394: + break; + case 38: + case 83: + // s148 + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1398; + } + + $this->p++; + } + e1398: + if (isset(self::T1490fe7f[$this->ids[$this->p]])) { + if (!$this->s151()) { + goto n1399;} + n1399: + } elseif ($this->p > $this->f) { + $this->rec(151); + } + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f1396;} + + $this->p++; + goto k1396; + f1396: + $this->p = $o2; + goto n1395; + k1396: + goto a1368; + n1395: + break; + case 19: + $this->p++; + goto a1368; + break; + case 20: + // s153 + $o2 = $this->p; + if (!$this->s154()) { + goto f1401;} + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1403; + } + + $this->p++; + } + e1403: + if (!isset(self::Ta7068161[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(171); + } + + goto f1401;} + + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1405; + } + + $this->p++; + } + e1405: + if (!$this->s145()) { + goto f1401;} + goto k1401; + f1401: + $this->p = $o2; + goto n1400; + k1401: + goto a1368; + n1400: + $this->p++; + goto a1368; + break; + case 21: + // s153 + $o2 = $this->p; + if (!$this->s154()) { + goto f1407;} + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1409; + } + + $this->p++; + } + e1409: + if (!isset(self::Ta7068161[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(171); + } + + goto f1407;} + + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1411; + } + + $this->p++; + } + e1411: + if (!$this->s145()) { + goto f1407;} + goto k1407; + f1407: + $this->p = $o2; + goto n1406; + k1407: + goto a1368; + n1406: + break; + } + + if ($this->p > $this->f) { + $this->rec(152); + } + + goto f1367; + a1368: + goto k1367; + f1367: + $this->p = $o1; + return false; + k1367: + + return true; + } + + private function s154(): bool + { + if (!isset(self::T7726a0df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(154); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + // s160 + $o2 = $this->p; + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if (isset(self::T00b73ddb[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1620;} + } + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f1620;} + + $this->p++; + if (!($this->ids[$this->p] === 43)) { + if ($this->p >= $this->f) { + $this->rec(66); + } + + goto f1620;} + + $this->p++; + if (!$this->s163()) { + goto f1620;} + goto k1620; + f1620: + $this->p = $o2; + goto n1619; + k1620: + goto a1618; + n1619: + // s169 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1622;} + } + goto k1622; + f1622: + $this->p = $o2; + goto n1621; + k1622: + goto a1618; + n1621: + break; + case 7: + case 15: + case 16: + case 17: + case 18: + // s169 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1624;} + } + goto k1624; + f1624: + $this->p = $o2; + goto n1623; + k1624: + goto a1618; + n1623: + break; + case 22: + case 23: + if (!$this->s155()) { + goto n1625;} + goto a1618; + n1625: + break; + case 20: + $this->p++; + goto a1618; + break; + case 21: + $this->p++; + goto a1618; + break; + } + + if ($this->p > $this->f) { + $this->rec(154); + } + + goto f1617; + a1618: + goto k1617; + f1617: + $this->p = $o1; + return false; + k1617: + + return true; + } + + private function s155(): bool + { + if (!isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(155); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 22: + // s156 + $o2 = $this->p; + $this->p++; + if (isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + // s158 + if (!isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(158); + } + + goto n1106;} + + $o3 = $this->p; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T7dfbf2bf[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(159); + } + + goto e1108; + } + + $this->p++; + + $k3++; + } + e1108: + + if ($k3 < 1) { + goto f1107; + } + goto k1107; + f1107: + $this->p = $o3; + goto n1106; + k1107: + n1106: + } elseif ($this->p > $this->f) { + $this->rec(158); + } + goto a1103; + n1104: + break; + case 23: + $this->p++; + goto a1103; + break; + } + + if ($this->p > $this->f) { + $this->rec(155); + } + + goto f1102; + a1103: + goto k1102; + f1102: + $this->p = $o1; + return false; + k1102: + + return true; + } + + private function s163(): bool + { + if (!isset(self::Td08f0236[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(163); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // s166 + $o2 = $this->p; + $this->p++; + if (isset(self::T4d756b3a[$this->ids[$this->p]])) { + // s168 + if (!isset(self::T4d756b3a[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(168); + } + + goto n482;} + + $o3 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 50: + // s164 + $o4 = $this->p; + $this->p++; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + if (!$this->s166()) { + goto n487;} + n487: + } elseif ($this->p > $this->f) { + $this->rec(166); + } + goto a484; + n485: + break; + case 85: + $this->p++; + goto a484; + break; + } + + if ($this->p > $this->f) { + $this->rec(168); + } + + goto f483; + a484: + goto k483; + f483: + $this->p = $o3; + goto n482; + k483: + n482: + } elseif ($this->p > $this->f) { + $this->rec(168); + } + goto a479; + n480: + break; + case 50: + if (!$this->s164()) { + goto n488;} + goto a479; + n488: + break; + case 85: + $this->p++; + goto a479; + break; + } + + if ($this->p > $this->f) { + $this->rec(163); + } + + goto f478; + a479: + goto k478; + f478: + $this->p = $o1; + return false; + k478: + + return true; + } + + private function s164(): bool + { + if (!($this->ids[$this->p] === 50)) { + if ($this->p > $this->f) { + $this->rec(164); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + // s166 + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(166); + } + + goto n770;} + + $o2 = $this->p; + $this->p++; + if (isset(self::T4d756b3a[$this->ids[$this->p]])) { + // s168 + if (!isset(self::T4d756b3a[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(168); + } + + goto n772;} + + $o3 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 50: + if (!$this->s164()) { + goto n775;} + goto a774; + n775: + break; + case 85: + $this->p++; + goto a774; + break; + } + + if ($this->p > $this->f) { + $this->rec(168); + } + + goto f773; + a774: + goto k773; + f773: + $this->p = $o3; + goto n772; + k773: + n772: + } elseif ($this->p > $this->f) { + $this->rec(168); + } + n770: + } elseif ($this->p > $this->f) { + $this->rec(166); + } + + return true; + } + + private function s166(): bool + { + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(166); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (isset(self::T4d756b3a[$this->ids[$this->p]])) { + // s168 + if (!isset(self::T4d756b3a[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(168); + } + + goto n763;} + + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 50: + // s164 + $o3 = $this->p; + $this->p++; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + if (!$this->s166()) { + goto n768;} + n768: + } elseif ($this->p > $this->f) { + $this->rec(166); + } + goto a765; + n766: + break; + case 85: + $this->p++; + goto a765; + break; + } + + if ($this->p > $this->f) { + $this->rec(168); + } + + goto f764; + a765: + goto k764; + f764: + $this->p = $o2; + goto n763; + k764: + n763: + } elseif ($this->p > $this->f) { + $this->rec(168); + } + + return true; + } + + private function s169(): bool + { + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(169); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f664;} + } + goto k664; + f664: + $this->p = $o1; + return false; + k664: + + return true; + } + + private function s176(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(176); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(177); + } + + goto e1413; + } + + // s177 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(177); + } + + goto e1413;} + + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1416; + } + + $this->p++; + } + e1416: + if (!$this->s178()) { + goto f1414;} + goto k1414; + f1414: + $this->p = $o2; + goto e1413; + k1414: + if ($this->p === $b1) { + $k1 = 1; + goto e1413; + } + + $k1++; + } + e1413: + + if ($k1 < 1) { + goto f1412; + } + goto k1412; + f1412: + $this->p = $o1; + return false; + k1412: + + return true; + } + + private function s178(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s180 + if (!isset(self::T1490fe7f[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(180); + } + + goto n1628;} + + $o2 = $this->p; + if (!$this->s152()) { + goto f1629;} + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1631; + } + + $this->p++; + } + e1631: + goto k1629; + f1629: + $this->p = $o2; + goto n1628; + k1629: + goto a1627; + n1628: + break; + case 0: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 80: + case 81: + case 82: + case 84: + case 85: + case 86: + case -1: + break; + case 39: + if (!($this->ids[$this->p] === 39)) { + if ($this->p > $this->f) { + $this->rec(62); + } + + goto n1632;} + goto a1627; + n1632: + break; + } + + if ($this->p > $this->f) { + $this->rec(178); + } + + goto f1626; + a1627: + goto k1626; + f1626: + $this->p = $o1; + return false; + k1626: + + return true; + } + + private function s182(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(182); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(183); + } + + goto e844; + } + + // s183 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(183); + } + + goto e844;} + + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e847; + } + + $this->p++; + } + e847: + if (!$this->s184()) { + goto f845;} + goto k845; + f845: + $this->p = $o2; + goto e844; + k845: + if ($this->p === $b1) { + $k1 = 1; + goto e844; + } + + $k1++; + } + e844: + + if ($k1 < 1) { + goto f843; + } + goto k843; + f843: + $this->p = $o1; + return false; + k843: + + return true; + } + + private function s184(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s186 + if (!isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(186); + } + + goto n1115;} + + $o2 = $this->p; + if (!$this->s142()) { + goto f1116;} + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e1118; + } + + $this->p++; + } + e1118: + goto k1116; + f1116: + $this->p = $o2; + goto n1115; + k1116: + goto a1114; + n1115: + break; + case 0: + case 21: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 34: + case 35: + case 36: + case 37: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 80: + case 81: + case 82: + case 84: + case 85: + case 86: + case -1: + break; + case 33: + if (!($this->ids[$this->p] === 33)) { + if ($this->p > $this->f) { + $this->rec(53); + } + + goto n1119;} + goto a1114; + n1119: + break; + } + + if ($this->p > $this->f) { + $this->rec(184); + } + + goto f1113; + a1114: + goto k1113; + f1113: + $this->p = $o1; + return false; + k1113: + + return true; + } + + private function s187(): bool + { + if (!isset(self::Tf6aec6a4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(187); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s138 + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(138); + } + + goto f267;} + + $o2 = $this->p; + $this->p++; + // s139 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!($this->ids[$this->p] === 80)) { + if ($b3 >= $this->f) { + $this->rec(3); + } + + goto e270; + } + + $this->p++; + } + e270: + if (isset(self::T1e2ed78c[$this->ids[$this->p]])) { + if (!$this->s141()) { + goto n271;} + n271: + } elseif ($this->p > $this->f) { + $this->rec(141); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f268;} + + $this->p++; + goto k268; + f268: + $this->p = $o2; + goto f267; + k268: + // s19 + $o2 = $this->p; + // s20 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T0979f8dc[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(21); + } + + goto e274; + } + + $this->p++; + } + e274: + if (!$this->s74()) { + goto f272;} + goto k272; + f272: + $this->p = $o2; + goto f267; + k272: + goto k267; + f267: + $this->p = $o1; + return false; + k267: + + return true; + } + + private function s189(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s455 + $o2 = $this->p; + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f46;} + } + // s457 + $o3 = $this->p; + if (!$this->s125()) { + goto f47;} + goto k47; + f47: + $this->p = $o3; + goto f46; + k47: + goto k46; + f46: + $this->p = $o2; + goto n45; + k46: + goto a44; + n45: + break; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + if (!$this->s190()) { + goto n48;} + goto a44; + n48: + if (!$this->s454()) { + goto n49;} + goto a44; + n49: + // s455 + $o2 = $this->p; + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f51;} + } + // s457 + $o3 = $this->p; + if (!$this->s125()) { + goto f52;} + goto k52; + f52: + $this->p = $o3; + goto f51; + k52: + goto k51; + f51: + $this->p = $o2; + goto n50; + k51: + goto a44; + n50: + break; + case 76: + case 77: + case 78: + case 79: + if (!$this->s454()) { + goto n53;} + goto a44; + n53: + // s455 + $o2 = $this->p; + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if (isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f55;} + } + // s457 + $o3 = $this->p; + if (!$this->s125()) { + goto f56;} + goto k56; + f56: + $this->p = $o3; + goto f55; + k56: + goto k55; + f55: + $this->p = $o2; + goto n54; + k55: + goto a44; + n54: + break; + } + + if ($this->p > $this->f) { + $this->rec(189); + } + + goto f43; + a44: + goto k43; + f43: + $this->p = $o1; + return false; + k43: + + return true; + } + + private function s190(): bool + { + if (!isset(self::Tce49e0fc[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(190); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 51: + // s402 + $o2 = $this->p; + $this->p++; + // s403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f127;} + + $o3 = $this->p; + $this->p++; + if (!$this->s125()) { + goto f128;} + goto k128; + f128: + $this->p = $o3; + goto f127; + k128: + goto k127; + f127: + $this->p = $o2; + goto n126; + k127: + goto a125; + n126: + break; + case 52: + // s405 + $o2 = $this->p; + $this->p++; + // s403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f130;} + + $o3 = $this->p; + $this->p++; + if (!$this->s125()) { + goto f131;} + goto k131; + f131: + $this->p = $o3; + goto f130; + k131: + goto k130; + f130: + $this->p = $o2; + goto n129; + k130: + goto a125; + n129: + break; + case 53: + // s406 + $o2 = $this->p; + $this->p++; + // s403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f133;} + + $o3 = $this->p; + $this->p++; + if (!$this->s125()) { + goto f134;} + goto k134; + f134: + $this->p = $o3; + goto f133; + k134: + goto k133; + f133: + $this->p = $o2; + goto n132; + k133: + goto a125; + n132: + break; + case 54: + // s404 + $o2 = $this->p; + $this->p++; + // s403 + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(403); + } + + goto f136;} + + $o3 = $this->p; + $this->p++; + if (!$this->s125()) { + goto f137;} + goto k137; + f137: + $this->p = $o3; + goto f136; + k137: + goto k136; + f136: + $this->p = $o2; + goto n135; + k136: + goto a125; + n135: + break; + case 55: + // s401 + $o2 = $this->p; + $this->p++; + // s399 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(399); + } + + goto f139;} + + $o3 = $this->p; + if (!$this->s199()) { + goto f140;} + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f140;} + + $this->p++; + if (!$this->s125()) { + goto f140;} + goto k140; + f140: + $this->p = $o3; + goto f139; + k140: + goto k139; + f139: + $this->p = $o2; + goto n138; + k139: + goto a125; + n138: + break; + case 56: + // s395 + $o2 = $this->p; + $this->p++; + if (!$this->s391()) { + goto f142;} + goto k142; + f142: + $this->p = $o2; + goto n141; + k142: + goto a125; + n141: + break; + case 57: + // s394 + $o2 = $this->p; + $this->p++; + if (!$this->s391()) { + goto f144;} + goto k144; + f144: + $this->p = $o2; + goto n143; + k144: + goto a125; + n143: + break; + case 58: + if (!$this->s443()) { + goto n145;} + goto a125; + n145: + break; + case 59: + // s446 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 31)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(52); + } + if (($this->ids[$this->p] === 46)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + if (!$this->s199()) { + goto f147;} + if (!isset(self::T29c7f960[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(448); + } + + goto f147;} + + $this->p++; + if (!$this->s449()) { + goto f147;} + if (!$this->s125()) { + goto f147;} + goto k147; + f147: + $this->p = $o2; + goto n146; + k147: + goto a125; + n146: + break; + case 60: + // s397 + $o2 = $this->p; + $this->p++; + if (!$this->s391()) { + goto f149;} + goto k149; + f149: + $this->p = $o2; + goto n148; + k149: + goto a125; + n148: + break; + case 61: + // s396 + $o2 = $this->p; + $this->p++; + if (!$this->s391()) { + goto f151;} + goto k151; + f151: + $this->p = $o2; + goto n150; + k151: + goto a125; + n150: + break; + case 62: + if (!$this->s436()) { + goto n152;} + goto a125; + n152: + break; + case 63: + // s398 + $o2 = $this->p; + $this->p++; + // s399 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(399); + } + + goto f154;} + + $o3 = $this->p; + if (!$this->s199()) { + goto f155;} + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f155;} + + $this->p++; + if (!$this->s125()) { + goto f155;} + goto k155; + f155: + $this->p = $o3; + goto f154; + k155: + goto k154; + f154: + $this->p = $o2; + goto n153; + k154: + goto a125; + n153: + break; + case 64: + // s439 + $o2 = $this->p; + $this->p++; + if (!$this->s438()) { + goto f157;} + goto k157; + f157: + $this->p = $o2; + goto n156; + k157: + goto a125; + n156: + break; + case 65: + // s407 + $o2 = $this->p; + $this->p++; + if (!$this->s125()) { + goto f159;} + goto k159; + f159: + $this->p = $o2; + goto n158; + k159: + goto a125; + n158: + break; + case 66: + // s441 + $o2 = $this->p; + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f161;} + + $this->p++; + if (($this->ids[$this->p] === 46)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + if (!$this->s199()) { + goto f161;} + if (!isset(self::T53b29bff[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(77); + } + + goto f161;} + goto k161; + f161: + $this->p = $o2; + goto n160; + k161: + goto a125; + n160: + // s442 + $o2 = $this->p; + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f163;} + + $this->p++; + if (($this->ids[$this->p] === 46)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + if (!$this->s125()) { + goto f163;} + goto k163; + f163: + $this->p = $o2; + goto n162; + k163: + goto a125; + n162: + break; + case 67: + // s400 + $o2 = $this->p; + $this->p++; + // s399 + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(399); + } + + goto f165;} + + $o3 = $this->p; + if (!$this->s199()) { + goto f166;} + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f166;} + + $this->p++; + if (!$this->s125()) { + goto f166;} + goto k166; + f166: + $this->p = $o3; + goto f165; + k166: + goto k165; + f165: + $this->p = $o2; + goto n164; + k165: + goto a125; + n164: + break; + case 68: + // s437 + $o2 = $this->p; + $this->p++; + if (!$this->s438()) { + goto f168;} + goto k168; + f168: + $this->p = $o2; + goto n167; + k168: + goto a125; + n167: + break; + case 69: + // s408 + $o2 = $this->p; + $this->p++; + if (!$this->s409()) { + goto f170;} + goto k170; + f170: + $this->p = $o2; + goto n169; + k170: + goto a125; + n169: + break; + case 70: + // s390 + $o2 = $this->p; + $this->p++; + if (!$this->s391()) { + goto f172;} + goto k172; + f172: + $this->p = $o2; + goto n171; + k172: + goto a125; + n171: + break; + case 71: + // s392 + $o2 = $this->p; + $this->p++; + if (!$this->s391()) { + goto f174;} + goto k174; + f174: + $this->p = $o2; + goto n173; + k174: + goto a125; + n173: + break; + case 72: + // s191 + $o2 = $this->p; + $this->p++; + if (!$this->s192()) { + goto f176;} + goto k176; + f176: + $this->p = $o2; + goto n175; + k176: + goto a125; + n175: + break; + case 73: + // s393 + $o2 = $this->p; + $this->p++; + if (!$this->s391()) { + goto f178;} + goto k178; + f178: + $this->p = $o2; + goto n177; + k178: + goto a125; + n177: + break; + case 74: + // s440 + $o2 = $this->p; + $this->p++; + if (!$this->s438()) { + goto f180;} + goto k180; + f180: + $this->p = $o2; + goto n179; + k180: + goto a125; + n179: + break; + case 75: + // s384 + $o2 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f182;} + if (!$this->s385()) { + goto f182;} + goto k182; + f182: + $this->p = $o2; + goto n181; + k182: + goto a125; + n181: + break; + } + + if ($this->p > $this->f) { + $this->rec(190); + } + + goto f124; + a125: + goto k124; + f124: + $this->p = $o1; + return false; + k124: + + return true; + } + + private function s192(): bool + { + if (!isset(self::T3bf4df75[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(192); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + // s198 + $o2 = $this->p; + if (!$this->s199()) { + goto f375;} + if (($this->ids[$this->p] === 27)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f375;} + + $this->p++; + if (!$this->s125()) { + goto f375;} + goto k375; + f375: + $this->p = $o2; + goto n374; + k375: + goto a373; + n374: + break; + case 26: + case 27: + case 42: + // s193 + $o2 = $this->p; + if (!isset(self::T553dc07b[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(195); + } + + goto f377;} + if (($this->ids[$this->p] === 27)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f377;} + + $this->p++; + if (!$this->s125()) { + goto f377;} + goto k377; + f377: + $this->p = $o2; + goto n376; + k377: + goto a373; + n376: + break; + } + + if ($this->p > $this->f) { + $this->rec(192); + } + + goto f372; + a373: + goto k372; + f372: + $this->p = $o1; + return false; + k372: + + return true; + } + + private function s199(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(199); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 32: + case 82: + // s367 + $o2 = $this->p; + if (!$this->s201()) { + goto f192;} + if (!$this->s368()) { + goto f192;} + goto k192; + f192: + $this->p = $o2; + goto n191; + k192: + goto a190; + n191: + break; + case 30: + // s200 + $o2 = $this->p; + $this->p++; + if (!$this->s201()) { + goto f194;} + goto k194; + f194: + $this->p = $o2; + goto n193; + k194: + goto a190; + n193: + break; + } + + if ($this->p > $this->f) { + $this->rec(199); + } + + goto f189; + a190: + goto k189; + f189: + $this->p = $o1; + return false; + k189: + + return true; + } + + private function s201(): bool + { + if (!isset(self::T977f027a[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(201); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 5: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // s366 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f426;} + } + if (!$this->s281()) { + goto f426;} + goto k426; + f426: + $this->p = $o2; + goto n425; + k426: + goto a424; + n425: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f428;} + } + if (!$this->s335()) { + goto f428;} + goto k428; + f428: + $this->p = $o2; + goto n427; + k428: + goto a424; + n427: + break; + case 19: + case 20: + case 21: + case 22: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f431;} + } + if (!$this->s335()) { + goto f431;} + goto k431; + f431: + $this->p = $o2; + goto n430; + k431: + goto a424; + n430: + break; + case 3: + case 4: + case 8: + if (!$this->s255()) { + goto n433;} + goto a424; + n433: + // s278 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f435;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f435;} + } + if (!$this->s281()) { + goto f435;} + goto k435; + f435: + $this->p = $o2; + goto n434; + k435: + goto a424; + n434: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f437;} + } + if (!$this->s335()) { + goto f437;} + goto k437; + f437: + $this->p = $o2; + goto n436; + k437: + goto a424; + n436: + break; + case 32: + case 82: + if (!$this->s202()) { + goto n439;} + goto a424; + n439: + break; + case 6: + if (!$this->s267()) { + goto n440;} + goto a424; + n440: + // s278 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f442;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f442;} + } + if (!$this->s281()) { + goto f442;} + goto k442; + f442: + $this->p = $o2; + goto n441; + k442: + goto a424; + n441: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f444;} + } + if (!$this->s335()) { + goto f444;} + goto k444; + f444: + $this->p = $o2; + goto n443; + k444: + goto a424; + n443: + break; + case 7: + if (!$this->s230()) { + goto n446;} + goto a424; + n446: + // s278 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f448;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f448;} + } + if (!$this->s281()) { + goto f448;} + goto k448; + f448: + $this->p = $o2; + goto n447; + k448: + goto a424; + n447: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f450;} + } + if (!$this->s335()) { + goto f450;} + goto k450; + f450: + $this->p = $o2; + goto n449; + k450: + goto a424; + n449: + break; + case 25: + // s229 + $o2 = $this->p; + $this->p++; + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n454;} + + $o3 = $this->p; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(224); + } + + goto e456; + } + + if (!$this->s224()) { + goto e456;} + if ($this->p === $b3) { + $k3 = 1; + goto e456; + } + + $k3++; + } + e456: + + if ($k3 < 1) { + goto f455; + } + goto k455; + f455: + $this->p = $o3; + goto n454; + k455: + n454: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto a424; + n452: + break; + } + + if ($this->p > $this->f) { + $this->rec(201); + } + + goto f423; + a424: + goto k423; + f423: + $this->p = $o1; + return false; + k423: + + return true; + } + + private function s202(): bool + { + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(202); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e723; + } + + $this->p++; + } + e723: + if (!$this->s205()) { + goto f721;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e725; + } + + $this->p++; + } + e725: + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f721;} + + $this->p++; + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n726;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e728; + } + + if (!$this->s224()) { + goto e728;} + if ($this->p === $b2) { + $k2 = 1; + goto e728; + } + + $k2++; + } + e728: + + if ($k2 < 1) { + goto f727; + } + goto k727; + f727: + $this->p = $o2; + goto n726; + k727: + n726: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k721; + f721: + $this->p = $o1; + return false; + k721: + + return true; + } + + private function s205(): bool + { + if (!isset(self::Tcd64b9c0[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(205); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 32: + case 82: + // s208 + $o2 = $this->p; + if (!$this->s201()) { + goto f1014;} + if (!$this->s209()) { + goto f1014;} + goto k1014; + f1014: + $this->p = $o2; + goto n1013; + k1014: + goto a1012; + n1013: + break; + case 26: + if (!$this->s206()) { + goto n1015;} + goto a1012; + n1015: + break; + case 30: + // s200 + $o2 = $this->p; + $this->p++; + if (!$this->s201()) { + goto f1017;} + goto k1017; + f1017: + $this->p = $o2; + goto n1016; + k1017: + goto a1012; + n1016: + break; + } + + if ($this->p > $this->f) { + $this->rec(205); + } + + goto f1011; + a1012: + goto k1011; + f1011: + $this->p = $o1; + return false; + k1011: + + return true; + } + + private function s206(): bool + { + if (!($this->ids[$this->p] === 26)) { + if ($this->p > $this->f) { + $this->rec(206); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!($this->ids[$this->p] === 12)) { + if ($this->p >= $this->f) { + $this->rec(23); + } + + goto f1303;} + + $this->p++; + if (($this->ids[$this->p] === 11)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(24); + } + if (!$this->s199()) { + goto f1303;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1305; + } + + $this->p++; + } + e1305: + if (!($this->ids[$this->p] === 30)) { + if ($this->p >= $this->f) { + $this->rec(51); + } + + goto f1303;} + + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1307; + } + + $this->p++; + } + e1307: + if (!$this->s199()) { + goto f1303;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1309; + } + + $this->p++; + } + e1309: + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1303;} + + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1311; + } + + $this->p++; + } + e1311: + if (!$this->s205()) { + goto f1303;} + goto k1303; + f1303: + $this->p = $o1; + return false; + k1303: + + return true; + } + + private function s209(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (!$this->s211()) { + goto n1300;} + goto a1299; + n1300: + break; + case 12: + if (!$this->s210()) { + goto n1301;} + goto a1299; + n1301: + if (!$this->s211()) { + goto n1302;} + goto a1299; + n1302: + break; + } + + if ($this->p > $this->f) { + $this->rec(209); + } + + goto f1298; + a1299: + goto k1298; + f1298: + $this->p = $o1; + return false; + k1298: + + return true; + } + + private function s210(): bool + { + if (!($this->ids[$this->p] === 12)) { + if ($this->p > $this->f) { + $this->rec(210); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 11)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(24); + } + if (!$this->s199()) { + goto f1576;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1578; + } + + $this->p++; + } + e1578: + if (!($this->ids[$this->p] === 30)) { + if ($this->p >= $this->f) { + $this->rec(51); + } + + goto f1576;} + + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1580; + } + + $this->p++; + } + e1580: + if (!$this->s199()) { + goto f1576;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1582; + } + + $this->p++; + } + e1582: + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1576;} + + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1584; + } + + $this->p++; + } + e1584: + if (!$this->s205()) { + goto f1576;} + goto k1576; + f1576: + $this->p = $o1; + return false; + k1576: + + return true; + } + + private function s211(): bool + { + $o1 = $this->p; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1574; + } + + $this->p++; + } + e1574: + if (isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if (!$this->s213()) { + goto n1575;} + n1575: + } elseif ($this->p > $this->f) { + $this->rec(213); + } + + return true; + } + + private function s213(): bool + { + if (!isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(213); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 28: + // s214 + $o2 = $this->p; + if (!$this->s215()) { + goto f1703;} + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1703;} + } + goto k1703; + f1703: + $this->p = $o2; + goto n1702; + k1703: + goto a1701; + n1702: + break; + case 29: + // s218 + $o2 = $this->p; + if (!$this->s219()) { + goto f1705;} + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f1705;} + } + goto k1705; + f1705: + $this->p = $o2; + goto n1704; + k1705: + goto a1701; + n1704: + break; + } + + if ($this->p > $this->f) { + $this->rec(213); + } + + goto f1700; + a1701: + goto k1700; + f1700: + $this->p = $o1; + return false; + k1700: + + return true; + } + + private function s215(): bool + { + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(215); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 28)) { + if ($b1 > $this->f) { + $this->rec(216); + } + + goto e1748; + } + + // s216 + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(216); + } + + goto e1748;} + + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1751; + } + + $this->p++; + } + e1751: + if (!$this->s201()) { + goto f1749;} + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1753; + } + + $this->p++; + } + e1753: + goto k1749; + f1749: + $this->p = $o2; + goto e1748; + k1749: + if ($this->p === $b1) { + $k1 = 1; + goto e1748; + } + + $k1++; + } + e1748: + + if ($k1 < 1) { + goto f1747; + } + goto k1747; + f1747: + $this->p = $o1; + return false; + k1747: + + return true; + } + + private function s219(): bool + { + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(219); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 29)) { + if ($b1 > $this->f) { + $this->rec(220); + } + + goto e1755; + } + + // s220 + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(220); + } + + goto e1755;} + + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1758; + } + + $this->p++; + } + e1758: + if (!$this->s201()) { + goto f1756;} + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1760; + } + + $this->p++; + } + e1760: + goto k1756; + f1756: + $this->p = $o2; + goto e1755; + k1756: + if ($this->p === $b1) { + $k1 = 1; + goto e1755; + } + + $k1++; + } + e1755: + + if ($k1 < 1) { + goto f1754; + } + goto k1754; + f1754: + $this->p = $o1; + return false; + k1754: + + return true; + } + + private function s224(): bool + { + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(224); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 36: + // s225 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 37)) { + if (($this->ids[$this->p] === 37)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f744;} + } + if (!$this->s199()) { + goto f744;} + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f744;} + + $this->p++; + goto k744; + f744: + $this->p = $o2; + goto n743; + k744: + goto a742; + n743: + // s227 + $o2 = $this->p; + $this->p++; + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f746;} + + $this->p++; + goto k746; + f746: + $this->p = $o2; + goto n745; + k746: + goto a742; + n745: + break; + case 84: + // s227 + $o2 = $this->p; + $this->p++; + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f748;} + + $this->p++; + goto k748; + f748: + $this->p = $o2; + goto n747; + k748: + goto a742; + n747: + break; + } + + if ($this->p > $this->f) { + $this->rec(224); + } + + goto f741; + a742: + goto k741; + f741: + $this->p = $o1; + return false; + k741: + + return true; + } + + private function s230(): bool + { + if (!($this->ids[$this->p] === 7)) { + if ($this->p > $this->f) { + $this->rec(230); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f737;} + } + if (!$this->s231()) { + goto f737;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n738;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e740; + } + + if (!$this->s224()) { + goto e740;} + if ($this->p === $b2) { + $k2 = 1; + goto e740; + } + + $k2++; + } + e740: + + if ($k2 < 1) { + goto f739; + } + goto k739; + f739: + $this->p = $o2; + goto n738; + k739: + n738: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k737; + f737: + $this->p = $o1; + return false; + k737: + + return true; + } + + private function s231(): bool + { + if (!($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->rec(231); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1025; + } + + $this->p++; + } + e1025: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + if (!$this->s233()) { + goto n1026;} + n1026: + } elseif ($this->p > $this->f) { + $this->rec(233); + } + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1028; + } + + $this->p++; + } + e1028: + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f1023;} + + $this->p++; + goto k1023; + f1023: + $this->p = $o1; + return false; + k1023: + + return true; + } + + private function s233(): bool + { + if (!isset(self::T50fd39f8[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(233); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + if (!$this->s243()) { + goto n1321;} + goto a1320; + n1321: + break; + case 42: + // s234 + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1325; + } + + $this->p++; + } + e1325: + if (!$this->s235()) { + goto f1323;} + if (($this->ids[$this->p] === 40)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(63); + } + goto k1323; + f1323: + $this->p = $o2; + goto n1322; + k1323: + goto a1320; + n1322: + break; + } + + if ($this->p > $this->f) { + $this->rec(233); + } + + goto f1319; + a1320: + goto k1319; + f1319: + $this->p = $o1; + return false; + k1319: + + return true; + } + + private function s235(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1599;} + goto a1598; + n1599: + break; + case 34: + case 86: + // s236 + $o2 = $this->p; + if (!$this->s237()) { + goto f1601;} + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1603; + } + + $this->p++; + } + e1603: + goto k1601; + f1601: + $this->p = $o2; + goto n1600; + k1601: + goto a1598; + n1600: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1604;} + goto a1598; + n1604: + break; + } + + if ($this->p > $this->f) { + $this->rec(235); + } + + goto f1597; + a1598: + goto k1597; + f1597: + $this->p = $o1; + return false; + k1597: + + return true; + } + + private function s237(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(237); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1712; + } + + $this->p++; + } + e1712: + if (!$this->s199()) { + goto f1710;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1714; + } + + $this->p++; + } + e1714: + if (($this->ids[$this->p] === 40)) { + // s240 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(240); + } + + goto n1715;} + + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1718; + } + + $this->p++; + } + e1718: + if (!$this->s199()) { + goto f1716;} + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1720; + } + + $this->p++; + } + e1720: + goto k1716; + f1716: + $this->p = $o2; + goto n1715; + k1716: + n1715: + } elseif ($this->p > $this->f) { + $this->rec(240); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1710;} + + $this->p++; + goto k1710; + f1710: + $this->p = $o1; + return false; + k1710: + + return true; + } + + private function s243(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(243); + } + + return false;} + + $o1 = $this->p; + if (!$this->s244()) { + goto f1593;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1595; + } + + $this->p++; + } + e1595: + if (($this->ids[$this->p] === 40)) { + if (!$this->s252()) { + goto n1596;} + n1596: + } elseif ($this->p > $this->f) { + $this->rec(252); + } + goto k1593; + f1593: + $this->p = $o1; + return false; + k1593: + + return true; + } + + private function s244(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(244); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 20: + case 21: + case 22: + case 24: + // s245 + $o2 = $this->p; + if (!$this->s246()) { + goto f1685;} + if (($this->ids[$this->p] === 30)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(51); + } + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1685;} + + $this->p++; + if (!$this->s199()) { + goto f1685;} + goto k1685; + f1685: + $this->p = $o2; + goto n1684; + k1685: + goto a1683; + n1684: + if (!$this->s199()) { + goto n1686;} + goto a1683; + n1686: + break; + case 19: + case 25: + case 30: + case 32: + case 82: + if (!$this->s199()) { + goto n1687;} + goto a1683; + n1687: + break; + } + + if ($this->p > $this->f) { + $this->rec(244); + } + + goto f1682; + a1683: + goto k1682; + f1682: + $this->p = $o1; + return false; + k1682: + + return true; + } + + private function s246(): bool + { + if (!isset(self::Tce797685[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(246); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // s247 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + // s249 + if (!($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->rec(249); + } + + goto n1745;} + + $o3 = $this->p; + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f1746;} + + $this->p++; + goto k1746; + f1746: + $this->p = $o3; + goto n1745; + k1746: + n1745: + } elseif ($this->p > $this->f) { + $this->rec(249); + } + goto a1742; + n1743: + break; + case 20: + $this->p++; + goto a1742; + break; + case 21: + $this->p++; + goto a1742; + break; + case 22: + $this->p++; + goto a1742; + break; + } + + if ($this->p > $this->f) { + $this->rec(246); + } + + goto f1741; + a1742: + goto k1741; + f1741: + $this->p = $o1; + return false; + k1741: + + return true; + } + + private function s252(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(252); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 41)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(254); + } + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1708; + } + + $this->p++; + } + e1708: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + if (!$this->s233()) { + goto n1709;} + n1709: + } elseif ($this->p > $this->f) { + $this->rec(233); + } + + return true; + } + + private function s255(): bool + { + if (!isset(self::Ta8d79561[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(255); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f717;} + } + if (!$this->s257()) { + goto f717;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n718;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e720; + } + + if (!$this->s224()) { + goto e720;} + if ($this->p === $b2) { + $k2 = 1; + goto e720; + } + + $k2++; + } + e720: + + if ($k2 < 1) { + goto f719; + } + goto k719; + f719: + $this->p = $o2; + goto n718; + k719: + n718: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k717; + f717: + $this->p = $o1; + return false; + k717: + + return true; + } + + private function s257(): bool + { + if (!($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->rec(257); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1007; + } + + $this->p++; + } + e1007: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + if (!$this->s259()) { + goto n1008;} + n1008: + } elseif ($this->p > $this->f) { + $this->rec(259); + } + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1010; + } + + $this->p++; + } + e1010: + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f1005;} + + $this->p++; + goto k1005; + f1005: + $this->p = $o1; + return false; + k1005: + + return true; + } + + private function s259(): bool + { + if (!isset(self::T50fd39f8[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(259); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + if (!$this->s264()) { + goto n1293;} + goto a1292; + n1293: + break; + case 42: + // s260 + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1297; + } + + $this->p++; + } + e1297: + if (!$this->s261()) { + goto f1295;} + if (($this->ids[$this->p] === 40)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(63); + } + goto k1295; + f1295: + $this->p = $o2; + goto n1294; + k1295: + goto a1292; + n1294: + break; + } + + if ($this->p > $this->f) { + $this->rec(259); + } + + goto f1291; + a1292: + goto k1291; + f1291: + $this->p = $o1; + return false; + k1291: + + return true; + } + + private function s261(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1569;} + goto a1568; + n1569: + break; + case 34: + case 86: + if (!$this->s262()) { + goto n1570;} + goto a1568; + n1570: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1571;} + goto a1568; + n1571: + break; + } + + if ($this->p > $this->f) { + $this->rec(261); + } + + goto f1567; + a1568: + goto k1567; + f1567: + $this->p = $o1; + return false; + k1567: + + return true; + } + + private function s262(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(262); + } + + return false;} + + $o1 = $this->p; + // s263 + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1695; + } + + $this->p++; + } + e1695: + if (!$this->s199()) { + goto f1693;} + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1697; + } + + $this->p++; + } + e1697: + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1693;} + + $this->p++; + goto k1693; + f1693: + $this->p = $o2; + goto f1692; + k1693: + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1699; + } + + $this->p++; + } + e1699: + goto k1692; + f1692: + $this->p = $o1; + return false; + k1692: + + return true; + } + + private function s264(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(264); + } + + return false;} + + $o1 = $this->p; + if (!$this->s244()) { + goto f1563;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1565; + } + + $this->p++; + } + e1565: + if (($this->ids[$this->p] === 40)) { + if (!$this->s266()) { + goto n1566;} + n1566: + } elseif ($this->p > $this->f) { + $this->rec(266); + } + goto k1563; + f1563: + $this->p = $o1; + return false; + k1563: + + return true; + } + + private function s266(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(266); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 41)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(254); + } + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1690; + } + + $this->p++; + } + e1690: + if (isset(self::T50fd39f8[$this->ids[$this->p]])) { + if (!$this->s259()) { + goto n1691;} + n1691: + } elseif ($this->p > $this->f) { + $this->rec(259); + } + + return true; + } + + private function s267(): bool + { + if (!($this->ids[$this->p] === 6)) { + if ($this->p > $this->f) { + $this->rec(267); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f729;} + } + // s268 + if (!($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->rec(268); + } + + goto f729;} + + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e732; + } + + $this->p++; + } + e732: + if (isset(self::Td8017923[$this->ids[$this->p]])) { + if (!$this->s270()) { + goto n733;} + n733: + } elseif ($this->p > $this->f) { + $this->rec(270); + } + if (!($this->ids[$this->p] === 39)) { + if ($this->p >= $this->f) { + $this->rec(62); + } + + goto f730;} + + $this->p++; + goto k730; + f730: + $this->p = $o2; + goto f729; + k730: + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n734;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e736; + } + + if (!$this->s224()) { + goto e736;} + if ($this->p === $b2) { + $k2 = 1; + goto e736; + } + + $k2++; + } + e736: + + if ($k2 < 1) { + goto f735; + } + goto k735; + f735: + $this->p = $o2; + goto n734; + k735: + n734: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k729; + f729: + $this->p = $o1; + return false; + k729: + + return true; + } + + private function s270(): bool + { + if (!isset(self::Td8017923[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(270); + } + + return false;} + + $o1 = $this->p; + // s271 + $o2 = $this->p; + if (!$this->s272()) { + goto f1019;} + if (($this->ids[$this->p] === 30)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(51); + } + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1019;} + + $this->p++; + if (!$this->s199()) { + goto f1019;} + goto k1019; + f1019: + $this->p = $o2; + goto f1018; + k1019: + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1021; + } + + $this->p++; + } + e1021: + if (($this->ids[$this->p] === 40)) { + if (!$this->s274()) { + goto n1022;} + n1022: + } elseif ($this->p > $this->f) { + $this->rec(274); + } + goto k1018; + f1018: + $this->p = $o1; + return false; + k1018: + + return true; + } + + private function s272(): bool + { + if (!isset(self::Td8017923[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(272); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + $this->p++; + goto a1313; + break; + case 2: + $this->p++; + goto a1313; + break; + case 3: + $this->p++; + goto a1313; + break; + case 4: + $this->p++; + goto a1313; + break; + case 5: + $this->p++; + goto a1313; + break; + case 6: + $this->p++; + goto a1313; + break; + case 7: + $this->p++; + goto a1313; + break; + case 8: + $this->p++; + goto a1313; + break; + case 9: + $this->p++; + goto a1313; + break; + case 10: + $this->p++; + goto a1313; + break; + case 11: + $this->p++; + goto a1313; + break; + case 12: + $this->p++; + goto a1313; + break; + case 13: + $this->p++; + goto a1313; + break; + case 14: + $this->p++; + goto a1313; + break; + case 15: + $this->p++; + goto a1313; + break; + case 16: + $this->p++; + goto a1313; + break; + case 17: + $this->p++; + goto a1313; + break; + case 18: + $this->p++; + goto a1313; + break; + case 21: + $this->p++; + goto a1313; + break; + case 22: + $this->p++; + goto a1313; + break; + case 24: + $this->p++; + goto a1313; + break; + } + + if ($this->p > $this->f) { + $this->rec(272); + } + + goto f1312; + a1313: + goto k1312; + f1312: + $this->p = $o1; + return false; + k1312: + + return true; + } + + private function s274(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(274); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(275); + } + + goto e1315; + } + + // s275 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(275); + } + + goto e1315;} + + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1318; + } + + $this->p++; + } + e1318: + if (!$this->s276()) { + goto f1316;} + goto k1316; + f1316: + $this->p = $o2; + goto e1315; + k1316: + if ($this->p === $b1) { + $k1 = 1; + goto e1315; + } + + $k1++; + } + e1315: + + if ($k1 < 1) { + goto f1314; + } + goto k1314; + f1314: + $this->p = $o1; + return false; + k1314: + + return true; + } + + private function s276(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 21: + case 22: + case 24: + // s277 + $o2 = $this->p; + // s271 + $o3 = $this->p; + if (!$this->s272()) { + goto f1589;} + if (($this->ids[$this->p] === 30)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(51); + } + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1589;} + + $this->p++; + if (!$this->s199()) { + goto f1589;} + goto k1589; + f1589: + $this->p = $o3; + goto f1588; + k1589: + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1591; + } + + $this->p++; + } + e1591: + goto k1588; + f1588: + $this->p = $o2; + goto n1587; + k1588: + goto a1586; + n1587: + break; + case 39: + if (!($this->ids[$this->p] === 39)) { + if ($this->p > $this->f) { + $this->rec(62); + } + + goto n1592;} + goto a1586; + n1592: + break; + } + + if ($this->p > $this->f) { + $this->rec(276); + } + + goto f1585; + a1586: + goto k1585; + f1585: + $this->p = $o1; + return false; + k1585: + + return true; + } + + private function s281(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n699;} + goto a698; + n699: + break; + case 32: + case 82: + // s364 + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e703; + } + + $this->p++; + } + e703: + if (isset(self::T7680fe2e[$this->ids[$this->p]])) { + if (!$this->s306()) { + goto n704;} + n704: + } elseif ($this->p > $this->f) { + $this->rec(306); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f701;} + + $this->p++; + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f701;} + + $this->p++; + if (!$this->s315()) { + goto f701;} + goto k701; + f701: + $this->p = $o2; + goto n700; + k701: + goto a698; + n700: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n705;} + goto a698; + n705: + break; + case 36: + case 84: + // s223 + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e708; + } + + if (!$this->s224()) { + goto e708;} + if ($this->p === $b2) { + $k2 = 1; + goto e708; + } + + $k2++; + } + e708: + + if ($k2 < 1) { + goto f707; + } + goto k707; + f707: + $this->p = $o2; + goto n706; + k707: + goto a698; + n706: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n709;} + goto a698; + n709: + break; + case 34: + if (!$this->s282()) { + goto n710;} + goto a698; + n710: + if (($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n711;} + goto a698; + n711: + break; + } + + if ($this->p > $this->f) { + $this->rec(281); + } + + goto f697; + a698: + goto k697; + f697: + $this->p = $o1; + return false; + k697: + + return true; + } + + private function s282(): bool + { + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(282); + } + + return false;} + + $o1 = $this->p; + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(54); + } + + goto f1004;} + if (!$this->s284()) { + goto f1004;} + goto k1004; + f1004: + $this->p = $o1; + return false; + k1004: + + return true; + } + + private function s284(): bool + { + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(284); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 34: + if (!$this->s285()) { + goto n1285;} + goto a1284; + n1285: + // s362 + $o2 = $this->p; + if (!$this->s363()) { + goto f1287;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n1288;} + + $o3 = $this->p; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(224); + } + + goto e1290; + } + + if (!$this->s224()) { + goto e1290;} + if ($this->p === $b3) { + $k3 = 1; + goto e1290; + } + + $k3++; + } + e1290: + + if ($k3 < 1) { + goto f1289; + } + goto k1289; + f1289: + $this->p = $o3; + goto n1288; + k1289: + n1288: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k1287; + f1287: + $this->p = $o2; + goto n1286; + k1287: + goto a1284; + n1286: + break; + } + + if ($this->p > $this->f) { + $this->rec(284); + } + + goto f1283; + a1284: + goto k1283; + f1283: + $this->p = $o1; + return false; + k1283: + + return true; + } + + private function s285(): bool + { + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(285); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1548; + } + + $this->p++; + } + e1548: + if (!$this->s286()) { + goto f1546;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1550; + } + + $this->p++; + } + e1550: + if (($this->ids[$this->p] === 40)) { + if (!$this->s300()) { + goto n1551;} + n1551: + } elseif ($this->p > $this->f) { + $this->rec(300); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1546;} + + $this->p++; + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f1546;} + + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1553; + } + + $this->p++; + } + e1553: + if (isset(self::T7680fe2e[$this->ids[$this->p]])) { + if (!$this->s306()) { + goto n1554;} + n1554: + } elseif ($this->p > $this->f) { + $this->rec(306); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f1546;} + + $this->p++; + if (!($this->ids[$this->p] === 47)) { + if ($this->p >= $this->f) { + $this->rec(70); + } + + goto f1546;} + + $this->p++; + if (!$this->s315()) { + goto f1546;} + goto k1546; + f1546: + $this->p = $o1; + return false; + k1546: + + return true; + } + + private function s286(): bool + { + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(286); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!$this->s287()) { + goto f1633;} + // s293 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 5)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1636;} + goto a1635; + n1636: + break; + case 5: + // s294 + $o3 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f1638;} + goto k1638; + f1638: + $this->p = $o3; + goto n1637; + k1638: + goto a1635; + n1637: + if (($this->ids[$this->p] === 5)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1639;} + goto a1635; + n1639: + break; + } + + if ($this->p > $this->f) { + $this->rec(293); + } + + goto f1634; + a1635: + goto k1634; + f1634: + $this->p = $o2; + goto f1633; + k1634: + // s296 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1642;} + goto a1641; + n1642: + break; + case 46: + // s297 + $o3 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f1644;} + goto k1644; + f1644: + $this->p = $o3; + goto n1643; + k1644: + goto a1641; + n1643: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1645;} + goto a1641; + n1645: + break; + } + + if ($this->p > $this->f) { + $this->rec(296); + } + + goto f1640; + a1641: + goto k1640; + f1640: + $this->p = $o2; + goto f1633; + k1640: + goto k1633; + f1633: + $this->p = $o1; + return false; + k1633: + + return true; + } + + private function s287(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s290 + $o2 = $this->p; + if (($this->ids[$this->p] === 13)) { + if (($this->ids[$this->p] === 13)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f626;} + } + if (($this->ids[$this->p] === 14)) { + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f626;} + } + goto k626; + f626: + $this->p = $o2; + goto n625; + k626: + goto a624; + n625: + break; + case 13: + // s288 + $o2 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f628;} + goto k628; + f628: + $this->p = $o2; + goto n627; + k628: + goto a624; + n627: + // s290 + $o2 = $this->p; + if (($this->ids[$this->p] === 13)) { + if (($this->ids[$this->p] === 13)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f630;} + } + if (($this->ids[$this->p] === 14)) { + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f630;} + } + goto k630; + f630: + $this->p = $o2; + goto n629; + k630: + goto a624; + n629: + break; + case 14: + // s289 + $o2 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f632;} + goto k632; + f632: + $this->p = $o2; + goto n631; + k632: + goto a624; + n631: + // s290 + $o2 = $this->p; + if (($this->ids[$this->p] === 13)) { + if (($this->ids[$this->p] === 13)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f634;} + } + if (($this->ids[$this->p] === 14)) { + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f634;} + } + goto k634; + f634: + $this->p = $o2; + goto n633; + k634: + goto a624; + n633: + break; + } + + if ($this->p > $this->f) { + $this->rec(287); + } + + goto f623; + a624: + goto k623; + f623: + $this->p = $o1; + return false; + k623: + + return true; + } + + private function s300(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(300); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(301); + } + + goto e1678; + } + + // s301 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(301); + } + + goto e1678;} + + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1681; + } + + $this->p++; + } + e1681: + if (!$this->s302()) { + goto f1679;} + goto k1679; + f1679: + $this->p = $o2; + goto e1678; + k1679: + if ($this->p === $b1) { + $k1 = 1; + goto e1678; + } + + $k1++; + } + e1678: + + if ($k1 < 1) { + goto f1677; + } + goto k1677; + f1677: + $this->p = $o1; + return false; + k1677: + + return true; + } + + private function s302(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // s304 + $o2 = $this->p; + if (!$this->s286()) { + goto f1737;} + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1739; + } + + $this->p++; + } + e1739: + goto k1737; + f1737: + $this->p = $o2; + goto n1736; + k1737: + goto a1735; + n1736: + break; + case 35: + if (!($this->ids[$this->p] === 35)) { + if ($this->p > $this->f) { + $this->rec(56); + } + + goto n1740;} + goto a1735; + n1740: + break; + } + + if ($this->p > $this->f) { + $this->rec(302); + } + + goto f1734; + a1735: + goto k1734; + f1734: + $this->p = $o1; + return false; + k1734: + + return true; + } + + private function s306(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(306); + } + + return false;} + + $o1 = $this->p; + // s307 + $o2 = $this->p; + if (!$this->s199()) { + goto f964;} + if (($this->ids[$this->p] === 27)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (($this->ids[$this->p] === 26)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(47); + } + if (($this->ids[$this->p] === 46)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + goto k964; + f964: + $this->p = $o2; + goto f963; + k964: + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e966; + } + + $this->p++; + } + e966: + if (($this->ids[$this->p] === 40)) { + if (!$this->s311()) { + goto n967;} + n967: + } elseif ($this->p > $this->f) { + $this->rec(311); + } + goto k963; + f963: + $this->p = $o1; + return false; + k963: + + return true; + } + + private function s311(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(311); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b1 > $this->f) { + $this->rec(312); + } + + goto e1262; + } + + // s312 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(312); + } + + goto e1262;} + + $o2 = $this->p; + $this->p++; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1265; + } + + $this->p++; + } + e1265: + if (!$this->s313()) { + goto f1263;} + goto k1263; + f1263: + $this->p = $o2; + goto e1262; + k1263: + if ($this->p === $b1) { + $k1 = 1; + goto e1262; + } + + $k1++; + } + e1262: + + if ($k1 < 1) { + goto f1261; + } + goto k1261; + f1261: + $this->p = $o1; + return false; + k1261: + + return true; + } + + private function s313(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + // s314 + $o2 = $this->p; + // s307 + $o3 = $this->p; + if (!$this->s199()) { + goto f1542;} + if (($this->ids[$this->p] === 27)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (($this->ids[$this->p] === 26)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(47); + } + if (($this->ids[$this->p] === 46)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(69); + } + goto k1542; + f1542: + $this->p = $o3; + goto f1541; + k1542: + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1544; + } + + $this->p++; + } + e1544: + goto k1541; + f1541: + $this->p = $o2; + goto n1540; + k1541: + goto a1539; + n1540: + break; + case 33: + if (!($this->ids[$this->p] === 33)) { + if ($this->p > $this->f) { + $this->rec(53); + } + + goto n1545;} + goto a1539; + n1545: + break; + } + + if ($this->p > $this->f) { + $this->rec(313); + } + + goto f1538; + a1539: + goto k1538; + f1538: + $this->p = $o1; + return false; + k1538: + + return true; + } + + private function s315(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(315); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 5: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // s331 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f971;} + } + if (!$this->s318()) { + goto f971;} + goto k971; + f971: + $this->p = $o2; + goto n970; + k971: + goto a969; + n970: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f973;} + } + if (!$this->s335()) { + goto f973;} + goto k973; + f973: + $this->p = $o2; + goto n972; + k973: + goto a969; + n972: + break; + case 19: + case 20: + case 21: + case 22: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f976;} + } + if (!$this->s335()) { + goto f976;} + goto k976; + f976: + $this->p = $o2; + goto n975; + k976: + goto a969; + n975: + break; + case 3: + case 4: + case 8: + if (!$this->s255()) { + goto n978;} + goto a969; + n978: + // s317 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f980;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f980;} + } + if (!$this->s318()) { + goto f980;} + goto k980; + f980: + $this->p = $o2; + goto n979; + k980: + goto a969; + n979: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f982;} + } + if (!$this->s335()) { + goto f982;} + goto k982; + f982: + $this->p = $o2; + goto n981; + k982: + goto a969; + n981: + break; + case 32: + case 82: + if (!$this->s316()) { + goto n984;} + goto a969; + n984: + break; + case 6: + if (!$this->s267()) { + goto n985;} + goto a969; + n985: + // s317 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f987;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f987;} + } + if (!$this->s318()) { + goto f987;} + goto k987; + f987: + $this->p = $o2; + goto n986; + k987: + goto a969; + n986: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f989;} + } + if (!$this->s335()) { + goto f989;} + goto k989; + f989: + $this->p = $o2; + goto n988; + k989: + goto a969; + n988: + break; + case 7: + if (!$this->s230()) { + goto n991;} + goto a969; + n991: + // s317 + $o2 = $this->p; + $this->p++; + if (($this->ids[$this->p] === 43)) { + if (($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f993;} + } + if (($this->ids[$this->p] === 38)) { + if (($this->ids[$this->p] === 38)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f993;} + } + if (!$this->s318()) { + goto f993;} + goto k993; + f993: + $this->p = $o2; + goto n992; + k993: + goto a969; + n992: + // s333 + $o2 = $this->p; + if (isset(self::T83e30518[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s169(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f995;} + } + if (!$this->s335()) { + goto f995;} + goto k995; + f995: + $this->p = $o2; + goto n994; + k995: + goto a969; + n994: + break; + case 25: + // s229 + $o2 = $this->p; + $this->p++; + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n999;} + + $o3 = $this->p; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(224); + } + + goto e1001; + } + + if (!$this->s224()) { + goto e1001;} + if ($this->p === $b3) { + $k3 = 1; + goto e1001; + } + + $k3++; + } + e1001: + + if ($k3 < 1) { + goto f1000; + } + goto k1000; + f1000: + $this->p = $o3; + goto n999; + k1000: + n999: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto a969; + n997: + break; + case 30: + // s200 + $o2 = $this->p; + $this->p++; + if (!$this->s201()) { + goto f1003;} + goto k1003; + f1003: + $this->p = $o2; + goto n1002; + k1003: + goto a969; + n1002: + break; + } + + if ($this->p > $this->f) { + $this->rec(315); + } + + goto f968; + a969: + goto k968; + f968: + $this->p = $o1; + return false; + k968: + + return true; + } + + private function s316(): bool + { + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(316); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!$this->s205()) { + goto f1279;} + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f1279;} + + $this->p++; + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n1280;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e1282; + } + + if (!$this->s224()) { + goto e1282;} + if ($this->p === $b2) { + $k2 = 1; + goto e1282; + } + + $k2++; + } + e1282: + + if ($k2 < 1) { + goto f1281; + } + goto k1281; + f1281: + $this->p = $o2; + goto n1280; + k1281: + n1280: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k1279; + f1279: + $this->p = $o1; + return false; + k1279: + + return true; + } + + private function s318(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1268;} + goto a1267; + n1268: + break; + case 34: + case 86: + // s319 + $o2 = $this->p; + if (!$this->s320()) { + goto f1270;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n1271;} + + $o3 = $this->p; + $k3 = 0; + while (true) { + $b3 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(224); + } + + goto e1273; + } + + if (!$this->s224()) { + goto e1273;} + if ($this->p === $b3) { + $k3 = 1; + goto e1273; + } + + $k3++; + } + e1273: + + if ($k3 < 1) { + goto f1272; + } + goto k1272; + f1272: + $this->p = $o3; + goto n1271; + k1272: + n1271: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k1270; + f1270: + $this->p = $o2; + goto n1269; + k1270: + goto a1267; + n1269: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1274;} + goto a1267; + n1274: + break; + case 36: + case 84: + // s223 + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e1277; + } + + if (!$this->s224()) { + goto e1277;} + if ($this->p === $b2) { + $k2 = 1; + goto e1277; + } + + $k2++; + } + e1277: + + if ($k2 < 1) { + goto f1276; + } + goto k1276; + f1276: + $this->p = $o2; + goto n1275; + k1276: + goto a1267; + n1275: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1278;} + goto a1267; + n1278: + break; + } + + if ($this->p > $this->f) { + $this->rec(318); + } + + goto f1266; + a1267: + goto k1266; + f1266: + $this->p = $o1; + return false; + k1266: + + return true; + } + + private function s320(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(320); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e637; + } + + $this->p++; + } + e637: + if (!$this->s321()) { + goto f635;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e639; + } + + $this->p++; + } + e639: + if (($this->ids[$this->p] === 40)) { + // s327 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(327); + } + + goto n640;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(328); + } + + goto e642; + } + + if (!$this->s328()) { + goto e642;} + if ($this->p === $b2) { + $k2 = 1; + goto e642; + } + + $k2++; + } + e642: + + if ($k2 < 1) { + goto f641; + } + goto k641; + f641: + $this->p = $o2; + goto n640; + k641: + n640: + } elseif ($this->p > $this->f) { + $this->rec(327); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f635;} + + $this->p++; + goto k635; + f635: + $this->p = $o1; + return false; + k635: + + return true; + } + + private function s321(): bool + { + if (!isset(self::Tb3cd2a63[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(321); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + // s324 + $o2 = $this->p; + if (isset(self::T05cf281c[$this->ids[$this->p]])) { + if (isset(self::T05cf281c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f874;} + } + if (!$this->s199()) { + goto f874;} + goto k874; + f874: + $this->p = $o2; + goto n873; + k874: + goto a872; + n873: + break; + case 1: + case 2: + // s322 + $o2 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f876;} + goto k876; + f876: + $this->p = $o2; + goto n875; + k876: + goto a872; + n875: + break; + case 50: + $this->p++; + goto a872; + break; + case 85: + $this->p++; + goto a872; + break; + } + + if ($this->p > $this->f) { + $this->rec(321); + } + + goto f871; + a872: + goto k871; + f871: + $this->p = $o1; + return false; + k871: + + return true; + } + + private function s328(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(328); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e879; + } + + $this->p++; + } + e879: + if (!$this->s329()) { + goto f877;} + goto k877; + f877: + $this->p = $o1; + return false; + k877: + + return true; + } + + private function s329(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 50: + case 82: + case 85: + // s330 + $o2 = $this->p; + if (!$this->s321()) { + goto f1137;} + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e1139; + } + + $this->p++; + } + e1139: + goto k1137; + f1137: + $this->p = $o2; + goto n1136; + k1137: + goto a1135; + n1136: + break; + case 35: + if (!($this->ids[$this->p] === 35)) { + if ($this->p > $this->f) { + $this->rec(56); + } + + goto n1140;} + goto a1135; + n1140: + break; + } + + if ($this->p > $this->f) { + $this->rec(329); + } + + goto f1134; + a1135: + goto k1134; + f1134: + $this->p = $o1; + return false; + k1134: + + return true; + } + + private function s335(): bool + { + if (!isset(self::T4546fd6c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(335); + } + + return false;} + + $o1 = $this->p; + if (isset(self::T1e81050f[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s337(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f712;} + } + if (!$this->s340()) { + goto f712;} + if (isset(self::T885cd349[$this->ids[$this->p]])) { + // s223 + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(223); + } + + goto n714;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!isset(self::T885cd349[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(224); + } + + goto e716; + } + + if (!$this->s224()) { + goto e716;} + if ($this->p === $b2) { + $k2 = 1; + goto e716; + } + + $k2++; + } + e716: + + if ($k2 < 1) { + goto f715; + } + goto k715; + f715: + $this->p = $o2; + goto n714; + k715: + n714: + } elseif ($this->p > $this->f) { + $this->rec(223); + } + goto k712; + f712: + $this->p = $o1; + return false; + k712: + + return true; + } + + private function s337(): bool + { + if (!isset(self::T1e81050f[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(337); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 7: + case 18: + // s338 + $o2 = $this->p; + $this->p++; + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f921;} + + $this->p++; + goto k921; + f921: + $this->p = $o2; + goto n920; + k921: + goto a919; + n920: + break; + case 36: + $this->p++; + goto a919; + break; + case 84: + $this->p++; + goto a919; + break; + } + + if ($this->p > $this->f) { + $this->rec(337); + } + + goto f918; + a919: + goto k918; + f918: + $this->p = $o1; + return false; + k918: + + return true; + } + + private function s340(): bool + { + if (!isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(340); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 24: + // s357 + $o2 = $this->p; + if (isset(self::T1ad6c327[$this->ids[$this->p]])) { + if (isset(self::T1ad6c327[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f206;} + } + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f206;} + + $this->p++; + if (($this->ids[$this->p] === 43)) { + // s360 + if (!($this->ids[$this->p] === 43)) { + if ($this->p > $this->f) { + $this->rec(360); + } + + goto n207;} + + $o3 = $this->p; + $this->p++; + if (!$this->s163()) { + goto f208;} + goto k208; + f208: + $this->p = $o3; + goto n207; + k208: + n207: + } elseif ($this->p > $this->f) { + $this->rec(360); + } + goto k206; + f206: + $this->p = $o2; + goto n205; + k206: + goto a204; + n205: + break; + case 7: + case 18: + // s347 + $o2 = $this->p; + $this->p++; + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f210;} + + $this->p++; + if (isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if (!$this->s349()) { + goto n211;} + n211: + } elseif ($this->p > $this->f) { + $this->rec(349); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f210;} + + $this->p++; + goto k210; + f210: + $this->p = $o2; + goto n209; + k210: + goto a204; + n209: + break; + case 21: + case 22: + // s343 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 21: + $this->p++; + goto a214; + break; + case 22: + $this->p++; + goto a214; + break; + } + + if ($this->p > $this->f) { + $this->rec(343); + } + + goto f213; + a214: + goto k213; + f213: + $this->p = $o2; + goto n212; + k213: + goto a204; + n212: + break; + case 36: + case 84: + // s361 + $o2 = $this->p; + $this->p++; + if (isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if (!$this->s349()) { + goto n217;} + n217: + } elseif ($this->p > $this->f) { + $this->rec(349); + } + if (!($this->ids[$this->p] === 37)) { + if ($this->p >= $this->f) { + $this->rec(59); + } + + goto f216;} + + $this->p++; + goto k216; + f216: + $this->p = $o2; + goto n215; + k216: + goto a204; + n215: + break; + case 15: + $this->p++; + goto a204; + break; + case 16: + $this->p++; + goto a204; + break; + case 17: + $this->p++; + goto a204; + break; + case 19: + $this->p++; + goto a204; + break; + case 20: + $this->p++; + goto a204; + break; + } + + if ($this->p > $this->f) { + $this->rec(340); + } + + goto f203; + a204: + goto k203; + f203: + $this->p = $o1; + return false; + k203: + + return true; + } + + private function s349(): bool + { + if (!isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(349); + } + + return false;} + + $o1 = $this->p; + // s350 + $o2 = $this->p; + if (!$this->s340()) { + goto f490;} + // s351 + $o3 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 44)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n493;} + goto a492; + n493: + break; + case 44: + // s352 + $o4 = $this->p; + $this->p++; + if (!$this->s340()) { + goto f495;} + goto k495; + f495: + $this->p = $o4; + goto n494; + k495: + goto a492; + n494: + if (($this->ids[$this->p] === 44)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n496;} + goto a492; + n496: + break; + } + + if ($this->p > $this->f) { + $this->rec(351); + } + + goto f491; + a492: + goto k491; + f491: + $this->p = $o3; + goto f490; + k491: + goto k490; + f490: + $this->p = $o2; + goto f489; + k490: + if (($this->ids[$this->p] === 40)) { + // s355 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(355); + } + + goto n497;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(356); + } + + goto e499; + } + + // s356 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(356); + } + + goto e499;} + + $o3 = $this->p; + $this->p++; + if (!$this->s350()) { + goto f500;} + goto k500; + f500: + $this->p = $o3; + goto e499; + k500: + if ($this->p === $b2) { + $k2 = 1; + goto e499; + } + + $k2++; + } + e499: + + if ($k2 < 1) { + goto f498; + } + goto k498; + f498: + $this->p = $o2; + goto n497; + k498: + n497: + } elseif ($this->p > $this->f) { + $this->rec(355); + } + if (($this->ids[$this->p] === 40)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(63); + } + goto k489; + f489: + $this->p = $o1; + return false; + k489: + + return true; + } + + private function s350(): bool + { + if (!isset(self::T69bf8cc4[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(350); + } + + return false;} + + $o1 = $this->p; + if (!$this->s340()) { + goto f776;} + // s351 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 44)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n779;} + goto a778; + n779: + break; + case 44: + // s352 + $o3 = $this->p; + $this->p++; + if (!$this->s340()) { + goto f781;} + goto k781; + f781: + $this->p = $o3; + goto n780; + k781: + goto a778; + n780: + if (($this->ids[$this->p] === 44)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n782;} + goto a778; + n782: + break; + } + + if ($this->p > $this->f) { + $this->rec(351); + } + + goto f777; + a778: + goto k777; + f777: + $this->p = $o2; + goto f776; + k777: + goto k776; + f776: + $this->p = $o1; + return false; + k776: + + return true; + } + + private function s363(): bool + { + if (!($this->ids[$this->p] === 34)) { + if ($this->p > $this->f) { + $this->rec(363); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1557; + } + + $this->p++; + } + e1557: + if (!$this->s321()) { + goto f1555;} + // s203 + $o2 = $this->p; + while (true) { + $b2 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b2 > $this->f) { + $this->rec(204); + } + + goto e1559; + } + + $this->p++; + } + e1559: + if (($this->ids[$this->p] === 40)) { + // s327 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(327); + } + + goto n1560;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(328); + } + + goto e1562; + } + + if (!$this->s328()) { + goto e1562;} + if ($this->p === $b2) { + $k2 = 1; + goto e1562; + } + + $k2++; + } + e1562: + + if ($k2 < 1) { + goto f1561; + } + goto k1561; + f1561: + $this->p = $o2; + goto n1560; + k1561: + n1560: + } elseif ($this->p > $this->f) { + $this->rec(327); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1555;} + + $this->p++; + goto k1555; + f1555: + $this->p = $o1; + return false; + k1555: + + return true; + } + + private function s368(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s383 + $o2 = $this->p; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f460;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f460;} + } + goto k460; + f460: + $this->p = $o2; + goto n459; + k460: + goto a458; + n459: + break; + case 28: + case 29: + case 41: + case 80: + // s369 + $o2 = $this->p; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e464; + } + + $this->p++; + } + e464: + // s370 + if (!isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(370); + } + + goto f462;} + + $o3 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 28: + if (!$this->s371()) { + goto n467;} + goto a466; + n467: + break; + case 29: + if (!$this->s377()) { + goto n468;} + goto a466; + n468: + break; + } + + if ($this->p > $this->f) { + $this->rec(370); + } + + goto f465; + a466: + goto k465; + f465: + $this->p = $o3; + goto f462; + k465: + goto k462; + f462: + $this->p = $o2; + goto n461; + k462: + goto a458; + n461: + // s383 + $o2 = $this->p; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f470;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f470;} + } + goto k470; + f470: + $this->p = $o2; + goto n469; + k470: + goto a458; + n469: + break; + } + + if ($this->p > $this->f) { + $this->rec(368); + } + + goto f457; + a458: + goto k457; + f457: + $this->p = $o1; + return false; + k457: + + return true; + } + + private function s371(): bool + { + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(371); + } + + return false;} + + $o1 = $this->p; + if (!$this->s372()) { + goto f749;} + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f749;} + } + goto k749; + f749: + $this->p = $o1; + return false; + k749: + + return true; + } + + private function s372(): bool + { + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(372); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 28)) { + if ($b1 > $this->f) { + $this->rec(373); + } + + goto e1030; + } + + // s373 + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(373); + } + + goto e1030;} + + $o2 = $this->p; + $this->p++; + if (!$this->s201()) { + goto f1031;} + // s375 + $o3 = $this->p; + // s203 + $o4 = $this->p; + while (true) { + $b4 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b4 > $this->f) { + $this->rec(204); + } + + goto e1035; + } + + $this->p++; + } + e1035: + if (!($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->rec(49); + } + + goto f1033;} + goto k1033; + f1033: + $this->p = $o3; + goto n1032; + k1033: + n1032: + goto k1031; + f1031: + $this->p = $o2; + goto e1030; + k1031: + if ($this->p === $b1) { + $k1 = 1; + goto e1030; + } + + $k1++; + } + e1030: + + if ($k1 < 1) { + goto f1029; + } + goto k1029; + f1029: + $this->p = $o1; + return false; + k1029: + + return true; + } + + private function s377(): bool + { + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(377); + } + + return false;} + + $o1 = $this->p; + if (!$this->s378()) { + goto f750;} + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f750;} + } + goto k750; + f750: + $this->p = $o1; + return false; + k750: + + return true; + } + + private function s378(): bool + { + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(378); + } + + return false;} + + $o1 = $this->p; + $k1 = 0; + while (true) { + $b1 = $this->p; + if (!($this->ids[$this->p] === 29)) { + if ($b1 > $this->f) { + $this->rec(379); + } + + goto e1037; + } + + // s379 + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(379); + } + + goto e1037;} + + $o2 = $this->p; + $this->p++; + if (!$this->s201()) { + goto f1038;} + // s381 + $o3 = $this->p; + // s203 + $o4 = $this->p; + while (true) { + $b4 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b4 > $this->f) { + $this->rec(204); + } + + goto e1042; + } + + $this->p++; + } + e1042: + if (!($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->rec(50); + } + + goto f1040;} + goto k1040; + f1040: + $this->p = $o3; + goto n1039; + k1040: + n1039: + goto k1038; + f1038: + $this->p = $o2; + goto e1037; + k1038: + if ($this->p === $b1) { + $k1 = 1; + goto e1037; + } + + $k1++; + } + e1037: + + if ($k1 < 1) { + goto f1036; + } + goto k1036; + f1036: + $this->p = $o1; + return false; + k1036: + + return true; + } + + private function s385(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + // s388 + $o2 = $this->p; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f381;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f381;} + } + if (($this->ids[$this->p] === 32)) { + if (($this->ids[$this->p] === 32)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f381;} + } + if (!$this->s125()) { + goto f381;} + goto k381; + f381: + $this->p = $o2; + goto n380; + k381: + goto a379; + n380: + break; + case 25: + case 26: + // s386 + $o2 = $this->p; + $this->p++; + if (!$this->s125()) { + goto f383;} + goto k383; + f383: + $this->p = $o2; + goto n382; + k383: + goto a379; + n382: + // s388 + $o2 = $this->p; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f385;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f385;} + } + if (($this->ids[$this->p] === 32)) { + if (($this->ids[$this->p] === 32)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f385;} + } + if (!$this->s125()) { + goto f385;} + goto k385; + f385: + $this->p = $o2; + goto n384; + k385: + goto a379; + n384: + break; + } + + if ($this->p > $this->f) { + $this->rec(385); + } + + goto f378; + a379: + goto k378; + f378: + $this->p = $o1; + return false; + k378: + + return true; + } + + private function s391(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(391); + } + + return false;} + + $o1 = $this->p; + if (!$this->s199()) { + goto f332;} + // s388 + $o2 = $this->p; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f333;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f333;} + } + if (($this->ids[$this->p] === 32)) { + if (($this->ids[$this->p] === 32)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f333;} + } + if (!$this->s125()) { + goto f333;} + goto k333; + f333: + $this->p = $o2; + goto f332; + k333: + goto k332; + f332: + $this->p = $o1; + return false; + k332: + + return true; + } + + private function s409(): bool + { + if (!isset(self::T7680fe2e[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(409); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 24: + case 25: + case 30: + case 32: + case 82: + // s435 + $o2 = $this->p; + if (!$this->s199()) { + goto f366;} + if (!$this->s415()) { + goto f366;} + goto k366; + f366: + $this->p = $o2; + goto n365; + k366: + goto a364; + n365: + break; + case 9: + // s410 + $o2 = $this->p; + $this->p++; + if (isset(self::T648acf56[$this->ids[$this->p]])) { + $sf = $this->f; + $se = $this->er; + $sp = $this->p; + $matched = $this->s412(); + $this->f = $sf; + $this->er = $se; + $this->p = $sp; + if ($matched) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f368;} + } + if (!$this->s199()) { + goto f368;} + if (!$this->s415()) { + goto f368;} + goto k368; + f368: + $this->p = $o2; + goto n367; + k368: + goto a364; + n367: + // s435 + $o2 = $this->p; + if (!$this->s199()) { + goto f371;} + if (!$this->s415()) { + goto f371;} + goto k371; + f371: + $this->p = $o2; + goto n370; + k371: + goto a364; + n370: + break; + } + + if ($this->p > $this->f) { + $this->rec(409); + } + + goto f363; + a364: + goto k363; + f363: + $this->p = $o1; + return false; + k363: + + return true; + } + + private function s412(): bool + { + if (!isset(self::T648acf56[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(412); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 28: + case 29: + case 41: + case 80: + // s413 + $o2 = $this->p; + // s203 + $o3 = $this->p; + while (true) { + $b3 = $this->p; + if (!isset(self::T5448ab4c[$this->ids[$this->p]])) { + if ($b3 > $this->f) { + $this->rec(204); + } + + goto e612; + } + + $this->p++; + } + e612: + if (!isset(self::Tc8c984b6[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(414); + } + + goto f610;} + + $this->p++; + goto k610; + f610: + $this->p = $o2; + goto n609; + k610: + goto a608; + n609: + break; + case 32: + $this->p++; + goto a608; + break; + case 34: + $this->p++; + goto a608; + break; + case 36: + $this->p++; + goto a608; + break; + case 43: + $this->p++; + goto a608; + break; + case 82: + $this->p++; + goto a608; + break; + case 84: + $this->p++; + goto a608; + break; + } + + if ($this->p > $this->f) { + $this->rec(412); + } + + goto f607; + a608: + goto k607; + f607: + $this->p = $o1; + return false; + k607: + + return true; + } + + private function s415(): bool + { + if (!isset(self::T02ca7bff[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(415); + } + + return false;} + + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + // s416 + $o2 = $this->p; + $this->p++; + if (!$this->s417()) { + goto f646;} + goto k646; + f646: + $this->p = $o2; + goto n645; + k646: + goto a644; + n645: + break; + case 32: + case 34: + case 82: + case 86: + if (!$this->s417()) { + goto n647;} + goto a644; + n647: + break; + } + + if ($this->p > $this->f) { + $this->rec(415); + } + + goto f643; + a644: + goto k643; + f643: + $this->p = $o1; + return false; + k643: + + return true; + } + + private function s417(): bool + { + if (!isset(self::Tf86de613[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(417); + } + + return false;} + + $o1 = $this->p; + if (!$this->s418()) { + goto f880;} + if (!isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(16); + } + + goto f880;} + + $this->p++; + if (isset(self::T9373805c[$this->ids[$this->p]])) { + if (!$this->s424()) { + goto n881;} + n881: + } elseif ($this->p > $this->f) { + $this->rec(424); + } + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f880;} + + $this->p++; + if (!$this->s125()) { + goto f880;} + goto k880; + f880: + $this->p = $o1; + return false; + k880: + + return true; + } + + private function s418(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1143;} + goto a1142; + n1143: + break; + case 34: + case 86: + if (!$this->s419()) { + goto n1144;} + goto a1142; + n1144: + if (isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1145;} + goto a1142; + n1145: + break; + } + + if ($this->p > $this->f) { + $this->rec(418); + } + + goto f1141; + a1142: + goto k1141; + f1141: + $this->p = $o1; + return false; + k1141: + + return true; + } + + private function s419(): bool + { + if (!isset(self::Tb46fb4f7[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(419); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!$this->s286()) { + goto f1425;} + if (($this->ids[$this->p] === 40)) { + // s421 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(421); + } + + goto n1426;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(422); + } + + goto e1428; + } + + // s422 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(422); + } + + goto e1428;} + + $o3 = $this->p; + $this->p++; + if (!$this->s286()) { + goto f1429;} + goto k1429; + f1429: + $this->p = $o3; + goto e1428; + k1429: + if ($this->p === $b2) { + $k2 = 1; + goto e1428; + } + + $k2++; + } + e1428: + + if ($k2 < 1) { + goto f1427; + } + goto k1427; + f1427: + $this->p = $o2; + goto n1426; + k1427: + n1426: + } elseif ($this->p > $this->f) { + $this->rec(421); + } + if (!($this->ids[$this->p] === 35)) { + if ($this->p >= $this->f) { + $this->rec(56); + } + + goto f1425;} + + $this->p++; + goto k1425; + f1425: + $this->p = $o1; + return false; + k1425: + + return true; + } + + private function s424(): bool + { + if (!isset(self::T9373805c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(424); + } + + return false;} + + $o1 = $this->p; + // s425 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + case 30: + case 32: + case 82: + if (!$this->s426()) { + goto n1149;} + goto a1148; + n1149: + break; + case 26: + case 27: + case 42: + if (!$this->s431()) { + goto n1150;} + goto a1148; + n1150: + break; + } + + if ($this->p > $this->f) { + $this->rec(425); + } + + goto f1147; + a1148: + goto k1147; + f1147: + $this->p = $o2; + goto f1146; + k1147: + if (($this->ids[$this->p] === 40)) { + // s433 + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(433); + } + + goto n1151;} + + $o2 = $this->p; + $k2 = 0; + while (true) { + $b2 = $this->p; + if (!($this->ids[$this->p] === 40)) { + if ($b2 > $this->f) { + $this->rec(434); + } + + goto e1153; + } + + if (!$this->s434()) { + goto e1153;} + if ($this->p === $b2) { + $k2 = 1; + goto e1153; + } + + $k2++; + } + e1153: + + if ($k2 < 1) { + goto f1152; + } + goto k1152; + f1152: + $this->p = $o2; + goto n1151; + k1152: + n1151: + } elseif ($this->p > $this->f) { + $this->rec(433); + } + goto k1146; + f1146: + $this->p = $o1; + return false; + k1146: + + return true; + } + + private function s426(): bool + { + if (!isset(self::T34c34eee[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(426); + } + + return false;} + + $o1 = $this->p; + if (!isset(self::T34c34eee[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(428); + } + + goto f1430;} + if (!$this->s199()) { + goto f1430;} + if (($this->ids[$this->p] === 27)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f1430;} + + $this->p++; + // s429 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1433;} + goto a1432; + n1433: + break; + case 46: + // s430 + $o3 = $this->p; + $this->p++; + if (!$this->s340()) { + goto f1435;} + goto k1435; + f1435: + $this->p = $o3; + goto n1434; + k1435: + goto a1432; + n1434: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1436;} + goto a1432; + n1436: + break; + } + + if ($this->p > $this->f) { + $this->rec(429); + } + + goto f1431; + a1432: + goto k1431; + f1431: + $this->p = $o2; + goto f1430; + k1431: + goto k1430; + f1430: + $this->p = $o1; + return false; + k1430: + + return true; + } + + private function s431(): bool + { + if (!isset(self::T553dc07b[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(431); + } + + return false;} + + $o1 = $this->p; + if (($this->ids[$this->p] === 27)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(48); + } + if (($this->ids[$this->p] === 42)) { + $this->p++; + } elseif ($this->p >= $this->f) { + $this->rec(65); + } + if (!($this->ids[$this->p] === 26)) { + if ($this->p >= $this->f) { + $this->rec(47); + } + + goto f1437;} + + $this->p++; + // s429 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1440;} + goto a1439; + n1440: + break; + case 46: + // s430 + $o3 = $this->p; + $this->p++; + if (!$this->s340()) { + goto f1442;} + goto k1442; + f1442: + $this->p = $o3; + goto n1441; + k1442: + goto a1439; + n1441: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n1443;} + goto a1439; + n1443: + break; + } + + if ($this->p > $this->f) { + $this->rec(429); + } + + goto f1438; + a1439: + goto k1438; + f1438: + $this->p = $o2; + goto f1437; + k1438: + goto k1437; + f1437: + $this->p = $o1; + return false; + k1437: + + return true; + } + + private function s434(): bool + { + if (!($this->ids[$this->p] === 40)) { + if ($this->p > $this->f) { + $this->rec(434); + } + + return false;} + + $o1 = $this->p; + $this->p++; + // s425 + if (!isset(self::T9373805c[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(425); + } + + goto f1444;} + + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 24: + case 30: + case 32: + case 82: + if (!$this->s426()) { + goto n1447;} + goto a1446; + n1447: + break; + case 26: + case 27: + case 42: + if (!$this->s431()) { + goto n1448;} + goto a1446; + n1448: + break; + } + + if ($this->p > $this->f) { + $this->rec(425); + } + + goto f1445; + a1446: + goto k1445; + f1445: + $this->p = $o2; + goto f1444; + k1445: + goto k1444; + f1444: + $this->p = $o1; + return false; + k1444: + + return true; + } + + private function s436(): bool + { + if (!($this->ids[$this->p] === 62)) { + if ($this->p > $this->f) { + $this->rec(436); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f347;} + + $this->p++; + if (!$this->s287()) { + goto f347;} + // s293 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 5)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n350;} + goto a349; + n350: + break; + case 5: + // s294 + $o3 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f352;} + goto k352; + f352: + $this->p = $o3; + goto n351; + k352: + goto a349; + n351: + if (($this->ids[$this->p] === 5)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n353;} + goto a349; + n353: + break; + } + + if ($this->p > $this->f) { + $this->rec(293); + } + + goto f348; + a349: + goto k348; + f348: + $this->p = $o2; + goto f347; + k348: + // s296 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n356;} + goto a355; + n356: + break; + case 46: + // s297 + $o3 = $this->p; + $this->p++; + if (!$this->s199()) { + goto f358;} + goto k358; + f358: + $this->p = $o3; + goto n357; + k358: + goto a355; + n357: + if (($this->ids[$this->p] === 46)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n359;} + goto a355; + n359: + break; + } + + if ($this->p > $this->f) { + $this->rec(296); + } + + goto f354; + a355: + goto k354; + f354: + $this->p = $o2; + goto f347; + k354: + // s388 + $o2 = $this->p; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f360;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f360;} + } + if (($this->ids[$this->p] === 32)) { + if (($this->ids[$this->p] === 32)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f360;} + } + if (!$this->s125()) { + goto f360;} + goto k360; + f360: + $this->p = $o2; + goto f347; + k360: + goto k347; + f347: + $this->p = $o1; + return false; + k347: + + return true; + } + + private function s438(): bool + { + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(438); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!$this->s320()) { + goto f361;} + // s388 + $o2 = $this->p; + if (($this->ids[$this->p] === 28)) { + if (($this->ids[$this->p] === 28)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f362;} + } + if (($this->ids[$this->p] === 29)) { + if (($this->ids[$this->p] === 29)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f362;} + } + if (($this->ids[$this->p] === 32)) { + if (($this->ids[$this->p] === 32)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto f362;} + } + if (!$this->s125()) { + goto f362;} + goto k362; + f362: + $this->p = $o2; + goto f361; + k362: + goto k361; + f361: + $this->p = $o1; + return false; + k361: + + return true; + } + + private function s443(): bool + { + if (!($this->ids[$this->p] === 58)) { + if ($this->p > $this->f) { + $this->rec(443); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f334;} + + $this->p++; + if (!($this->ids[$this->p] === 10)) { + if ($this->p >= $this->f) { + $this->rec(26); + } + + goto f334;} + + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f334;} + + $this->p++; + // s444 + $o2 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n337;} + goto a336; + n337: + break; + case 14: + // s445 + $o3 = $this->p; + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f339;} + + $this->p++; + goto k339; + f339: + $this->p = $o3; + goto n338; + k339: + goto a336; + n338: + if (($this->ids[$this->p] === 14)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n340;} + goto a336; + n340: + break; + } + + if ($this->p > $this->f) { + $this->rec(444); + } + + goto f335; + a336: + goto k335; + f335: + $this->p = $o2; + goto f334; + k335: + goto k334; + f334: + $this->p = $o1; + return false; + k334: + + return true; + } + + private function s449(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (($this->ids[$this->p] === 45)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n343;} + goto a342; + n343: + break; + case 45: + // s450 + $o2 = $this->p; + $this->p++; + if (!isset(self::T83e30518[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(144); + } + + goto f345;} + + $this->p++; + if (!$this->s451()) { + goto f345;} + goto k345; + f345: + $this->p = $o2; + goto n344; + k345: + goto a342; + n344: + if (($this->ids[$this->p] === 45)) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n346;} + goto a342; + n346: + break; + } + + if ($this->p > $this->f) { + $this->rec(449); + } + + goto f341; + a342: + goto k341; + f341: + $this->p = $o1; + return false; + k341: + + return true; + } + + private function s451(): bool + { + $o1 = $this->p; + switch ($this->ids[$this->p]) { + default: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n619;} + goto a618; + n619: + break; + case 32: + case 82: + // s452 + $o2 = $this->p; + $this->p++; + if (!($this->ids[$this->p] === 33)) { + if ($this->p >= $this->f) { + $this->rec(53); + } + + goto f621;} + + $this->p++; + goto k621; + f621: + $this->p = $o2; + goto n620; + k621: + goto a618; + n620: + if (isset(self::Tc8cfa1df[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->f = $this->p; + $this->er = []; + } + goto n622;} + goto a618; + n622: + break; + } + + if ($this->p > $this->f) { + $this->rec(451); + } + + goto f617; + a618: + goto k617; + f617: + $this->p = $o1; + return false; + k617: + + return true; + } + + private function s454(): bool + { + if (!isset(self::Tf4b693bf[$this->ids[$this->p]])) { + if ($this->p > $this->f) { + $this->rec(454); + } + + return false;} + + $o1 = $this->p; + $this->p++; + if (!$this->s125()) { + goto f288;} + goto k288; + f288: + $this->p = $o1; + return false; + k288: + + return true; + } +} diff --git a/src/Parser/PhpDocParser.php b/src/Parser/PhpDocParser.php index f6734225..7ac8e707 100644 --- a/src/Parser/PhpDocParser.php +++ b/src/Parser/PhpDocParser.php @@ -2,41 +2,21 @@ namespace PHPStan\PhpDocParser\Parser; -use LogicException; use PHPStan\PhpDocParser\Ast; -use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode; -use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode; -use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode; -use PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine; -use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Lexer\Lexer; use PHPStan\PhpDocParser\ParserConfig; -use PHPStan\ShouldNotHappenException; -use function array_key_exists; -use function count; -use function rtrim; -use function str_replace; -use function trim; +use function strlen; -/** - * @phpstan-import-type ValueType from Doctrine\DoctrineArgument as DoctrineValueType - */ class PhpDocParser { - private const DISALLOWED_DESCRIPTION_START_TOKENS = [ - Lexer::TOKEN_UNION, - Lexer::TOKEN_INTERSECTION, - ]; - private ParserConfig $config; - private TypeParser $typeParser; - - private ConstExprParser $constantExprParser; - - private ConstExprParser $doctrineConstantExprParser; + private AstBuilder $builder; + // The parsers it has always been given are not needed anymore, but it is + // constructed the way it always has been + // @phpstan-ignore constructor.unusedParameter, constructor.unusedParameter public function __construct( ParserConfig $config, TypeParser $typeParser, @@ -44,1214 +24,110 @@ public function __construct( ) { $this->config = $config; - $this->typeParser = $typeParser; - $this->constantExprParser = $constantExprParser; - $this->doctrineConstantExprParser = $constantExprParser->toDoctrine(); + $this->builder = new AstBuilder($config); } public function parse(TokenIterator $tokens): Ast\PhpDoc\PhpDocNode { - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PHPDOC); - $tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL); - - $children = []; - - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) { - $lastChild = $this->parseChild($tokens); - $children[] = $lastChild; - while (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) { - if ( - $lastChild instanceof Ast\PhpDoc\PhpDocTagNode - && ( - $lastChild->value instanceof Doctrine\DoctrineTagValueNode - || $lastChild->value instanceof Ast\PhpDoc\GenericTagValueNode - ) - ) { - $tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) { - break; - } - $lastChild = $this->parseChild($tokens); - $children[] = $lastChild; - continue; - } - - if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL)) { - break; - } - if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) { - break; - } - - $lastChild = $this->parseChild($tokens); - $children[] = $lastChild; - } - } - - try { - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PHPDOC); - } catch (ParserException $e) { - $name = ''; - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - if (count($children) > 0) { - $lastChild = $children[count($children) - 1]; - if ($lastChild instanceof Ast\PhpDoc\PhpDocTagNode) { - $name = $lastChild->name; - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - } - } - - $tag = new Ast\PhpDoc\PhpDocTagNode( - $name, - $this->enrichWithAttributes( - $tokens, - new Ast\PhpDoc\InvalidTagValueNode($e->getMessage(), $e), - $startLine, - $startIndex, - ), - ); - - $tokens->forwardToTheEnd(); - - $comments = $tokens->flushComments(); - if ($comments !== []) { - throw new LogicException('Comments should already be flushed'); - } - - return $this->enrichWithAttributes($tokens, new Ast\PhpDoc\PhpDocNode([$this->enrichWithAttributes($tokens, $tag, $startLine, $startIndex)]), 1, 0); - } - - $comments = $tokens->flushComments(); - if ($comments !== []) { - throw new LogicException('Comments should already be flushed'); - } - - return $this->enrichWithAttributes($tokens, new Ast\PhpDoc\PhpDocNode($children), 1, 0); - } - - /** @phpstan-impure */ - private function parseChild(TokenIterator $tokens): Ast\PhpDoc\PhpDocChildNode - { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG)) { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - return $this->enrichWithAttributes($tokens, $this->parseTag($tokens), $startLine, $startIndex); - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_DOCTRINE_TAG)) { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - $tag = $tokens->currentTokenValue(); - $tokens->next(); - - $tagStartLine = $tokens->currentTokenLine(); - $tagStartIndex = $tokens->currentTokenIndex(); - - return $this->enrichWithAttributes($tokens, new Ast\PhpDoc\PhpDocTagNode( - $tag, - $this->enrichWithAttributes( - $tokens, - $this->parseDoctrineTagValue($tokens, $tag), - $tagStartLine, - $tagStartIndex, - ), - ), $startLine, $startIndex); - } - - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - $text = $this->parseText($tokens); - - return $this->enrichWithAttributes($tokens, $text, $startLine, $startIndex); - } - - /** - * @template T of Ast\Node - * @param T $tag - * @return T - */ - private function enrichWithAttributes(TokenIterator $tokens, Ast\Node $tag, int $startLine, int $startIndex): Ast\Node - { - if ($this->config->useLinesAttributes) { - $tag->setAttribute(Ast\Attribute::START_LINE, $startLine); - $tag->setAttribute(Ast\Attribute::END_LINE, $tokens->currentTokenLine()); - } - - if ($this->config->useIndexAttributes) { - $tag->setAttribute(Ast\Attribute::START_INDEX, $startIndex); - $tag->setAttribute(Ast\Attribute::END_INDEX, $tokens->endIndexOfLastRelevantToken()); - } - - return $tag; - } - - private function parseText(TokenIterator $tokens): Ast\PhpDoc\PhpDocTextNode - { - $text = ''; - - $endTokens = [Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END]; - - $savepoint = false; - - // if the next token is EOL, everything below is skipped and empty string is returned - while (true) { - $tmpText = $tokens->getSkippedHorizontalWhiteSpaceIfAny() . $tokens->joinUntil(Lexer::TOKEN_PHPDOC_EOL, ...$endTokens); - $text .= $tmpText; - - // stop if we're not at EOL - meaning it's the end of PHPDoc - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC)) { - break; - } - - if (!$savepoint) { - $tokens->pushSavePoint(); - $savepoint = true; - } elseif ($tmpText !== '') { - $tokens->dropSavePoint(); - $tokens->pushSavePoint(); - } - - $tokens->pushSavePoint(); - $tokens->next(); - - // if we're at EOL, check what's next - // if next is a PHPDoc tag, EOL, or end of PHPDoc, stop - if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG, Lexer::TOKEN_DOCTRINE_TAG, ...$endTokens)) { - $tokens->rollback(); - break; - } - - // otherwise if the next is text, continue building the description string - - $tokens->dropSavePoint(); - $text .= $tokens->getDetectedNewline() ?? "\n"; - } - - if ($savepoint) { - $tokens->rollback(); - $text = rtrim($text, $tokens->getDetectedNewline() ?? "\n"); - } - - return new Ast\PhpDoc\PhpDocTextNode(trim($text, " \t")); - } - - private function parseOptionalDescriptionAfterDoctrineTag(TokenIterator $tokens): string - { - $text = ''; - - $endTokens = [Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END]; - - $savepoint = false; - - // if the next token is EOL, everything below is skipped and empty string is returned - while (true) { - $tmpText = $tokens->getSkippedHorizontalWhiteSpaceIfAny() . $tokens->joinUntil(Lexer::TOKEN_PHPDOC_TAG, Lexer::TOKEN_DOCTRINE_TAG, Lexer::TOKEN_PHPDOC_EOL, ...$endTokens); - $text .= $tmpText; - - // stop if we're not at EOL - meaning it's the end of PHPDoc - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC)) { - if (!$tokens->isPrecededByHorizontalWhitespace()) { - return trim($text . $this->parseText($tokens)->text, " \t"); - } - if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG)) { - $tokens->pushSavePoint(); - $child = $this->parseChild($tokens); - if ($child instanceof Ast\PhpDoc\PhpDocTagNode) { - if ( - $child->value instanceof Ast\PhpDoc\GenericTagValueNode - || $child->value instanceof Doctrine\DoctrineTagValueNode - ) { - $tokens->rollback(); - break; - } - if ($child->value instanceof Ast\PhpDoc\InvalidTagValueNode) { - $tokens->rollback(); - $tokens->pushSavePoint(); - $tokens->next(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { - $tokens->rollback(); - break; - } - $tokens->rollback(); - return trim($text . $this->parseText($tokens)->text, " \t"); - } - } - - $tokens->rollback(); - return trim($text . $this->parseText($tokens)->text, " \t"); - } - break; - } - - if (!$savepoint) { - $tokens->pushSavePoint(); - $savepoint = true; - } elseif ($tmpText !== '') { - $tokens->dropSavePoint(); - $tokens->pushSavePoint(); - } - - $tokens->pushSavePoint(); - $tokens->next(); - - // if we're at EOL, check what's next - // if next is a PHPDoc tag, EOL, or end of PHPDoc, stop - if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG, Lexer::TOKEN_DOCTRINE_TAG, ...$endTokens)) { - $tokens->rollback(); - break; - } - - // otherwise if the next is text, continue building the description string - - $tokens->dropSavePoint(); - $text .= $tokens->getDetectedNewline() ?? "\n"; - } - - if ($savepoint) { - $tokens->rollback(); - $text = rtrim($text, $tokens->getDetectedNewline() ?? "\n"); - } - - return trim($text, " \t"); - } - - public function parseTag(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagNode - { - $tag = $tokens->currentTokenValue(); - $tokens->next(); - $value = $this->parseTagValue($tokens, $tag); - - return new Ast\PhpDoc\PhpDocTagNode($tag, $value); - } - - public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\PhpDocTagValueNode - { - $startLine = $tokens->currentTokenLine(); $startIndex = $tokens->currentTokenIndex(); - - try { - $tokens->pushSavePoint(); - - switch ($tag) { - case '@param': - case '@phpstan-param': - case '@psalm-param': - case '@phan-param': - $tagValue = $this->parseParamTagValue($tokens); - break; - - case '@param-immediately-invoked-callable': - case '@phpstan-param-immediately-invoked-callable': - $tagValue = $this->parseParamImmediatelyInvokedCallableTagValue($tokens); - break; - - case '@param-later-invoked-callable': - case '@phpstan-param-later-invoked-callable': - $tagValue = $this->parseParamLaterInvokedCallableTagValue($tokens); - break; - - case '@param-closure-this': - case '@phpstan-param-closure-this': - $tagValue = $this->parseParamClosureThisTagValue($tokens); - break; - - case '@pure-unless-callable-is-impure': - case '@phpstan-pure-unless-callable-is-impure': - $tagValue = $this->parsePureUnlessCallableIsImpureTagValue($tokens); - break; - - case '@pure-unless-parameter-passed': - case '@phpstan-pure-unless-parameter-passed': - $tagValue = $this->parsePureUnlessParameterIsPassed($tokens); - break; - - case '@var': - case '@phpstan-var': - case '@psalm-var': - case '@phan-var': - $tagValue = $this->parseVarTagValue($tokens); - break; - - case '@return': - case '@phpstan-return': - case '@psalm-return': - case '@phan-return': - case '@phan-real-return': - $tagValue = $this->parseReturnTagValue($tokens); - break; - - case '@throws': - case '@phpstan-throws': - $tagValue = $this->parseThrowsTagValue($tokens); - break; - - case '@mixin': - case '@phan-mixin': - $tagValue = $this->parseMixinTagValue($tokens); - break; - - case '@psalm-require-extends': - case '@phpstan-require-extends': - $tagValue = $this->parseRequireExtendsTagValue($tokens); - break; - - case '@psalm-require-implements': - case '@phpstan-require-implements': - $tagValue = $this->parseRequireImplementsTagValue($tokens); - break; - - case '@psalm-inheritors': - case '@phpstan-sealed': - $tagValue = $this->parseSealedTagValue($tokens); - break; - - case '@deprecated': - $tagValue = $this->parseDeprecatedTagValue($tokens); - break; - - case '@property': - case '@property-read': - case '@property-write': - case '@phpstan-property': - case '@phpstan-property-read': - case '@phpstan-property-write': - case '@psalm-property': - case '@psalm-property-read': - case '@psalm-property-write': - case '@phan-property': - case '@phan-property-read': - case '@phan-property-write': - $tagValue = $this->parsePropertyTagValue($tokens); - break; - - case '@method': - case '@phpstan-method': - case '@psalm-method': - case '@phan-method': - $tagValue = $this->parseMethodTagValue($tokens); - break; - - case '@template': - case '@phpstan-template': - case '@psalm-template': - case '@phan-template': - case '@template-covariant': - case '@phpstan-template-covariant': - case '@psalm-template-covariant': - case '@template-contravariant': - case '@phpstan-template-contravariant': - case '@psalm-template-contravariant': - $tagValue = $this->typeParser->parseTemplateTagValue( - $tokens, - fn ($tokens) => $this->parseOptionalDescription($tokens, true), - ); - break; - - case '@extends': - case '@phpstan-extends': - case '@phan-extends': - case '@phan-inherits': - case '@template-extends': - $tagValue = $this->parseExtendsTagValue('@extends', $tokens); - break; - - case '@implements': - case '@phpstan-implements': - case '@template-implements': - $tagValue = $this->parseExtendsTagValue('@implements', $tokens); - break; - - case '@use': - case '@phpstan-use': - case '@template-use': - $tagValue = $this->parseExtendsTagValue('@use', $tokens); - break; - - case '@phpstan-type': - case '@psalm-type': - case '@phan-type': - $tagValue = $this->parseTypeAliasTagValue($tokens); - break; - - case '@phpstan-import-type': - case '@psalm-import-type': - $tagValue = $this->parseTypeAliasImportTagValue($tokens); - break; - - case '@phpstan-assert': - case '@phpstan-assert-if-true': - case '@phpstan-assert-if-false': - case '@psalm-assert': - case '@psalm-assert-if-true': - case '@psalm-assert-if-false': - case '@phan-assert': - case '@phan-assert-if-true': - case '@phan-assert-if-false': - $tagValue = $this->parseAssertTagValue($tokens); - break; - - case '@phpstan-this-out': - case '@phpstan-self-out': - case '@psalm-this-out': - case '@psalm-self-out': - $tagValue = $this->parseSelfOutTagValue($tokens); - break; - - case '@param-out': - case '@phpstan-param-out': - case '@psalm-param-out': - $tagValue = $this->parseParamOutTagValue($tokens); - break; - - default: - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { - $tagValue = $this->parseDoctrineTagValue($tokens, $tag); - } else { - $tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescriptionAfterDoctrineTag($tokens)); - } - break; + $all = $tokens->getTokens(); + foreach ($all as $i => $token) { + if ($i < $startIndex || $token[Lexer::TYPE_OFFSET] !== Lexer::TOKEN_PHPDOC_EOL) { + continue; } - $tokens->dropSavePoint(); - - } catch (ParserException $e) { - $tokens->rollback(); - $tagValue = new Ast\PhpDoc\InvalidTagValueNode($this->parseOptionalDescription($tokens, false), $e); - } - - return $this->enrichWithAttributes($tokens, $tagValue, $startLine, $startIndex); - } - - private function parseDoctrineTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\PhpDocTagValueNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - return new Doctrine\DoctrineTagValueNode( - $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineAnnotation($tag, $this->parseDoctrineArguments($tokens, false)), - $startLine, - $startIndex, - ), - $this->parseOptionalDescriptionAfterDoctrineTag($tokens), - ); - } - - /** - * @return list - */ - private function parseDoctrineArguments(TokenIterator $tokens, bool $deep): array - { - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { - return []; + $tokens->detectNewlineOf($token[Lexer::VALUE_OFFSET]); + break; } - if (!$deep) { - $tokens->addEndOfLineToSkippedTokens(); - } - - $arguments = []; - try { - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES); - - do { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) { - break; - } - $arguments[] = $this->parseDoctrineArgument($tokens); - } while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)); - } finally { - if (!$deep) { - $tokens->removeEndOfLineFromSkippedTokens(); - } - } - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); - - return $arguments; - } - - private function parseDoctrineArgument(TokenIterator $tokens): Doctrine\DoctrineArgument - { - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - return $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineArgument(null, $this->parseDoctrineArgumentValue($tokens)), - $startLine, - $startIndex, - ); - } - - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - try { - $tokens->pushSavePoint(); - $currentValue = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - $key = $this->enrichWithAttributes( - $tokens, - new IdentifierTypeNode($currentValue), - $startLine, - $startIndex, - ); - $tokens->consumeTokenType(Lexer::TOKEN_EQUAL); - - $value = $this->parseDoctrineArgumentValue($tokens); - - $tokens->dropSavePoint(); - - return $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineArgument($key, $value), - $startLine, - $startIndex, - ); + /** @var Ast\PhpDoc\PhpDocNode */ + return $this->builder->read($tokens, 'PhpDoc'); } catch (ParserException $e) { - $tokens->rollback(); - - return $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineArgument(null, $this->parseDoctrineArgumentValue($tokens)), - $startLine, - $startIndex, - ); + return $this->createInvalidPhpDoc($tokens, $e, $startIndex); } } /** - * @return DoctrineValueType + * A PHPDoc that cannot be read up to its end is read as a single tag that + * cannot be read: the one written last before the error, if any. */ - private function parseDoctrineArgumentValue(TokenIterator $tokens) - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG, Lexer::TOKEN_DOCTRINE_TAG)) { - $name = $tokens->currentTokenValue(); - $tokens->next(); - - return $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineAnnotation($name, $this->parseDoctrineArguments($tokens, true)), - $startLine, - $startIndex, - ); - } - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET)) { - $items = []; - do { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) { - break; - } - $items[] = $this->parseDoctrineArrayItem($tokens); - } while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)); - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET); - - return $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineArray($items), - $startLine, - $startIndex, - ); - } - - $currentTokenValue = $tokens->currentTokenValue(); - $tokens->pushSavePoint(); // because of ConstFetchNode - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_IDENTIFIER)) { - $identifier = $this->enrichWithAttributes( - $tokens, - new Ast\Type\IdentifierTypeNode($currentTokenValue), - $startLine, - $startIndex, - ); - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON)) { - $tokens->dropSavePoint(); - return $identifier; - } - - $tokens->rollback(); // because of ConstFetchNode - } else { - $tokens->dropSavePoint(); // because of ConstFetchNode - } - - $currentTokenValue = $tokens->currentTokenValue(); - $currentTokenType = $tokens->currentTokenType(); - $currentTokenOffset = $tokens->currentTokenOffset(); - $currentTokenLine = $tokens->currentTokenLine(); - - try { - $constExpr = $this->doctrineConstantExprParser->parse($tokens); - if ($constExpr instanceof Ast\ConstExpr\ConstExprArrayNode) { - throw new ParserException( - $currentTokenValue, - $currentTokenType, - $currentTokenOffset, - Lexer::TOKEN_IDENTIFIER, - null, - $currentTokenLine, - ); + private function createInvalidPhpDoc(TokenIterator $tokens, ParserException $e, int $startIndex): Ast\PhpDoc\PhpDocNode + { + $all = $tokens->getTokens(); + $errorIndex = $startIndex; + $offset = 0; + foreach ($all as $i => $token) { + if ($offset >= $e->getCurrentOffset()) { + $errorIndex = $i; + break; } - return $constExpr; - } catch (LogicException $e) { - throw new ParserException( - $currentTokenValue, - $currentTokenType, - $currentTokenOffset, - Lexer::TOKEN_IDENTIFIER, - null, - $currentTokenLine, - ); + $offset += strlen($token[Lexer::VALUE_OFFSET]); } - } - - private function parseDoctrineArrayItem(TokenIterator $tokens): Doctrine\DoctrineArrayItem - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - try { - $tokens->pushSavePoint(); - $key = $this->parseDoctrineArrayKey($tokens); - if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL)) { - if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_COLON)) { - $tokens->consumeTokenType(Lexer::TOKEN_EQUAL); // will throw exception - } + $name = ''; + for ($i = $errorIndex - 1; $i > $startIndex; $i--) { + $type = $all[$i][Lexer::TYPE_OFFSET]; + if ($type === Lexer::TOKEN_PHPDOC_TAG || $type === Lexer::TOKEN_DOCTRINE_TAG) { + $name = $all[$i][Lexer::VALUE_OFFSET]; + break; } - - $value = $this->parseDoctrineArgumentValue($tokens); - - $tokens->dropSavePoint(); - - return $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineArrayItem($key, $value), - $startLine, - $startIndex, - ); - } catch (ParserException $e) { - $tokens->rollback(); - - return $this->enrichWithAttributes( - $tokens, - new Doctrine\DoctrineArrayItem(null, $this->parseDoctrineArgumentValue($tokens)), - $startLine, - $startIndex, - ); } - } - - /** - * @return ConstExprIntegerNode|ConstExprStringNode|IdentifierTypeNode|ConstFetchNode - */ - private function parseDoctrineArrayKey(TokenIterator $tokens) - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) { - $key = new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $tokens->currentTokenValue())); - $tokens->next(); + $tokens->forwardToTheEnd(); - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_DOCTRINE_ANNOTATION_STRING)) { - $key = $this->doctrineConstantExprParser->parseDoctrineString($tokens->currentTokenValue(), $tokens); + $value = new Ast\PhpDoc\InvalidTagValueNode($e->getMessage(), $e); + $tag = new Ast\PhpDoc\PhpDocTagNode($name, $value); + $node = new Ast\PhpDoc\PhpDocNode([$tag]); - $tokens->next(); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) { - $key = new Ast\ConstExpr\ConstExprStringNode(StringUnescaper::unescapeString($tokens->currentTokenValue()), Ast\ConstExpr\ConstExprStringNode::SINGLE_QUOTED); - $tokens->next(); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_QUOTED_STRING)) { - $value = $tokens->currentTokenValue(); - $tokens->next(); - $key = $this->doctrineConstantExprParser->parseDoctrineString($value, $tokens); - - } else { - $currentTokenValue = $tokens->currentTokenValue(); - $tokens->pushSavePoint(); // because of ConstFetchNode - if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_IDENTIFIER)) { - $tokens->dropSavePoint(); - throw new ParserException( - $tokens->currentTokenValue(), - $tokens->currentTokenType(), - $tokens->currentTokenOffset(), - Lexer::TOKEN_IDENTIFIER, - null, - $tokens->currentTokenLine(), - ); - } - - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON)) { - $tokens->dropSavePoint(); - - return $this->enrichWithAttributes( - $tokens, - new IdentifierTypeNode($currentTokenValue), - $startLine, - $startIndex, - ); + $endIndex = $tokens->endIndexOfLastRelevantToken(); + $endLine = $tokens->currentTokenLine(); + foreach ([$value, $tag, $node] as $item) { + $isPhpDoc = $item === $node; + if ($this->config->useLinesAttributes) { + $item->setAttribute(Ast\Attribute::START_LINE, $isPhpDoc ? $all[$startIndex][Lexer::LINE_OFFSET] : $all[$errorIndex][Lexer::LINE_OFFSET]); + $item->setAttribute(Ast\Attribute::END_LINE, $endLine); } - $tokens->rollback(); - $constExpr = $this->doctrineConstantExprParser->parse($tokens); - if (!$constExpr instanceof Ast\ConstExpr\ConstFetchNode) { - throw new ParserException( - $tokens->currentTokenValue(), - $tokens->currentTokenType(), - $tokens->currentTokenOffset(), - Lexer::TOKEN_IDENTIFIER, - null, - $tokens->currentTokenLine(), - ); + if (!$this->config->useIndexAttributes) { + continue; } - return $constExpr; + $item->setAttribute(Ast\Attribute::START_INDEX, $isPhpDoc ? $startIndex : $errorIndex); + $item->setAttribute(Ast\Attribute::END_INDEX, $endIndex); } - return $this->enrichWithAttributes($tokens, $key, $startLine, $startIndex); + return $node; } /** - * @return Ast\PhpDoc\ParamTagValueNode|Ast\PhpDoc\TypelessParamTagValueNode + * Reads the tag at the position the iterator is at, along with its value. */ - private function parseParamTagValue(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode - { - if ( - $tokens->isCurrentTokenType(Lexer::TOKEN_REFERENCE, Lexer::TOKEN_VARIADIC, Lexer::TOKEN_VARIABLE) - ) { - $type = null; - } else { - $type = $this->typeParser->parse($tokens); - } - - $isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE); - $isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC); - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - if ($type !== null) { - return new Ast\PhpDoc\ParamTagValueNode($type, $isVariadic, $parameterName, $description, $isReference); - } - - return new Ast\PhpDoc\TypelessParamTagValueNode($isVariadic, $parameterName, $description, $isReference); - } - - private function parseParamImmediatelyInvokedCallableTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamImmediatelyInvokedCallableTagValueNode - { - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - return new Ast\PhpDoc\ParamImmediatelyInvokedCallableTagValueNode($parameterName, $description); - } - - private function parseParamLaterInvokedCallableTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamLaterInvokedCallableTagValueNode - { - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - return new Ast\PhpDoc\ParamLaterInvokedCallableTagValueNode($parameterName, $description); - } - - private function parseParamClosureThisTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamClosureThisTagValueNode - { - $type = $this->typeParser->parse($tokens); - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - return new Ast\PhpDoc\ParamClosureThisTagValueNode($type, $parameterName, $description); - } - - private function parsePureUnlessCallableIsImpureTagValue(TokenIterator $tokens): Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode - { - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - return new Ast\PhpDoc\PureUnlessCallableIsImpureTagValueNode($parameterName, $description); - } - - private function parsePureUnlessParameterIsPassed(TokenIterator $tokens): Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode - { - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - return new Ast\PhpDoc\PureUnlessParameterIsPassedTagValueNode($parameterName, $description); - } - - private function parseVarTagValue(TokenIterator $tokens): Ast\PhpDoc\VarTagValueNode - { - $type = $this->typeParser->parse($tokens); - $variableName = $this->parseOptionalVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, $variableName === ''); - return new Ast\PhpDoc\VarTagValueNode($type, $variableName, $description); - } - - private function parseReturnTagValue(TokenIterator $tokens): Ast\PhpDoc\ReturnTagValueNode - { - $type = $this->typeParser->parse($tokens); - $description = $this->parseOptionalDescription($tokens, true); - return new Ast\PhpDoc\ReturnTagValueNode($type, $description); - } - - private function parseThrowsTagValue(TokenIterator $tokens): Ast\PhpDoc\ThrowsTagValueNode - { - $type = $this->typeParser->parse($tokens); - $description = $this->parseOptionalDescription($tokens, true); - return new Ast\PhpDoc\ThrowsTagValueNode($type, $description); - } - - private function parseMixinTagValue(TokenIterator $tokens): Ast\PhpDoc\MixinTagValueNode - { - $type = $this->typeParser->parse($tokens); - $description = $this->parseOptionalDescription($tokens, true); - return new Ast\PhpDoc\MixinTagValueNode($type, $description); - } - - private function parseRequireExtendsTagValue(TokenIterator $tokens): Ast\PhpDoc\RequireExtendsTagValueNode - { - $type = $this->typeParser->parse($tokens); - $description = $this->parseOptionalDescription($tokens, true); - return new Ast\PhpDoc\RequireExtendsTagValueNode($type, $description); - } - - private function parseRequireImplementsTagValue(TokenIterator $tokens): Ast\PhpDoc\RequireImplementsTagValueNode - { - $type = $this->typeParser->parse($tokens); - $description = $this->parseOptionalDescription($tokens, true); - return new Ast\PhpDoc\RequireImplementsTagValueNode($type, $description); - } - - private function parseSealedTagValue(TokenIterator $tokens): Ast\PhpDoc\SealedTagValueNode - { - $type = $this->typeParser->parse($tokens); - $description = $this->parseOptionalDescription($tokens, true); - return new Ast\PhpDoc\SealedTagValueNode($type, $description); - } - - private function parseDeprecatedTagValue(TokenIterator $tokens): Ast\PhpDoc\DeprecatedTagValueNode - { - $description = $this->parseOptionalDescription($tokens, false); - return new Ast\PhpDoc\DeprecatedTagValueNode($description); - } - - private function parsePropertyTagValue(TokenIterator $tokens): Ast\PhpDoc\PropertyTagValueNode - { - $type = $this->typeParser->parse($tokens); - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - return new Ast\PhpDoc\PropertyTagValueNode($type, $parameterName, $description); - } - - private function parseMethodTagValue(TokenIterator $tokens): Ast\PhpDoc\MethodTagValueNode - { - $staticKeywordOrReturnTypeOrMethodName = $this->typeParser->parse($tokens); - - if ($staticKeywordOrReturnTypeOrMethodName instanceof Ast\Type\IdentifierTypeNode && $staticKeywordOrReturnTypeOrMethodName->name === 'static') { - $isStatic = true; - $returnTypeOrMethodName = $this->typeParser->parse($tokens); - - } else { - $isStatic = false; - $returnTypeOrMethodName = $staticKeywordOrReturnTypeOrMethodName; - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) { - $returnType = $returnTypeOrMethodName; - $methodName = $tokens->currentTokenValue(); - $tokens->next(); - - } elseif ($returnTypeOrMethodName instanceof Ast\Type\IdentifierTypeNode) { - $returnType = $isStatic ? $staticKeywordOrReturnTypeOrMethodName : null; - $methodName = $returnTypeOrMethodName->name; - $isStatic = false; - - } else { - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); // will throw exception - exit; - } - - $templateTypes = []; - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) { - do { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - $templateTypes[] = $this->enrichWithAttributes( - $tokens, - $this->typeParser->parseTemplateTagValue($tokens), - $startLine, - $startIndex, - ); - } while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)); - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET); - } - - $parameters = []; - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES); - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) { - $parameters[] = $this->parseMethodTagValueParameter($tokens); - while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { - $parameters[] = $this->parseMethodTagValueParameter($tokens); - } - } - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); - - $description = $this->parseOptionalDescription($tokens, false); - return new Ast\PhpDoc\MethodTagValueNode($isStatic, $returnType, $methodName, $parameters, $description, $templateTypes); - } - - private function parseMethodTagValueParameter(TokenIterator $tokens): Ast\PhpDoc\MethodTagValueParameterNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - switch ($tokens->currentTokenType()) { - case Lexer::TOKEN_IDENTIFIER: - case Lexer::TOKEN_OPEN_PARENTHESES: - case Lexer::TOKEN_NULLABLE: - $parameterType = $this->typeParser->parse($tokens); - break; - - default: - $parameterType = null; - } - - $isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE); - $isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC); - - $parameterName = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL)) { - $defaultValue = $this->constantExprParser->parse($tokens); - - } else { - $defaultValue = null; - } - - return $this->enrichWithAttributes( - $tokens, - new Ast\PhpDoc\MethodTagValueParameterNode($parameterType, $isReference, $isVariadic, $parameterName, $defaultValue), - $startLine, - $startIndex, - ); - } - - private function parseExtendsTagValue(string $tagName, TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - $baseType = new IdentifierTypeNode($tokens->currentTokenValue()); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - $type = $this->typeParser->parseGeneric( - $tokens, - $this->typeParser->enrichWithAttributes($tokens, $baseType, $startLine, $startIndex), - ); - - $description = $this->parseOptionalDescription($tokens, true); - - switch ($tagName) { - case '@extends': - return new Ast\PhpDoc\ExtendsTagValueNode($type, $description); - case '@implements': - return new Ast\PhpDoc\ImplementsTagValueNode($type, $description); - case '@use': - return new Ast\PhpDoc\UsesTagValueNode($type, $description); - } - - throw new ShouldNotHappenException(); - } - - private function parseTypeAliasTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeAliasTagValueNode - { - $alias = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - // support phan-type/psalm-type syntax - $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL); - - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - try { - $type = $this->typeParser->parse($tokens); - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) { - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) { - throw new ParserException( - $tokens->currentTokenValue(), - $tokens->currentTokenType(), - $tokens->currentTokenOffset(), - Lexer::TOKEN_PHPDOC_EOL, - null, - $tokens->currentTokenLine(), - ); - } - } - - return new Ast\PhpDoc\TypeAliasTagValueNode($alias, $type); - } catch (ParserException $e) { - $this->parseOptionalDescription($tokens, false); - return new Ast\PhpDoc\TypeAliasTagValueNode( - $alias, - $this->enrichWithAttributes($tokens, new Ast\Type\InvalidTypeNode($e), $startLine, $startIndex), - ); - } - } - - private function parseTypeAliasImportTagValue(TokenIterator $tokens): Ast\PhpDoc\TypeAliasImportTagValueNode + public function parseTag(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagNode { - $importedAlias = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - $tokens->consumeTokenValue(Lexer::TOKEN_IDENTIFIER, 'from'); - - $identifierStartLine = $tokens->currentTokenLine(); - $identifierStartIndex = $tokens->currentTokenIndex(); - $importedFrom = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - $importedFromType = $this->enrichWithAttributes( + /** @var Ast\PhpDoc\PhpDocTagNode */ + return $this->builder->read( $tokens, - new IdentifierTypeNode($importedFrom), - $identifierStartLine, - $identifierStartIndex, + $tokens->isCurrentTokenType(Lexer::TOKEN_DOCTRINE_TAG) || !isset(Phplrt\TokenStream::TAGS[$tokens->currentTokenValue()]) + ? 'UnreadTagChild' + : 'PhpDocChild', ); - - $importedAs = null; - if ($tokens->tryConsumeTokenValue('as')) { - $importedAs = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - } - - return new Ast\PhpDoc\TypeAliasImportTagValueNode($importedAlias, $importedFromType, $importedAs); } /** - * @return Ast\PhpDoc\AssertTagValueNode|Ast\PhpDoc\AssertTagPropertyValueNode|Ast\PhpDoc\AssertTagMethodValueNode + * Reads the value of the given tag at the position the iterator is at. */ - private function parseAssertTagValue(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagValueNode - { - $isNegated = $tokens->tryConsumeTokenType(Lexer::TOKEN_NEGATED); - $isEquality = $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL); - $type = $this->typeParser->parse($tokens); - $parameter = $this->parseAssertParameter($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - if (array_key_exists('method', $parameter)) { - return new Ast\PhpDoc\AssertTagMethodValueNode($type, $parameter['parameter'], $parameter['method'], $isNegated, $description, $isEquality); - } elseif (array_key_exists('property', $parameter)) { - return new Ast\PhpDoc\AssertTagPropertyValueNode($type, $parameter['parameter'], $parameter['property'], $isNegated, $description, $isEquality); - } - - return new Ast\PhpDoc\AssertTagValueNode($type, $parameter['parameter'], $isNegated, $description, $isEquality); - } - - /** - * @return array{parameter: string}|array{parameter: string, property: string}|array{parameter: string, method: string} - */ - private function parseAssertParameter(TokenIterator $tokens): array - { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_THIS_VARIABLE)) { - $parameter = '$this'; - $tokens->next(); - } else { - $parameter = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_ARROW)) { - $tokens->consumeTokenType(Lexer::TOKEN_ARROW); - - $propertyOrMethod = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); - - return ['parameter' => $parameter, 'method' => $propertyOrMethod]; - } - - return ['parameter' => $parameter, 'property' => $propertyOrMethod]; - } - - return ['parameter' => $parameter]; - } - - private function parseSelfOutTagValue(TokenIterator $tokens): Ast\PhpDoc\SelfOutTagValueNode - { - $type = $this->typeParser->parse($tokens); - $description = $this->parseOptionalDescription($tokens, true); - - return new Ast\PhpDoc\SelfOutTagValueNode($type, $description); - } - - private function parseParamOutTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamOutTagValueNode - { - $type = $this->typeParser->parse($tokens); - $parameterName = $this->parseRequiredVariableName($tokens); - $description = $this->parseOptionalDescription($tokens, false); - - return new Ast\PhpDoc\ParamOutTagValueNode($type, $parameterName, $description); - } - - private function parseOptionalVariableName(TokenIterator $tokens): string - { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) { - $parameterName = $tokens->currentTokenValue(); - $tokens->next(); - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_THIS_VARIABLE)) { - $parameterName = '$this'; - $tokens->next(); - - } else { - $parameterName = ''; - } - - return $parameterName; - } - - private function parseRequiredVariableName(TokenIterator $tokens): string - { - $parameterName = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); - - return $parameterName; - } - - /** - * @param bool $limitStartToken true should be used when the description immediately follows a parsed type - */ - private function parseOptionalDescription(TokenIterator $tokens, bool $limitStartToken): string + public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\PhpDocTagValueNode { - if ($limitStartToken) { - foreach (self::DISALLOWED_DESCRIPTION_START_TOKENS as $disallowedStartToken) { - if (!$tokens->isCurrentTokenType($disallowedStartToken)) { - continue; - } - - $tokens->consumeTokenType(Lexer::TOKEN_OTHER); // will throw exception - } - - if ( - !$tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END) - && !$tokens->isPrecededByHorizontalWhitespace() - ) { - $tokens->consumeTokenType(Lexer::TOKEN_HORIZONTAL_WS); // will throw exception - } - } + /** @var Ast\PhpDoc\PhpDocTagNode $node */ + $node = $this->builder->read( + $tokens, + isset(Phplrt\TokenStream::TAGS[$tag]) ? 'PhpDocChild' : 'UnreadTagChild', + $tag, + ); - return $this->parseText($tokens)->text; + return $node->value; } } diff --git a/src/Parser/Phplrt/Fragment.php b/src/Parser/Phplrt/Fragment.php new file mode 100644 index 00000000..2d517305 --- /dev/null +++ b/src/Parser/Phplrt/Fragment.php @@ -0,0 +1,50 @@ +kind = $kind; + $this->end = $end; + $this->a = $a; + $this->b = $b; + $this->c = $c; + } + +} diff --git a/src/Parser/Phplrt/Token.php b/src/Parser/Phplrt/Token.php new file mode 100644 index 00000000..2627c7fe --- /dev/null +++ b/src/Parser/Phplrt/Token.php @@ -0,0 +1,30 @@ +id = $id; + $this->value = $value; + $this->offset = $offset; + } + +} diff --git a/src/Parser/Phplrt/TokenStream.php b/src/Parser/Phplrt/TokenStream.php new file mode 100644 index 00000000..8698dd8c --- /dev/null +++ b/src/Parser/Phplrt/TokenStream.php @@ -0,0 +1,644 @@ + 'T_KEYWORD_IS', + 'not' => 'T_KEYWORD_NOT', + 'of' => 'T_KEYWORD_OF', + 'as' => 'T_KEYWORD_AS', + 'super' => 'T_KEYWORD_SUPER', + 'static' => 'T_KEYWORD_STATIC', + 'from' => 'T_KEYWORD_FROM', + 'covariant' => 'T_KEYWORD_COVARIANT', + 'contravariant' => 'T_KEYWORD_CONTRAVARIANT', + 'array' => 'T_KEYWORD_ARRAY', + 'list' => 'T_KEYWORD_LIST', + 'non-empty-array' => 'T_KEYWORD_NON_EMPTY_ARRAY', + 'non-empty-list' => 'T_KEYWORD_NON_EMPTY_LIST', + 'object' => 'T_KEYWORD_OBJECT', + 'true' => 'T_KEYWORD_TRUE', + 'false' => 'T_KEYWORD_FALSE', + 'null' => 'T_KEYWORD_NULL', + ]; + + /** + * The words a constant expression compares without regard to case. + */ + private const KEYWORDS_ANY_CASE = [ + 'true' => 'T_KEYWORD_TRUE', + 'false' => 'T_KEYWORD_FALSE', + 'null' => 'T_KEYWORD_NULL', + 'array' => 'T_KEYWORD_ARRAY_ANY_CASE', + ]; + + /** + * The tags whose value a rule of its own reads, told apart by the whole + * name written. + */ + public const TAGS = [ + '@param' => 'T_TAG_PARAM', + '@phpstan-param' => 'T_TAG_PARAM', + '@psalm-param' => 'T_TAG_PARAM', + '@phan-param' => 'T_TAG_PARAM', + '@param-immediately-invoked-callable' => 'T_TAG_PARAM_IMMEDIATELY_INVOKED_CALLABLE', + '@phpstan-param-immediately-invoked-callable' => 'T_TAG_PARAM_IMMEDIATELY_INVOKED_CALLABLE', + '@param-later-invoked-callable' => 'T_TAG_PARAM_LATER_INVOKED_CALLABLE', + '@phpstan-param-later-invoked-callable' => 'T_TAG_PARAM_LATER_INVOKED_CALLABLE', + '@param-closure-this' => 'T_TAG_PARAM_CLOSURE_THIS', + '@phpstan-param-closure-this' => 'T_TAG_PARAM_CLOSURE_THIS', + '@pure-unless-callable-is-impure' => 'T_TAG_PURE_UNLESS_CALLABLE_IS_IMPURE', + '@phpstan-pure-unless-callable-is-impure' => 'T_TAG_PURE_UNLESS_CALLABLE_IS_IMPURE', + '@pure-unless-parameter-passed' => 'T_TAG_PURE_UNLESS_PARAMETER_PASSED', + '@phpstan-pure-unless-parameter-passed' => 'T_TAG_PURE_UNLESS_PARAMETER_PASSED', + '@var' => 'T_TAG_VAR', + '@phpstan-var' => 'T_TAG_VAR', + '@psalm-var' => 'T_TAG_VAR', + '@phan-var' => 'T_TAG_VAR', + '@return' => 'T_TAG_RETURN', + '@phpstan-return' => 'T_TAG_RETURN', + '@psalm-return' => 'T_TAG_RETURN', + '@phan-return' => 'T_TAG_RETURN', + '@phan-real-return' => 'T_TAG_RETURN', + '@throws' => 'T_TAG_THROWS', + '@phpstan-throws' => 'T_TAG_THROWS', + '@mixin' => 'T_TAG_MIXIN', + '@phan-mixin' => 'T_TAG_MIXIN', + '@psalm-require-extends' => 'T_TAG_REQUIRE_EXTENDS', + '@phpstan-require-extends' => 'T_TAG_REQUIRE_EXTENDS', + '@psalm-require-implements' => 'T_TAG_REQUIRE_IMPLEMENTS', + '@phpstan-require-implements' => 'T_TAG_REQUIRE_IMPLEMENTS', + '@psalm-inheritors' => 'T_TAG_SEALED', + '@phpstan-sealed' => 'T_TAG_SEALED', + '@deprecated' => 'T_TAG_DEPRECATED', + '@property' => 'T_TAG_PROPERTY', + '@property-read' => 'T_TAG_PROPERTY', + '@property-write' => 'T_TAG_PROPERTY', + '@phpstan-property' => 'T_TAG_PROPERTY', + '@phpstan-property-read' => 'T_TAG_PROPERTY', + '@phpstan-property-write' => 'T_TAG_PROPERTY', + '@psalm-property' => 'T_TAG_PROPERTY', + '@psalm-property-read' => 'T_TAG_PROPERTY', + '@psalm-property-write' => 'T_TAG_PROPERTY', + '@phan-property' => 'T_TAG_PROPERTY', + '@phan-property-read' => 'T_TAG_PROPERTY', + '@phan-property-write' => 'T_TAG_PROPERTY', + '@method' => 'T_TAG_METHOD', + '@phpstan-method' => 'T_TAG_METHOD', + '@psalm-method' => 'T_TAG_METHOD', + '@phan-method' => 'T_TAG_METHOD', + '@template' => 'T_TAG_TEMPLATE', + '@phpstan-template' => 'T_TAG_TEMPLATE', + '@psalm-template' => 'T_TAG_TEMPLATE', + '@phan-template' => 'T_TAG_TEMPLATE', + '@template-covariant' => 'T_TAG_TEMPLATE', + '@phpstan-template-covariant' => 'T_TAG_TEMPLATE', + '@psalm-template-covariant' => 'T_TAG_TEMPLATE', + '@template-contravariant' => 'T_TAG_TEMPLATE', + '@phpstan-template-contravariant' => 'T_TAG_TEMPLATE', + '@psalm-template-contravariant' => 'T_TAG_TEMPLATE', + '@extends' => 'T_TAG_EXTENDS', + '@phpstan-extends' => 'T_TAG_EXTENDS', + '@phan-extends' => 'T_TAG_EXTENDS', + '@phan-inherits' => 'T_TAG_EXTENDS', + '@template-extends' => 'T_TAG_EXTENDS', + '@implements' => 'T_TAG_IMPLEMENTS', + '@phpstan-implements' => 'T_TAG_IMPLEMENTS', + '@template-implements' => 'T_TAG_IMPLEMENTS', + '@use' => 'T_TAG_USE', + '@phpstan-use' => 'T_TAG_USE', + '@template-use' => 'T_TAG_USE', + '@phpstan-type' => 'T_TAG_TYPE_ALIAS', + '@psalm-type' => 'T_TAG_TYPE_ALIAS', + '@phan-type' => 'T_TAG_TYPE_ALIAS', + '@phpstan-import-type' => 'T_TAG_TYPE_ALIAS_IMPORT', + '@psalm-import-type' => 'T_TAG_TYPE_ALIAS_IMPORT', + '@phpstan-assert' => 'T_TAG_ASSERT', + '@phpstan-assert-if-true' => 'T_TAG_ASSERT', + '@phpstan-assert-if-false' => 'T_TAG_ASSERT', + '@psalm-assert' => 'T_TAG_ASSERT', + '@psalm-assert-if-true' => 'T_TAG_ASSERT', + '@psalm-assert-if-false' => 'T_TAG_ASSERT', + '@phan-assert' => 'T_TAG_ASSERT', + '@phan-assert-if-true' => 'T_TAG_ASSERT', + '@phan-assert-if-false' => 'T_TAG_ASSERT', + '@phpstan-this-out' => 'T_TAG_SELF_OUT', + '@phpstan-self-out' => 'T_TAG_SELF_OUT', + '@psalm-this-out' => 'T_TAG_SELF_OUT', + '@psalm-self-out' => 'T_TAG_SELF_OUT', + '@param-out' => 'T_TAG_PARAM_OUT', + '@phpstan-param-out' => 'T_TAG_PARAM_OUT', + '@psalm-param-out' => 'T_TAG_PARAM_OUT', + ]; + + /** + * The tokens of the lexer the grammar reads under a name of their own. + */ + private const TYPES = [ + Lexer::TOKEN_REFERENCE => 'T_REFERENCE', + Lexer::TOKEN_UNION => 'T_UNION', + Lexer::TOKEN_INTERSECTION => 'T_INTERSECTION', + Lexer::TOKEN_NULLABLE => 'T_NULLABLE', + Lexer::TOKEN_NEGATED => 'T_NEGATED', + Lexer::TOKEN_CLOSE_PARENTHESES => 'T_CLOSE_PARENTHESES', + Lexer::TOKEN_CLOSE_ANGLE_BRACKET => 'T_CLOSE_ANGLE_BRACKET', + Lexer::TOKEN_CLOSE_SQUARE_BRACKET => 'T_CLOSE_SQUARE_BRACKET', + Lexer::TOKEN_CLOSE_CURLY_BRACKET => 'T_CLOSE_CURLY_BRACKET', + Lexer::TOKEN_COMMA => 'T_COMMA', + Lexer::TOKEN_COMMENT => 'T_COMMENT', + Lexer::TOKEN_VARIADIC => 'T_VARIADIC', + Lexer::TOKEN_DOUBLE_COLON => 'T_DOUBLE_COLON', + Lexer::TOKEN_DOUBLE_ARROW => 'T_DOUBLE_ARROW', + Lexer::TOKEN_ARROW => 'T_ARROW', + Lexer::TOKEN_EQUAL => 'T_EQUAL', + Lexer::TOKEN_COLON => 'T_COLON', + Lexer::TOKEN_FLOAT => 'T_FLOAT', + Lexer::TOKEN_INTEGER => 'T_INTEGER', + Lexer::TOKEN_SINGLE_QUOTED_STRING => 'T_SINGLE_QUOTED_STRING', + Lexer::TOKEN_DOUBLE_QUOTED_STRING => 'T_DOUBLE_QUOTED_STRING', + Lexer::TOKEN_DOCTRINE_ANNOTATION_STRING => 'T_DOCTRINE_ANNOTATION_STRING', + Lexer::TOKEN_THIS_VARIABLE => 'T_THIS_VARIABLE', + Lexer::TOKEN_VARIABLE => 'T_VARIABLE', + Lexer::TOKEN_OPEN_PHPDOC => 'T_OPEN_PHPDOC', + Lexer::TOKEN_CLOSE_PHPDOC => 'T_CLOSE_PHPDOC', + Lexer::TOKEN_PHPDOC_EOL => 'T_PHPDOC_EOL', + Lexer::TOKEN_OTHER => 'T_OTHER', + ]; + + /** where the end of the input returned by {@see tokenize()} holds the identifiers of the stream */ + public const STREAM_IDS = 3; + + /** where it holds the index of the token each of them stands for */ + public const STREAM_INDEXES = 4; + + /** @var array */ + private static ?array $types = null; + + /** @var array the token each token preceded by whitespace is read as */ + private static array $whitespaceVariants; + + private static int $eol; + + /** @var array */ + private static array $keywords; + + /** @var array */ + + /** @var array */ + private static array $tags; + + private static int $identifier; + + private static int $phpDocTag; + + private static int $phpDocTagWs; + + private static int $doctrineTag; + + private static int $doctrineTagWs; + + private static int $openCurly; + + private static int $openCurlyWs; + + private static int $openParentheses; + + private static int $openParenthesesWs; + + private static int $openSquare; + + private static int $openSquareWs; + + private static int $wildcard; + + private static int $wildcardWs; + + private static int $openAngle; + + private static int $openAngleHtml; + + /** + * Appends the given tokens of the lexer to the stream the parser reads, one + * per token it reads: the whitespace is left out, while the index of the + * token of the lexer each of them stands for is kept along. The stream + * ends with -1, the end of the input. + * + * @param list $tokens + * @param int $start the index of the first token to read + * @param array $ids the identifier of each token of the stream + * @param array $indexes the index of each token of the stream + * @param-out array $ids + * @param-out array $indexes + */ + public static function create(array $tokens, int $start, array &$ids, array &$indexes): void + { + if (self::$types === null) { + self::initialize(); + } + + $types = self::$types; + $keywords = self::$keywords; + $identifier = self::$identifier; + + $count = count($tokens); + + for ($index = $start; $index < $count; $index++) { + $token = $tokens[$index]; + $type = $token[1]; + + // the most common tokens first + if ($type === Lexer::TOKEN_HORIZONTAL_WS) { + continue; + } + + if ($type === Lexer::TOKEN_IDENTIFIER) { + $ids[] = $keywords[$token[0]] ?? $identifier; + $indexes[] = $index; + continue; + } + + if (isset($types[$type])) { + $ids[] = $types[$type]; + $indexes[] = $index; + continue; + } + + $value = $token[0]; + + switch ($type) { + case Lexer::TOKEN_PHPDOC_TAG: + $id = self::$tags[$value] ?? (self::isPrecededByWhitespace($tokens, $index) ? self::$phpDocTagWs : self::$phpDocTag); + break; + + case Lexer::TOKEN_DOCTRINE_TAG: + $id = self::isPrecededByWhitespace($tokens, $index) ? self::$doctrineTagWs : self::$doctrineTag; + break; + + case Lexer::TOKEN_OPEN_CURLY_BRACKET: + $id = self::isPrecededByWhitespace($tokens, $index) ? self::$openCurlyWs : self::$openCurly; + break; + + case Lexer::TOKEN_OPEN_PARENTHESES: + $id = self::isPrecededByWhitespace($tokens, $index) ? self::$openParenthesesWs : self::$openParentheses; + break; + + case Lexer::TOKEN_OPEN_SQUARE_BRACKET: + $id = self::isPrecededByWhitespace($tokens, $index) ? self::$openSquareWs : self::$openSquare; + break; + + case Lexer::TOKEN_WILDCARD: + $id = ($tokens[$index + 1][1] ?? -1) === Lexer::TOKEN_HORIZONTAL_WS ? self::$wildcardWs : self::$wildcard; + break; + + case Lexer::TOKEN_OPEN_ANGLE_BRACKET: + $id = self::isHtml($tokens, $index, $count) ? self::$openAngleHtml : self::$openAngle; + break; + + default: + // Lexer::TOKEN_END + $ids[] = -1; + $indexes[] = $index; + continue 2; + } + + $ids[] = $id; + $indexes[] = $index; + } + } + + /** + * Reads the given PHPDoc into the tokens of {@see Lexer}, and the stream of + * {@see create()} along with them, in one pass. + * + * The stream is handed over in the last token, the end of the input, as + * its {@see STREAM_IDS} and {@see STREAM_INDEXES}: the tokens are all + * {@see Lexer::tokenize()} returns, and the parser is given nothing else. + * See {@see fromTokens()}. + * + * @return list, 4?: list}> + */ + public static function tokenize(string $s): array + { + if (self::$types === null) { + self::initialize(); + } + + // PREG_PATTERN_ORDER, not PREG_SET_ORDER: it collects the whole PHPDoc + // into two arrays instead of allocating one array per token. This only + // pays off while the token patterns have no capturing groups, because + // every group would get an array of its own, one entry per token. + preg_match_all(GeneratedParser::LEXER_PATTERN, $s, $matches); + + $values = $matches[0]; + // no MARK at all when nothing has been matched + $marks = $matches['MARK'] ?? []; + + $lexerTypes = GeneratedParser::LEXER_TYPES; + $keywords = self::$keywords; + $tags = self::$tags; + $identifier = self::$identifier; + $phpDocTag = self::$phpDocTag; + $whitespaceVariants = self::$whitespaceVariants; + $wildcard = self::$wildcard; + $openAngle = self::$openAngle; + $eol = self::$eol; + + $tokens = []; + $ids = []; + $indexes = []; + $angles = []; + $line = 1; + $afterWhitespace = false; + + foreach ($values as $index => $value) { + /** @var key-of $id every mark of the pattern is a token it reads */ + $id = (int) $marks[$index]; + + if ($id === 0) { + // T_HORIZONTAL_WS, the first token of the grammar, which the + // stream leaves out + $tokens[] = [$value, Lexer::TOKEN_HORIZONTAL_WS, $line]; + $afterWhitespace = true; + continue; + } + + $tokens[] = [$value, $lexerTypes[$id], $line]; + + if ($id === $identifier) { + $id = $keywords[$value] ?? $identifier; + } elseif (isset($whitespaceVariants[$id])) { + if ($id === $phpDocTag && isset($tags[$value])) { + $id = $tags[$value]; + } elseif ($afterWhitespace) { + $id = $whitespaceVariants[$id]; + } + } elseif ($id === $wildcard) { + if (($marks[$index + 1] ?? null) === '0') { + $id = self::$wildcardWs; + } + } elseif ($id === $openAngle) { + $angles[] = count($ids); + } elseif ($id === $eol) { + $line++; + } + + $ids[] = $id; + $indexes[] = $index; + $afterWhitespace = false; + } + + $count = count($tokens); + $closable = []; + foreach ($angles as $position) { + // A tag is only closed by an end tag written somewhere in the + // PHPDoc, which is looked for once per name rather than once per + // "<": every "list" would otherwise be one walk to the end + $name = $tokens[$indexes[$position + 1] ?? $count][0] ?? ''; + $closable[$name] ??= $name !== '' && strpos($s, '/' . $name . '>') !== false; + if (!$closable[$name] || !self::isHtml($tokens, $indexes[$position], $count)) { + continue; + } + + $ids[$position] = self::$openAngleHtml; + } + + $ids[] = -1; + $indexes[] = $count; + $tokens[] = ['', Lexer::TOKEN_END, $line, $ids, $indexes]; + + return $tokens; + } + + /** + * The stream of the given tokens from the given index on, in case the + * tokens are the ones {@see tokenize()} has returned, or null in case they + * have to be read by {@see create()}. + * + * Whatever has been done to the tokens since, other than reading them, + * leaves the stream describing other tokens. Of all that may be done, the + * stream only tells apart the tokens being cut off or added to. + * + * @param list, 4?: list}> $tokens + * @return array{array, list}|null + */ + public static function fromTokens(array $tokens, int $start): ?array + { + $last = count($tokens) - 1; + $end = $tokens[$last] ?? null; + if (!isset($end[self::STREAM_INDEXES])) { + return null; + } + + $ids = $end[self::STREAM_IDS] ?? []; + $indexes = $end[self::STREAM_INDEXES]; + $length = count($indexes); + if ($indexes[$length - 1] !== $last) { + return null; + } + + if ($start <= $indexes[0]) { + return [$ids, $indexes]; + } + + // the first token of the stream at the given index or after it + $low = 0; + $high = $length - 1; + while ($low < $high) { + $middle = $low + $high >> 1; + if ($indexes[$middle] < $start) { + $low = $middle + 1; + } else { + $high = $middle; + } + } + + return [array_slice($ids, $low), array_slice($indexes, $low)]; + } + + /** + * The identifier of the token a tag written nowhere in the tokens is read as. + */ + public static function tagId(string $value): int + { + if (self::$types === null) { + self::initialize(); + } + + return self::$tags[$value] ?? self::$phpDocTag; + } + + private static function initialize(): void + { + $ids = GeneratedParser::TOKENS; + + $types = []; + foreach (self::TYPES as $type => $name) { + $types[$type] = $ids[$name]; + } + + // A keyword written in any case is looked up along with the others, + // every way of writing it in, since only a few of them are + $keywords = []; + foreach (self::KEYWORDS_ANY_CASE as $value => $name) { + foreach (self::caseVariants($value) as $variant) { + $keywords[$variant] = $ids[$name]; + } + } + + foreach (self::KEYWORDS as $value => $name) { + $keywords[$value] = $ids[$name]; + } + self::$keywords = $keywords; + + $tags = []; + foreach (self::TAGS as $value => $name) { + $tags[$value] = $ids[$name]; + } + self::$tags = $tags; + + self::$identifier = $ids['T_IDENTIFIER']; + self::$phpDocTag = $ids['T_PHPDOC_TAG']; + self::$phpDocTagWs = $ids['T_PHPDOC_TAG_WS']; + self::$doctrineTag = $ids['T_DOCTRINE_TAG']; + self::$doctrineTagWs = $ids['T_DOCTRINE_TAG_WS']; + self::$openCurly = $ids['T_OPEN_CURLY_BRACKET']; + self::$openCurlyWs = $ids['T_OPEN_CURLY_BRACKET_WS']; + self::$openParentheses = $ids['T_OPEN_PARENTHESES']; + self::$openParenthesesWs = $ids['T_OPEN_PARENTHESES_WS']; + self::$openSquare = $ids['T_OPEN_SQUARE_BRACKET']; + self::$openSquareWs = $ids['T_OPEN_SQUARE_BRACKET_WS']; + self::$wildcard = $ids['T_WILDCARD']; + self::$wildcardWs = $ids['T_WILDCARD_WS']; + self::$openAngle = $ids['T_OPEN_ANGLE_BRACKET']; + self::$openAngleHtml = $ids['T_OPEN_ANGLE_BRACKET_HTML']; + self::$eol = $ids['T_PHPDOC_EOL']; + self::$whitespaceVariants = [ + self::$phpDocTag => self::$phpDocTagWs, + self::$doctrineTag => self::$doctrineTagWs, + self::$openCurly => self::$openCurlyWs, + self::$openParentheses => self::$openParenthesesWs, + self::$openSquare => self::$openSquareWs, + ]; + + self::$types = $types; + } + + /** + * @return list + */ + private static function caseVariants(string $value): array + { + $variants = ['']; + for ($i = 0, $length = strlen($value); $i < $length; $i++) { + $next = []; + foreach ($variants as $variant) { + $next[] = $variant . strtolower($value[$i]); + $next[] = $variant . strtoupper($value[$i]); + } + $variants = $next; + } + + return $variants; + } + + /** + * @param list $tokens + */ + private static function isPrecededByWhitespace(array $tokens, int $index): bool + { + return ($tokens[$index - 1][1] ?? -1) === Lexer::TOKEN_HORIZONTAL_WS; + } + + /** + * Whether the "<" at the given position opens what looks like an HTML tag: + * a "" with a matching "" somewhere after it. + * + * @param list $tokens + */ + private static function isHtml(array $tokens, int $index, int $count): bool + { + $index = self::skipWhitespace($tokens, $index + 1, $count); + if ($index >= $count || $tokens[$index][1] !== Lexer::TOKEN_IDENTIFIER) { + return false; + } + + $name = $tokens[$index][0]; + + $index = self::skipWhitespace($tokens, $index + 1, $count); + if ($index >= $count || $tokens[$index][1] !== Lexer::TOKEN_CLOSE_ANGLE_BRACKET) { + return false; + } + + $index = self::skipWhitespace($tokens, $index + 1, $count); + + $endTag = ''; + $length = strlen($endTag); + + while ($index < $count && $tokens[$index][1] !== Lexer::TOKEN_END) { + if ($tokens[$index][1] === Lexer::TOKEN_OPEN_ANGLE_BRACKET) { + $index = self::skipWhitespace($tokens, $index + 1, $count); + + if ($index < $count && strpos($tokens[$index][0], '/' . $name . '>') !== false) { + return true; + } + } + + if ($index < $count) { + $value = $tokens[$index][0]; + + if (strlen($value) >= $length && substr_compare($value, $endTag, -$length) === 0) { + return true; + } + } + + $index = self::skipWhitespace($tokens, $index + 1, $count); + } + + return false; + } + + /** + * @param list $tokens + */ + private static function skipWhitespace(array $tokens, int $index, int $count): int + { + while ($index < $count && $tokens[$index][1] === Lexer::TOKEN_HORIZONTAL_WS) { + $index++; + } + + return $index; + } + +} diff --git a/src/Parser/TokenIterator.php b/src/Parser/TokenIterator.php index 043639f1..3b99a7ac 100644 --- a/src/Parser/TokenIterator.php +++ b/src/Parser/TokenIterator.php @@ -300,6 +300,34 @@ public function removeEndOfLineFromSkippedTokens(): void $this->skippedTokenTypes = [Lexer::TOKEN_HORIZONTAL_WS]; } + /** + * Moves the iterator to the given token, which the parsers do once they + * have read everything up to it. + * + * @internal + */ + public function setCurrentTokenIndex(int $index): void + { + $this->index = $index; + $this->skipIrrelevantTokens(); + } + + /** + * @internal + */ + public function detectNewlineOf(string $endOfLine): void + { + if ($this->newline !== null) { + return; + } + + if (substr($endOfLine, 0, 2) === "\r\n") { + $this->newline = "\r\n"; + } elseif (substr($endOfLine, 0, 1) === "\n") { + $this->newline = "\n"; + } + } + /** @phpstan-impure */ public function forwardToTheEnd(): void { diff --git a/src/Parser/TypeParser.php b/src/Parser/TypeParser.php index a2db4fce..a84282c3 100644 --- a/src/Parser/TypeParser.php +++ b/src/Parser/TypeParser.php @@ -2,1132 +2,36 @@ namespace PHPStan\PhpDocParser\Parser; -use LogicException; use PHPStan\PhpDocParser\Ast; -use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode; -use PHPStan\PhpDocParser\Lexer\Lexer; use PHPStan\PhpDocParser\ParserConfig; -use function in_array; -use function str_replace; -use function strlen; -use function strpos; -use function substr_compare; class TypeParser { - private ParserConfig $config; - - private ConstExprParser $constExprParser; + private AstBuilder $builder; + // The parsers it has always been given are not needed anymore, but it is + // constructed the way it always has been + // @phpstan-ignore constructor.unusedParameter public function __construct( ParserConfig $config, ConstExprParser $constExprParser ) { - $this->config = $config; - $this->constExprParser = $constExprParser; - } - - /** @phpstan-impure */ - public function parse(TokenIterator $tokens): Ast\Type\TypeNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_NULLABLE)) { - $type = $this->parseNullable($tokens); - - } else { - $type = $this->parseAtomic($tokens); - - $tokens->pushSavePoint(); - $tokens->skipNewLineTokensAndConsumeComments(); - - try { - $enrichedType = $this->enrichTypeOnUnionOrIntersection($tokens, $type); - - } catch (ParserException $parserException) { - $enrichedType = null; - } - - if ($enrichedType !== null) { - $type = $enrichedType; - $tokens->dropSavePoint(); - - } else { - $tokens->rollback(); - $type = $this->enrichTypeOnUnionOrIntersection($tokens, $type) ?? $type; - } - } - - return $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex); - } - - /** @phpstan-impure */ - private function enrichTypeOnUnionOrIntersection(TokenIterator $tokens, Ast\Type\TypeNode $type): ?Ast\Type\TypeNode - { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) { - return $this->parseUnion($tokens, $type); - - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) { - return $this->parseIntersection($tokens, $type); - } - - return null; - } - - /** - * @internal - * @template T of Ast\Node - * @param T $type - * @return T - */ - public function enrichWithAttributes(TokenIterator $tokens, Ast\Node $type, int $startLine, int $startIndex): Ast\Node - { - if ($this->config->useLinesAttributes) { - $type->setAttribute(Ast\Attribute::START_LINE, $startLine); - $type->setAttribute(Ast\Attribute::END_LINE, $tokens->currentTokenLine()); - } - - $comments = $tokens->flushComments(); - if ($this->config->useCommentsAttributes) { - $type->setAttribute(Ast\Attribute::COMMENTS, $comments); - } - - if ($this->config->useIndexAttributes) { - $type->setAttribute(Ast\Attribute::START_INDEX, $startIndex); - $type->setAttribute(Ast\Attribute::END_INDEX, $tokens->endIndexOfLastRelevantToken()); - } - - return $type; - } - - /** @phpstan-impure */ - private function subParse(TokenIterator $tokens): Ast\Type\TypeNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_NULLABLE)) { - $type = $this->parseNullable($tokens); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) { - $type = $this->parseConditionalForParameter($tokens, $tokens->currentTokenValue()); - - } else { - $type = $this->parseAtomic($tokens); - - if ($tokens->isCurrentTokenValue('is')) { - $type = $this->parseConditional($tokens, $type); - } else { - $tokens->skipNewLineTokensAndConsumeComments(); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) { - $type = $this->subParseUnion($tokens, $type); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) { - $type = $this->subParseIntersection($tokens, $type); - } - } - } - - return $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex); - } - - /** @phpstan-impure */ - private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { - $tokens->skipNewLineTokensAndConsumeComments(); - $type = $this->subParse($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $type); - } - - return $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex); - } - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_THIS_VARIABLE)) { - $type = $this->enrichWithAttributes($tokens, new Ast\Type\ThisTypeNode(), $startLine, $startIndex); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $type); - } - - return $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex); - } - - $currentTokenValue = $tokens->currentTokenValue(); - $tokens->pushSavePoint(); // because of ConstFetchNode - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_IDENTIFIER)) { - $type = $this->enrichWithAttributes($tokens, new Ast\Type\IdentifierTypeNode($currentTokenValue), $startLine, $startIndex); - - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON)) { - $tokens->dropSavePoint(); // because of ConstFetchNode - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) { - $tokens->pushSavePoint(); - - $isHtml = $this->isHtml($tokens); - $tokens->rollback(); - if ($isHtml) { - return $type; - } - - $origType = $type; - $type = $this->tryParseCallable($tokens, $type, true); - if ($type === $origType) { - $type = $this->parseGeneric($tokens, $type); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $type); - } - } - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { - $type = $this->tryParseCallable($tokens, $type, false); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $type); - - } elseif (in_array($type->name, [ - Ast\Type\ArrayShapeNode::KIND_ARRAY, - Ast\Type\ArrayShapeNode::KIND_LIST, - Ast\Type\ArrayShapeNode::KIND_NON_EMPTY_ARRAY, - Ast\Type\ArrayShapeNode::KIND_NON_EMPTY_LIST, - 'object', - ], true) && $tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET) && !$tokens->isPrecededByHorizontalWhitespace()) { - if ($type->name === 'object') { - $type = $this->parseObjectShape($tokens); - } else { - $type = $this->parseArrayShape($tokens, $type, $type->name); - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess( - $tokens, - $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex), - ); - } - } - - return $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex); - } else { - $tokens->rollback(); // because of ConstFetchNode - } - } else { - $tokens->dropSavePoint(); // because of ConstFetchNode - } - - $currentTokenValue = $tokens->currentTokenValue(); - $currentTokenType = $tokens->currentTokenType(); - $currentTokenOffset = $tokens->currentTokenOffset(); - $currentTokenLine = $tokens->currentTokenLine(); - - try { - $constExpr = $this->constExprParser->parse($tokens); - if ($constExpr instanceof Ast\ConstExpr\ConstExprArrayNode) { - throw new ParserException( - $currentTokenValue, - $currentTokenType, - $currentTokenOffset, - Lexer::TOKEN_IDENTIFIER, - null, - $currentTokenLine, - ); - } - - $type = $this->enrichWithAttributes( - $tokens, - new Ast\Type\ConstTypeNode($constExpr), - $startLine, - $startIndex, - ); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $type); - } - - return $type; - } catch (LogicException $e) { - throw new ParserException( - $currentTokenValue, - $currentTokenType, - $currentTokenOffset, - Lexer::TOKEN_IDENTIFIER, - null, - $currentTokenLine, - ); - } - } - - /** @phpstan-impure */ - private function parseUnion(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode - { - $types = [$type]; - - while ($tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)) { - $types[] = $this->parseAtomic($tokens); - $tokens->pushSavePoint(); - $tokens->skipNewLineTokensAndConsumeComments(); - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) { - $tokens->rollback(); - break; - } - - $tokens->dropSavePoint(); - } - - return new Ast\Type\UnionTypeNode($types); - } - - /** @phpstan-impure */ - private function subParseUnion(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode - { - $types = [$type]; - - while ($tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)) { - $tokens->skipNewLineTokensAndConsumeComments(); - $types[] = $this->parseAtomic($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - } - - return new Ast\Type\UnionTypeNode($types); - } - - /** @phpstan-impure */ - private function parseIntersection(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode - { - $types = [$type]; - - while ($tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) { - $types[] = $this->parseAtomic($tokens); - $tokens->pushSavePoint(); - $tokens->skipNewLineTokensAndConsumeComments(); - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) { - $tokens->rollback(); - break; - } - - $tokens->dropSavePoint(); - } - - return new Ast\Type\IntersectionTypeNode($types); - } - - /** @phpstan-impure */ - private function subParseIntersection(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode - { - $types = [$type]; - - while ($tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) { - $tokens->skipNewLineTokensAndConsumeComments(); - $types[] = $this->parseAtomic($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - } - - return new Ast\Type\IntersectionTypeNode($types); - } - - /** @phpstan-impure */ - private function parseConditional(TokenIterator $tokens, Ast\Type\TypeNode $subjectType): Ast\Type\TypeNode - { - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - $negated = false; - if ($tokens->isCurrentTokenValue('not')) { - $negated = true; - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - } - - $targetType = $this->parse($tokens); - - $tokens->skipNewLineTokensAndConsumeComments(); - $tokens->consumeTokenType(Lexer::TOKEN_NULLABLE); - $tokens->skipNewLineTokensAndConsumeComments(); - - $ifType = $this->parse($tokens); - - $tokens->skipNewLineTokensAndConsumeComments(); - $tokens->consumeTokenType(Lexer::TOKEN_COLON); - $tokens->skipNewLineTokensAndConsumeComments(); - - $elseType = $this->subParse($tokens); - - return new Ast\Type\ConditionalTypeNode($subjectType, $targetType, $ifType, $elseType, $negated); - } - - /** @phpstan-impure */ - private function parseConditionalForParameter(TokenIterator $tokens, string $parameterName): Ast\Type\TypeNode - { - $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); - $tokens->consumeTokenValue(Lexer::TOKEN_IDENTIFIER, 'is'); - - $negated = false; - if ($tokens->isCurrentTokenValue('not')) { - $negated = true; - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - } - - $targetType = $this->parse($tokens); - - $tokens->skipNewLineTokensAndConsumeComments(); - $tokens->consumeTokenType(Lexer::TOKEN_NULLABLE); - $tokens->skipNewLineTokensAndConsumeComments(); - - $ifType = $this->parse($tokens); - - $tokens->skipNewLineTokensAndConsumeComments(); - $tokens->consumeTokenType(Lexer::TOKEN_COLON); - $tokens->skipNewLineTokensAndConsumeComments(); - - $elseType = $this->subParse($tokens); - - return new Ast\Type\ConditionalTypeForParameterNode($parameterName, $targetType, $ifType, $elseType, $negated); - } - - /** @phpstan-impure */ - private function parseNullable(TokenIterator $tokens): Ast\Type\TypeNode - { - $tokens->consumeTokenType(Lexer::TOKEN_NULLABLE); - - $type = $this->parseAtomic($tokens); - - return new Ast\Type\NullableTypeNode($type); - } - - /** @phpstan-impure */ - public function isHtml(TokenIterator $tokens): bool - { - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET); - - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) { - return false; - } - - $htmlTagName = $tokens->currentTokenValue(); - - $tokens->next(); - - if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) { - return false; - } - - $endTag = ''; - $endTagSearchOffset = - strlen($endTag); - - while (!$tokens->isCurrentTokenType(Lexer::TOKEN_END)) { - if ( - ( - $tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET) - && strpos($tokens->currentTokenValue(), '/' . $htmlTagName . '>') !== false - ) - || substr_compare($tokens->currentTokenValue(), $endTag, $endTagSearchOffset) === 0 - ) { - return true; - } - - $tokens->next(); - } - - return false; - } - - /** @phpstan-impure */ - public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $baseType): Ast\Type\GenericTypeNode - { - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET); - $tokens->skipNewLineTokensAndConsumeComments(); - - $startLine = $baseType->getAttribute(Ast\Attribute::START_LINE); - $startIndex = $baseType->getAttribute(Ast\Attribute::START_INDEX); - $genericTypes = []; - $variances = []; - - $isFirst = true; - while ( - $isFirst - || $tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA) - ) { - $tokens->skipNewLineTokensAndConsumeComments(); - - // trailing comma case - if (!$isFirst && $tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) { - break; - } - $isFirst = false; - - [$genericTypes[], $variances[]] = $this->parseGenericTypeArgument($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - } - - $type = new Ast\Type\GenericTypeNode($baseType, $genericTypes, $variances); - if ($startLine !== null && $startIndex !== null) { - $type = $this->enrichWithAttributes($tokens, $type, $startLine, $startIndex); - } else { - // The comments read between the arguments have to be given away - // even where the node is not placed, or they would still be waiting - // for a node once the whole PHPDoc has been read - $tokens->flushComments(); - } - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET); - - return $type; + $this->builder = new AstBuilder($config); } /** - * @phpstan-impure - * @return array{Ast\Type\TypeNode, Ast\Type\GenericTypeNode::VARIANCE_*} - */ - public function parseGenericTypeArgument(TokenIterator $tokens): array - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_WILDCARD)) { - return [ - $this->enrichWithAttributes($tokens, new Ast\Type\IdentifierTypeNode('mixed'), $startLine, $startIndex), - Ast\Type\GenericTypeNode::VARIANCE_BIVARIANT, - ]; - } - - if ($tokens->tryConsumeTokenValue('contravariant')) { - $variance = Ast\Type\GenericTypeNode::VARIANCE_CONTRAVARIANT; - } elseif ($tokens->tryConsumeTokenValue('covariant')) { - $variance = Ast\Type\GenericTypeNode::VARIANCE_COVARIANT; - } else { - $variance = Ast\Type\GenericTypeNode::VARIANCE_INVARIANT; - } - - $type = $this->parse($tokens); - return [$type, $variance]; - } - - /** - * @throws ParserException - * @param ?callable(TokenIterator): string $parseDescription - */ - public function parseTemplateTagValue( - TokenIterator $tokens, - ?callable $parseDescription = null - ): TemplateTagValueNode - { - $name = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - $upperBound = $lowerBound = null; - - if ($tokens->tryConsumeTokenValue('of') || $tokens->tryConsumeTokenValue('as')) { - $upperBound = $this->parse($tokens); - } - - if ($tokens->tryConsumeTokenValue('super')) { - $lowerBound = $this->parse($tokens); - } - - if ($tokens->tryConsumeTokenValue('=')) { - $default = $this->parse($tokens); - } else { - $default = null; - } - - if ($parseDescription !== null) { - $description = $parseDescription($tokens); - } else { - $description = ''; - } - - if ($name === '') { - throw new LogicException('Template tag name cannot be empty.'); - } - - return new Ast\PhpDoc\TemplateTagValueNode($name, $upperBound, $description, $default, $lowerBound); - } - - /** @phpstan-impure */ - private function parseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier, bool $hasTemplate): Ast\Type\TypeNode - { - $templates = $hasTemplate - ? $this->parseCallableTemplates($tokens) - : []; - - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES); - $tokens->skipNewLineTokensAndConsumeComments(); - - $parameters = []; - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) { - $parameters[] = $this->parseCallableParameter($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { - $tokens->skipNewLineTokensAndConsumeComments(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) { - break; - } - $parameters[] = $this->parseCallableParameter($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - } - } - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); - $tokens->consumeTokenType(Lexer::TOKEN_COLON); - - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - $returnType = $this->enrichWithAttributes($tokens, $this->parseCallableReturnType($tokens), $startLine, $startIndex); - - return new Ast\Type\CallableTypeNode($identifier, $parameters, $returnType, $templates); - } - - /** - * @return Ast\PhpDoc\TemplateTagValueNode[] + * Reads a type at the position the iterator is at and leaves the iterator + * right after it. * * @phpstan-impure + * @throws ParserException */ - private function parseCallableTemplates(TokenIterator $tokens): array - { - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET); - - $templates = []; - - $isFirst = true; - while ($isFirst || $tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { - $tokens->skipNewLineTokensAndConsumeComments(); - - // trailing comma case - if (!$isFirst && $tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) { - break; - } - $isFirst = false; - - $templates[] = $this->parseCallableTemplateArgument($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - } - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET); - - return $templates; - } - - private function parseCallableTemplateArgument(TokenIterator $tokens): Ast\PhpDoc\TemplateTagValueNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - return $this->enrichWithAttributes( - $tokens, - $this->parseTemplateTagValue($tokens), - $startLine, - $startIndex, - ); - } - - /** @phpstan-impure */ - private function parseCallableParameter(TokenIterator $tokens): Ast\Type\CallableTypeParameterNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - $type = $this->parse($tokens); - $isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE); - $isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) { - $parameterName = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); - - } else { - $parameterName = ''; - } - - $isOptional = $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL); - return $this->enrichWithAttributes( - $tokens, - new Ast\Type\CallableTypeParameterNode($type, $isReference, $isVariadic, $parameterName, $isOptional), - $startLine, - $startIndex, - ); - } - - /** @phpstan-impure */ - private function parseCallableReturnType(TokenIterator $tokens): Ast\Type\TypeNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_NULLABLE)) { - return $this->parseNullable($tokens); - - } elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { - $type = $this->subParse($tokens); - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $type); - } - - return $type; - } elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_THIS_VARIABLE)) { - $type = new Ast\Type\ThisTypeNode(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - )); - } - - return $type; - } else { - $currentTokenValue = $tokens->currentTokenValue(); - $tokens->pushSavePoint(); // because of ConstFetchNode - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_IDENTIFIER)) { - $type = new Ast\Type\IdentifierTypeNode($currentTokenValue); - - if (!$tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON)) { - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) { - $type = $this->parseGeneric( - $tokens, - $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - ), - ); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - )); - } - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - )); - - } elseif (in_array($type->name, [ - Ast\Type\ArrayShapeNode::KIND_ARRAY, - Ast\Type\ArrayShapeNode::KIND_LIST, - Ast\Type\ArrayShapeNode::KIND_NON_EMPTY_ARRAY, - Ast\Type\ArrayShapeNode::KIND_NON_EMPTY_LIST, - 'object', - ], true) && $tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET) && !$tokens->isPrecededByHorizontalWhitespace()) { - if ($type->name === 'object') { - $type = $this->parseObjectShape($tokens); - } else { - $type = $this->parseArrayShape($tokens, $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - ), $type->name); - } - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - )); - } - } - - return $type; - } else { - $tokens->rollback(); // because of ConstFetchNode - } - } else { - $tokens->dropSavePoint(); // because of ConstFetchNode - } - } - - $currentTokenValue = $tokens->currentTokenValue(); - $currentTokenType = $tokens->currentTokenType(); - $currentTokenOffset = $tokens->currentTokenOffset(); - $currentTokenLine = $tokens->currentTokenLine(); - - try { - $constExpr = $this->constExprParser->parse($tokens); - if ($constExpr instanceof Ast\ConstExpr\ConstExprArrayNode) { - throw new ParserException( - $currentTokenValue, - $currentTokenType, - $currentTokenOffset, - Lexer::TOKEN_IDENTIFIER, - null, - $currentTokenLine, - ); - } - - $type = $this->enrichWithAttributes( - $tokens, - new Ast\Type\ConstTypeNode($constExpr), - $startLine, - $startIndex, - ); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $type = $this->tryParseArrayOrOffsetAccess($tokens, $type); - } - - return $type; - } catch (LogicException $e) { - throw new ParserException( - $currentTokenValue, - $currentTokenType, - $currentTokenOffset, - Lexer::TOKEN_IDENTIFIER, - null, - $currentTokenLine, - ); - } - } - - /** @phpstan-impure */ - private function tryParseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier, bool $hasTemplate): Ast\Type\TypeNode - { - try { - $tokens->pushSavePoint(); - $type = $this->parseCallable($tokens, $identifier, $hasTemplate); - $tokens->dropSavePoint(); - - } catch (ParserException $e) { - $tokens->rollback(); - $type = $identifier; - } - - return $type; - } - - /** @phpstan-impure */ - private function tryParseArrayOrOffsetAccess(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode - { - $startLine = $type->getAttribute(Ast\Attribute::START_LINE); - $startIndex = $type->getAttribute(Ast\Attribute::START_INDEX); - try { - while ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { - $tokens->pushSavePoint(); - - $canBeOffsetAccessType = !$tokens->isPrecededByHorizontalWhitespace(); - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET); - - if ($canBeOffsetAccessType && !$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_SQUARE_BRACKET)) { - $offset = $this->parse($tokens); - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_SQUARE_BRACKET); - $tokens->dropSavePoint(); - $type = new Ast\Type\OffsetAccessTypeNode($type, $offset); - - if ($startLine !== null && $startIndex !== null) { - $type = $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - ); - } - } else { - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_SQUARE_BRACKET); - $tokens->dropSavePoint(); - $type = new Ast\Type\ArrayTypeNode($type); - - if ($startLine !== null && $startIndex !== null) { - $type = $this->enrichWithAttributes( - $tokens, - $type, - $startLine, - $startIndex, - ); - } - } - } - - } catch (ParserException $e) { - $tokens->rollback(); - } - - return $type; - } - - /** - * @phpstan-impure - * @param Ast\Type\ArrayShapeNode::KIND_* $kind - */ - private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type, string $kind): Ast\Type\ArrayShapeNode - { - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET); - - $items = []; - $sealed = true; - $unsealedType = null; - - $done = false; - - do { - $tokens->skipNewLineTokensAndConsumeComments(); - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) { - return Ast\Type\ArrayShapeNode::createSealed($items, $kind); - } - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC)) { - $sealed = false; - - $tokens->skipNewLineTokensAndConsumeComments(); - if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) { - if ($kind === Ast\Type\ArrayShapeNode::KIND_ARRAY) { - $unsealedType = $this->parseArrayShapeUnsealedType($tokens); - } else { - $unsealedType = $this->parseListShapeUnsealedType($tokens); - } - $tokens->skipNewLineTokensAndConsumeComments(); - } - - $tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA); - break; - } - - $items[] = $this->parseArrayShapeItem($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { - $done = true; - } - if ($tokens->currentTokenType() !== Lexer::TOKEN_COMMENT) { - continue; - } - - $tokens->next(); - - } while (!$done); - - $tokens->skipNewLineTokensAndConsumeComments(); - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET); - - if ($sealed) { - return Ast\Type\ArrayShapeNode::createSealed($items, $kind); - } - - return Ast\Type\ArrayShapeNode::createUnsealed($items, $unsealedType, $kind); - } - - /** @phpstan-impure */ - private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShapeItemNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - // parse any comments above the item - $tokens->skipNewLineTokensAndConsumeComments(); - - try { - $tokens->pushSavePoint(); - $key = $this->parseArrayShapeKey($tokens); - $optional = $tokens->tryConsumeTokenType(Lexer::TOKEN_NULLABLE); - $tokens->consumeTokenType(Lexer::TOKEN_COLON); - $value = $this->parse($tokens); - - $tokens->dropSavePoint(); - - return $this->enrichWithAttributes( - $tokens, - new Ast\Type\ArrayShapeItemNode($key, $optional, $value), - $startLine, - $startIndex, - ); - } catch (ParserException $e) { - $tokens->rollback(); - $value = $this->parse($tokens); - - return $this->enrichWithAttributes( - $tokens, - new Ast\Type\ArrayShapeItemNode(null, false, $value), - $startLine, - $startIndex, - ); - } - } - - /** - * @phpstan-impure - * @return Ast\ConstExpr\ConstExprIntegerNode|Ast\ConstExpr\ConstExprStringNode|Ast\ConstExpr\ConstFetchNode|Ast\Type\IdentifierTypeNode - */ - private function parseArrayShapeKey(TokenIterator $tokens) - { - $startIndex = $tokens->currentTokenIndex(); - $startLine = $tokens->currentTokenLine(); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) { - $key = new Ast\ConstExpr\ConstExprIntegerNode(str_replace('_', '', $tokens->currentTokenValue())); - $tokens->next(); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) { - $key = new Ast\ConstExpr\ConstExprStringNode(StringUnescaper::unescapeString($tokens->currentTokenValue()), Ast\ConstExpr\ConstExprStringNode::SINGLE_QUOTED); - $tokens->next(); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_QUOTED_STRING)) { - $key = new Ast\ConstExpr\ConstExprStringNode(StringUnescaper::unescapeString($tokens->currentTokenValue()), Ast\ConstExpr\ConstExprStringNode::DOUBLE_QUOTED); - - $tokens->next(); - - } else { - $identifier = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_COLON)) { - $classConstantName = $tokens->currentTokenValue(); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - - $key = new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName); - } else { - $key = new Ast\Type\IdentifierTypeNode($identifier); - } - } - - return $this->enrichWithAttributes( - $tokens, - $key, - $startLine, - $startIndex, - ); - } - - /** - * @phpstan-impure - */ - private function parseArrayShapeUnsealedType(TokenIterator $tokens): Ast\Type\ArrayShapeUnsealedTypeNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET); - $tokens->skipNewLineTokensAndConsumeComments(); - - $valueType = $this->parse($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - - $keyType = null; - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { - $tokens->skipNewLineTokensAndConsumeComments(); - - $keyType = $valueType; - $valueType = $this->parse($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - } - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET); - - return $this->enrichWithAttributes( - $tokens, - new Ast\Type\ArrayShapeUnsealedTypeNode($valueType, $keyType), - $startLine, - $startIndex, - ); - } - - /** - * @phpstan-impure - */ - private function parseListShapeUnsealedType(TokenIterator $tokens): Ast\Type\ArrayShapeUnsealedTypeNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET); - $tokens->skipNewLineTokensAndConsumeComments(); - - $valueType = $this->parse($tokens); - $tokens->skipNewLineTokensAndConsumeComments(); - - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET); - - return $this->enrichWithAttributes( - $tokens, - new Ast\Type\ArrayShapeUnsealedTypeNode($valueType, null), - $startLine, - $startIndex, - ); - } - - /** - * @phpstan-impure - */ - private function parseObjectShape(TokenIterator $tokens): Ast\Type\ObjectShapeNode - { - $tokens->consumeTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET); - - $items = []; - - do { - $tokens->skipNewLineTokensAndConsumeComments(); - - if ($tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) { - return new Ast\Type\ObjectShapeNode($items); - } - - $items[] = $this->parseObjectShapeItem($tokens); - - $tokens->skipNewLineTokensAndConsumeComments(); - } while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)); - - $tokens->skipNewLineTokensAndConsumeComments(); - $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET); - - return new Ast\Type\ObjectShapeNode($items); - } - - /** @phpstan-impure */ - private function parseObjectShapeItem(TokenIterator $tokens): Ast\Type\ObjectShapeItemNode - { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - $tokens->skipNewLineTokensAndConsumeComments(); - - $key = $this->parseObjectShapeKey($tokens); - $optional = $tokens->tryConsumeTokenType(Lexer::TOKEN_NULLABLE); - $tokens->consumeTokenType(Lexer::TOKEN_COLON); - $value = $this->parse($tokens); - - return $this->enrichWithAttributes( - $tokens, - new Ast\Type\ObjectShapeItemNode($key, $optional, $value), - $startLine, - $startIndex, - ); - } - - /** - * @phpstan-impure - * @return Ast\ConstExpr\ConstExprStringNode|Ast\Type\IdentifierTypeNode - */ - private function parseObjectShapeKey(TokenIterator $tokens) + public function parse(TokenIterator $tokens): Ast\Type\TypeNode { - $startLine = $tokens->currentTokenLine(); - $startIndex = $tokens->currentTokenIndex(); - - if ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) { - $key = new Ast\ConstExpr\ConstExprStringNode(StringUnescaper::unescapeString($tokens->currentTokenValue()), Ast\ConstExpr\ConstExprStringNode::SINGLE_QUOTED); - $tokens->next(); - - } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_QUOTED_STRING)) { - $key = new Ast\ConstExpr\ConstExprStringNode(StringUnescaper::unescapeString($tokens->currentTokenValue()), Ast\ConstExpr\ConstExprStringNode::DOUBLE_QUOTED); - $tokens->next(); - - } else { - $key = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue()); - $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); - } - - return $this->enrichWithAttributes($tokens, $key, $startLine, $startIndex); + /** @var Ast\Type\TypeNode */ + return $this->builder->read($tokens, 'Type'); } } diff --git a/tests/PHPStan/Lexer/LexerTest.php b/tests/PHPStan/Lexer/LexerTest.php index e66e9339..456d8710 100644 --- a/tests/PHPStan/Lexer/LexerTest.php +++ b/tests/PHPStan/Lexer/LexerTest.php @@ -2,12 +2,15 @@ namespace PHPStan\PhpDocParser\Lexer; +use PHPStan\PhpDocParser\Parser\Generated\GeneratedParser; +use PHPStan\PhpDocParser\Parser\Phplrt\TokenStream; use PHPStan\PhpDocParser\ParserConfig; use PHPUnit\Framework\TestCase; -use ReflectionProperty; use function array_keys; +use function array_map; +use function count; +use function intdiv; use function preg_match_all; -use const PHP_VERSION_ID; class LexerTest extends TestCase { @@ -23,15 +26,7 @@ class LexerTest extends TestCase */ public function testTokenPatternsHaveNoCapturingGroups(): void { - $lexer = new Lexer(new ParserConfig([])); - $lexer->tokenize('/** @param float $a */'); - - $property = new ReflectionProperty(Lexer::class, 'regexp'); - if (PHP_VERSION_ID < 80100) { - $property->setAccessible(true); - } - $regexp = $property->getValue($lexer); - self::assertIsString($regexp); + $regexp = GeneratedParser::LEXER_PATTERN; // exercises the patterns that are most likely to grow a group $subject = '/** 0b1_0 0o1_0 0xa_b 1_0 1_0.0_1e+1_0 Foo|Bar $a ... */'; @@ -40,4 +35,37 @@ public function testTokenPatternsHaveNoCapturingGroups(): void self::assertSame([0, 'MARK'], array_keys($matches)); } + /** + * @return iterable + */ + public function dataStream(): iterable + { + yield ['/** @param ARRAY|Array{a: int}|array {b} $is IS is-a \\is not\\Of */']; + yield ['/** @Param @phpstan-param:foo @param-out @param- @psalm-param_x @ORM\\Entity @Foo(1) */']; + yield ["/**\n * @var Foo[0] Foo [0] Foo(1) Foo (1) Foo{1} Foo {1}\n * @return Foo::BAR* Foo::BAR*|Baz\n */"]; + yield ['/** @return Foo
see below
< br > x
Foo b */']; + yield ['/** TRUE False nULL true-ish 1_0.0_1e+1_0 0x1F -1 "a""b" \'c\' // comment */']; + yield ['']; + yield ['@var int']; + } + + /** + * The stream the lexer reads along with the tokens is the very one the + * parsers would otherwise read out of the tokens themselves. + * + * @dataProvider dataStream + */ + public function testStream(string $input): void + { + $tokens = (new Lexer(new ParserConfig([])))->tokenize($input); + + foreach ([0, intdiv(count($tokens), 2), count($tokens) - 1] as $start) { + $ids = []; + $indexes = []; + TokenStream::create(array_map(static fn (array $token): array => [$token[0], $token[1], $token[2]], $tokens), $start, $ids, $indexes); + + self::assertSame([$ids, $indexes], TokenStream::fromTokens($tokens, $start)); + } + } + } diff --git a/tests/PHPStan/Parser/PhpDocParserTest.php b/tests/PHPStan/Parser/PhpDocParserTest.php index eacece63..4918556c 100644 --- a/tests/PHPStan/Parser/PhpDocParserTest.php +++ b/tests/PHPStan/Parser/PhpDocParserTest.php @@ -473,12 +473,12 @@ public function provideParamTagsData(): Iterator new InvalidTagValueNode( 'Foo', new ParserException( - "\n\t\t\t ", - Lexer::TOKEN_PHPDOC_EOL, - 21, - Lexer::TOKEN_VARIABLE, + '*/', + Lexer::TOKEN_CLOSE_PHPDOC, + 27, + Lexer::TOKEN_IDENTIFIER, null, - 2, + 3, ), ), ), @@ -1540,7 +1540,7 @@ public function provideReturnTagsData(): Iterator '|', Lexer::TOKEN_UNION, 18, - Lexer::TOKEN_OTHER, + Lexer::TOKEN_IDENTIFIER, null, 1, ), @@ -1561,7 +1561,7 @@ public function provideReturnTagsData(): Iterator '&', Lexer::TOKEN_INTERSECTION, 18, - Lexer::TOKEN_OTHER, + Lexer::TOKEN_IDENTIFIER, null, 1, ), @@ -1844,10 +1844,10 @@ public function provideReturnTagsData(): Iterator new InvalidTagValueNode( '\Closure(...int, string): string', new ParserException( - '(', - Lexer::TOKEN_OPEN_PARENTHESES, - 20, - Lexer::TOKEN_HORIZONTAL_WS, + '...', + Lexer::TOKEN_VARIADIC, + 21, + Lexer::TOKEN_CLOSE_PARENTHESES, null, 1, ), @@ -1908,10 +1908,10 @@ public function provideReturnTagsData(): Iterator new PhpDocTagNode( '@return', new InvalidTagValueNode('callable(int, string)', new ParserException( - '(', - 4, - 20, - 27, + '*/', + Lexer::TOKEN_CLOSE_PHPDOC, + 34, + Lexer::TOKEN_COLON, null, 1, )), @@ -3089,10 +3089,10 @@ public function provideSingleLinePhpDocData(): Iterator new InvalidTagValueNode( 'callable(int)', new ParserException( - '(', - Lexer::TOKEN_OPEN_PARENTHESES, - 17, - Lexer::TOKEN_HORIZONTAL_WS, + '*/', + Lexer::TOKEN_CLOSE_PHPDOC, + 23, + Lexer::TOKEN_COLON, null, 1, ), @@ -4480,12 +4480,12 @@ public function provideMultiLinePhpDocData(): iterable ' >,' . PHP_EOL . '}> $a', new ParserException( - '?', - Lexer::TOKEN_NULLABLE, - DIRECTORY_SEPARATOR === '\\' ? 65 : 62, - Lexer::TOKEN_CLOSE_CURLY_BRACKET, + '|', + Lexer::TOKEN_UNION, + DIRECTORY_SEPARATOR === '\\' ? 192 : 186, + Lexer::TOKEN_CLOSE_ANGLE_BRACKET, null, - 4, + 7, ), )), ]), @@ -5836,7 +5836,7 @@ public function provideRealWorldExampleData(): Iterator 'malformed const fetch', '/** @param Foo::** $a */', new PhpDocNode([ - new PhpDocTagNode('@param', new InvalidTagValueNode('Foo::** $a', new ParserException('*', Lexer::TOKEN_WILDCARD, 17, Lexer::TOKEN_VARIABLE, null, 1))), + new PhpDocTagNode('@param', new InvalidTagValueNode('Foo::** $a', new ParserException('*', Lexer::TOKEN_WILDCARD, 17, Lexer::TOKEN_IDENTIFIER, null, 1))), ]), ]; @@ -7381,10 +7381,10 @@ public function provideDoctrineWithoutDoctrineCheckData(): Iterator new PhpDocNode([ new PhpDocTagNode('@X', new GenericTagValueNode('test')), new PhpDocTagNode('@Z', new InvalidTagValueNode('(test=', new ParserException( - '=', - 14, - 19, - 5, + '*/', + Lexer::TOKEN_CLOSE_PHPDOC, + 21, + Lexer::TOKEN_IDENTIFIER, null, 1, ))), @@ -7398,10 +7398,10 @@ public function provideDoctrineWithoutDoctrineCheckData(): Iterator new PhpDocNode([ new PhpDocTagNode('@X', new DoctrineTagValueNode(new DoctrineAnnotation('@X', []), 'test')), new PhpDocTagNode('@Z', new InvalidTagValueNode('(test=', new ParserException( - '=', - 14, - 21, - 5, + '*/', + Lexer::TOKEN_CLOSE_PHPDOC, + 23, + Lexer::TOKEN_IDENTIFIER, null, 1, ))), diff --git a/tests/PHPStan/Parser/TypeParserTest.php b/tests/PHPStan/Parser/TypeParserTest.php index 1f97651d..5a8612c6 100644 --- a/tests/PHPStan/Parser/TypeParserTest.php +++ b/tests/PHPStan/Parser/TypeParserTest.php @@ -756,7 +756,7 @@ public function provideParseData(): array '', Lexer::TOKEN_END, 6, - Lexer::TOKEN_IDENTIFIER, + Lexer::TOKEN_CLOSE_CURLY_BRACKET, null, null, ), @@ -2556,10 +2556,10 @@ public function provideParseData(): array [ 'Foo', new ParserException( - '>', - Lexer::TOKEN_CLOSE_ANGLE_BRACKET, - 13, - Lexer::TOKEN_IDENTIFIER, + '', + Lexer::TOKEN_END, + 14, + Lexer::TOKEN_OPEN_PARENTHESES, null, null, ), @@ -2708,7 +2708,7 @@ public function provideParseData(): array '', Lexer::TOKEN_END, 7, - Lexer::TOKEN_IDENTIFIER, + Lexer::TOKEN_CLOSE_CURLY_BRACKET, null, null, ), @@ -2741,7 +2741,7 @@ public function provideParseData(): array '0', Lexer::TOKEN_END, 7, - Lexer::TOKEN_IDENTIFIER, + Lexer::TOKEN_CLOSE_CURLY_BRACKET, null, null, ), @@ -2752,7 +2752,7 @@ public function provideParseData(): array '0', Lexer::TOKEN_END, 7, - Lexer::TOKEN_IDENTIFIER, + Lexer::TOKEN_CLOSE_CURLY_BRACKET, null, null, ), diff --git a/tools/phplrt/GeneratedParser.template.php b/tools/phplrt/GeneratedParser.template.php new file mode 100644 index 00000000..df283f39 --- /dev/null +++ b/tools/phplrt/GeneratedParser.template.php @@ -0,0 +1,132 @@ + the identifier of each rule a reading may start at */ + public const RULES = /*RULES*/[]; + + /** @var array the identifier of each token */ + public const TOKENS = /*TOKENS*/[]; + + /** @var array the name each token is expected by */ + public const EXPECTATIONS = /*EXPECTATIONS*/[]; + + /** the pattern of the lexer, marking each token by its identifier */ + public const LEXER_PATTERN = /*LEXER_PATTERN*/''; + + /** @var array the type of the lexer each token it reads is, by the identifier */ + public const LEXER_TYPES = /*LEXER_TYPES*/[]; + + /*CONSTANTS*/ + + /** @var array the identifier of the token at each position, the last one being -1 */ + protected array $ids = []; + + /** @var array the index of the token of the lexer at each position */ + protected array $indexes = []; + + /** the position the reading is at */ + protected int $p = 0; + + /** @var array the values built, as a stack */ + protected array $v = []; + + /** the size of the stack of values */ + protected int $n = 0; + + /** @var array the comments read and not given to any node yet, by their index */ + protected array $comments = []; + + /** the furthest position a failure has been recorded at */ + private int $f = -1; + + /** @var list the rules recorded as failed at the furthest position */ + private array $er = []; + + abstract protected function token(int $position): Token; + + + /*REDUCERS*/ + + /** + * Where the last reading has failed, along with the tokens expected there. + * + * @return array{int, list} + */ + protected function failure(): array + { + if ($this->f === -1 || $this->f < $this->p) { + return [$this->p, []]; + } + + $expected = []; + foreach ($this->er as $rule) { + foreach (self::EXPECTED[$rule] ?? [] as $token) { + $expected[$token] = true; + } + } + + ksort($expected); + + return [$this->f, array_keys($expected)]; + } + + /** + * Saves the state of the reading, so that a reading may be started in the + * middle of another one. + * + * @return array{int, int, list} + */ + protected function saveReading(): array + { + return [$this->p, $this->f, $this->er]; + } + + /** + * @param array{int, int, list} $state + */ + protected function restoreReading(array $state): void + { + [$this->p, $this->f, $this->er] = $state; + } + + private function rec(int $rule): void + { + $position = $this->p; + if ($position > $this->f) { + $this->f = $position; + $this->er = [$rule]; + return; + } + + if ($position !== $this->f || isset($this->er[3])) { + return; + } + + $this->er[] = $rule; + } + + /*METHODS*/ +} diff --git a/tools/phplrt/ParserGenerator.php b/tools/phplrt/ParserGenerator.php new file mode 100644 index 00000000..751eaa38 --- /dev/null +++ b/tools/phplrt/ParserGenerator.php @@ -0,0 +1,785 @@ +p > \$this->f) {\n\t\$this->f = \$this->p;\n\t\$this->er = [];\n}\n"; + + /** @var array */ + private array $grammar; + + /** @var array|null> */ + private array $start; + + /** @var array>> */ + private array $choice; + + /** @var array> */ + private array $sequence; + + /** @var array */ + private array $kept; + + /** @var array the reducer of each rule, whether it reads the children, and whether it builds nothing */ + private array $reducers; + + /** @var list every token id, along with the end of the input */ + private array $tokenIds; + + /** @var array the tokens no reducer reads, which are never pushed */ + private array $silent; + + /** @var array the sets of tokens written as constants, by their name */ + private array $sets = []; + + /** @var array the methods asked for */ + private array $requested = []; + + /** @var list the methods still to write */ + private array $queue = []; + + private int $labels = 0; + + /** + * @var array|null the tokens the reading is known to be at + * where the code being written starts, or null when nothing is known + */ + private ?array $known = null; + + /** @var array the rules being written out into each other */ + private array $stack = []; + + /** + * @param array>> $choicePrediction + * @param array $reducers + * @param list $tokenIds + * @param list $silent the tokens no reducer reads + */ + public function __construct(ParserBuilderResult $parser, array $choicePrediction, array $reducers, array $tokenIds, array $silent) + { + $this->silent = array_fill_keys($silent, true); + $this->grammar = $parser->grammar; + $this->start = $parser->startPrediction; + $this->choice = $choicePrediction; + $this->sequence = $parser->sequencePrediction; + $this->kept = $parser->kept; + $this->reducers = $reducers; + $this->tokenIds = $tokenIds; + + foreach ($this->grammar as $id => $rule) { + if ($rule instanceof Lexeme && !$rule->keep) { + throw new LogicException(sprintf('Rule %d: a token not kept is not supported', $id)); + } + + if ($rule instanceof Predicate && $this->kept[$id]) { + throw new LogicException(sprintf('Rule %d: a kept predicate is not supported', $id)); + } + } + } + + /** + * @param array $entrypoints + * @return array{string, string} the methods and the constants of the class + */ + public function generate(array $entrypoints): array + { + $dispatch = []; + foreach ($entrypoints as $name => $id) { + $dispatch[] = sprintf( + "\t\t\tcase %d: // %s\n\t\t\t\treturn \$build ? \$this->%s() : \$this->%s();", + $id, + $name, + $this->request($id, true), + $this->request($id, false), + ); + } + + $methods = []; + while ($this->queue !== []) { + $name = array_shift($this->queue); + $methods[$name] = $this->method((int) substr($name, 1), $name[0] === 'b'); + } + + ksort($methods, SORT_NATURAL); + + $code = "\t/**\n\t * Reads the given rule from the given position.\n\t *\n\t * @phpstan-impure\n\t */\n" + . "\tprotected function parseRule(int \$rule, int \$position, bool \$build): bool\n\t{\n" + . "\t\t\$this->p = \$position;\n\t\t\$this->f = -1;\n\t\t\$this->er = [];\n\n" + . "\t\tswitch (\$rule) {\n" . implode("\n", $dispatch) . "\n\t\t\tdefault:\n" + . "\t\t\t\tthrow new \\LogicException('Not an entrypoint: ' . \$rule);\n\t\t}\n\t}\n\n" + . implode("\n", $methods); + + $constants = ''; + ksort($this->sets, SORT_NATURAL); + foreach ($this->sets as $name => $value) { + $constants .= sprintf("\tprivate const %s = %s;\n", $name, $value); + } + + $expected = []; + foreach ($this->grammar as $id => $rule) { + $tokens = $this->expected($id); + if ($tokens === []) { + continue; + } + + sort($tokens); + $expected[] = $id . '=>[' . implode(',', $tokens) . ']'; + } + + $constants .= sprintf("\n\t/** the tokens each rule is expected to begin with */\n\tprivate const EXPECTED = [%s];\n", implode(',', $expected)); + + return [$code, $constants]; + } + + /** + * The tokens a failure of the given rule says have been expected: the ones + * it may begin with. An alternation the compiler predicts nothing of, + * because it may be a predicate as well, expects what its alternatives do, + * a predicate expecting a rule being one expecting what the rule does. + * + * @param array $visited + * @return list + */ + private function expected(int $id, array $visited = []): array + { + $rule = $this->grammar[$id]; + if ($rule instanceof Lexeme) { + return [$rule->tokenId]; + } + + if (isset($this->start[$id])) { + return array_keys($this->start[$id]); + } + + $visited[$id] = true; + $inner = []; + if ($rule instanceof Alternation) { + $inner = $rule->ruleIds; + } elseif ($rule instanceof Predicate && $rule->isExpected) { + $inner = [$rule->ruleId]; + } + + $tokens = []; + foreach ($inner as $alternative) { + if (isset($visited[$alternative])) { + continue; + } + + foreach ($this->expected($alternative, $visited) as $token) { + $tokens[$token] = true; + } + } + + return array_keys($tokens); + } + + private function request(int $id, bool $build): string + { + $name = ($build ? 'b' : 's') . $id; + if (!isset($this->requested[$name])) { + $this->requested[$name] = true; + $this->queue[] = $name; + } + + return $name; + } + + /** + * The tokens the reading is known to be at, which the code written next + * is the only one to be told about. + * + * @return array|null + */ + private function takeKnown(): ?array + { + $known = $this->known; + $this->known = null; + + return $known; + } + + /** + * Whether a check for the given tokens is known to pass. + * + * @param array|null $known + * @param list $tokens + */ + private static function implied(?array $known, array $tokens): bool + { + return $known !== null && array_diff_key($known, array_flip($tokens)) === []; + } + + private function unique(): int + { + return ++$this->labels; + } + + // ------------------------------------------------------------------------- + + private function method(int $id, bool $build): string + { + $this->stack = [($build ? 'b' : 's') . $id => true]; + $this->known = null; + + return sprintf("\tprivate function %s%d(): bool\n\t{\n", $build ? 'b' : 's', $id) + . self::indent($this->body($id, $build, 'return false;'), 2) + . "\n\t\treturn true;\n\t}\n"; + } + + /** + * The code reading the given rule: it goes on past its end in case the + * rule has been read, and runs the given code once it has given back + * whatever it has read in case it has not. + */ + private function body(int $id, bool $build, string $fail): string + { + $rule = $this->grammar[$id]; + $reducer = $this->reducers[$id] ?? null; + $kept = $build && $reducer !== null; + $u = $this->unique(); + // The variables of a rule are named after how deep it is written out, + // which is all it takes for them not to be overwritten by the rules + // inside it: a function initializes every variable it has on every + // call, so there are as few of them as possible + $d = count($this->stack); + + $known = $this->takeKnown(); + + // A rule whose reducer reads nothing of what it contains is only read + if ($kept && !$reducer[1]) { + $this->known = $known; + return "\$o{$d} = \$this->p;\n" + . $this->match($id, false, $fail) + . sprintf($reducer[2] ? "\$this->%s(%s);\n" : "\$this->v[\$this->n++] = \$this->%s(%s);\n", $reducer[0], self::span("\$o{$d}")); + } + + $code = ''; + $start = $this->start[$id] ?? null; + if ($start !== null && self::implied($known, array_keys($start))) { + // the token is known to be one the rule may begin with + } elseif ($start !== null) { + $known = $known === null ? $start : array_intersect_key($known, $start); + $code .= sprintf( + "if (!%s) {\n\tif (\$this->p > \$this->f) {\n\t\t\$this->rec(%d);\n\t}\n\n%s}\n\n", + $this->in(array_keys($start)), + $id, + self::indent($fail, 1), + ); + } + + // Every rule pushes the tokens it reads while building, but for a + // predicate, which reads nothing + $pushes = $build && !$rule instanceof Predicate; + $code .= "\$o{$d} = \$this->p;\n"; + if ($pushes) { + $code .= "\$m{$d} = \$this->n;\n\$cs{$d} = \$this->comments;\n"; + } + + $failure = "goto f{$u};"; + $this->known = $known; + if ($rule instanceof Concatenation) { + $code .= $this->concatenation($id, $rule, $build, $failure); + } elseif ($rule instanceof Alternation) { + $code .= $this->alternation($id, $rule, $build, $failure); + } elseif ($rule instanceof Repetition) { + $code .= $this->repetition($rule, $build, $failure); + } elseif ($rule instanceof Optional) { + $code .= $this->optional($rule->ruleId, $build); + } elseif ($rule instanceof Predicate) { + $code .= $this->predicate($rule, $failure); + } else { + throw new LogicException(sprintf('Rule %d: unsupported %s', $id, get_class($rule))); + } + + if (strpos($code, $failure) !== false) { + $code .= "goto k{$u};\nf{$u}:\n\$this->p = \$o{$d};\n" + . ($pushes ? "\$this->n = \$m{$d};\n\$this->comments = \$cs{$d};\n" : '') + . $fail . "\nk{$u}:\n"; + } + + if ($kept) { + $code .= sprintf( + "\$this->v[\$m%1\$d] = \$this->%2\$s(%3\$s, \$this->n === \$m%1\$d + 1 ? [\$this->v[\$m%1\$d]] : \\array_slice(\$this->v, \$m%1\$d, \$this->n - \$m%1\$d));\n\$this->n = \$m%1\$d + 1;\n", + $d, + $reducer[0], + self::span("\$o{$d}"), + ); + } + + return $code; + } + + /** + * The code reading the given rule where another one expects it: written + * out right there in case it is small enough, called otherwise. + */ + private function match(int $inner, bool $build, string $fail): string + { + $definition = $this->grammar[$inner]; + $tokens = $this->tokens($inner); + if ($tokens !== null) { + if (self::implied($this->takeKnown(), $tokens[0])) { + return $this->read($inner, $build); + } + + return sprintf( + "if (!%s) {\n\tif (\$this->p %s \$this->f) {\n\t\t\$this->rec(%d);\n\t}\n\n%s}\n\n%s", + $this->in($tokens[0]), + $tokens[1], + $inner, + self::indent($fail, 1), + $this->read($inner, $build), + ); + } + + if ($definition instanceof Predicate) { + $this->known = null; + + return $this->predicate($definition, $fail); + } + + $key = ($build ? 'b' : 's') . $inner; + if (!isset($this->stack[$key]) && count($this->stack) < self::INLINE_DEPTH) { + $this->stack[$key] = true; + $labels = $this->labels; + $sets = $this->sets; + $requested = $this->requested; + $queue = $this->queue; + $code = $this->body($inner, $build, $fail); + unset($this->stack[$key]); + + if (strlen($code) <= self::INLINE_SIZE) { + return "// {$key}\n" . $code; + } + + // Too much to write out: the methods asked for along the way are + // not asked for after all, and the method called is told nothing + $this->known = null; + $this->labels = $labels; + $this->sets = $sets; + $this->requested = $requested; + $this->queue = $queue; + } + + $this->known = null; + + return sprintf("if (!\$this->%s()) {\n%s}\n", $this->request($inner, $build), self::indent($fail, 1)); + } + + private function concatenation(int $id, Concatenation $rule, bool $build, string $fail): string + { + $code = ''; + $first = true; + foreach ($this->sequence[$id] ?? $rule->ruleIds as $inner) { + if (!$first) { + $this->known = null; + } + + $first = false; + if ($inner >= 0) { + $code .= $this->match($inner, $build, $fail); + continue; + } + + // An element that may be left out + $this->known = null; + $inner = -$inner - 1; + $element = $this->grammar[$inner]; + if ($element instanceof Predicate) { + $tokens = $this->start[$element->ruleId] ?? null; + $predicate = $this->predicate($element, $fail, true); + $code .= $tokens === null + ? $predicate + : sprintf("if (%s) {\n%s}\n", $this->in(array_keys($tokens)), self::indent($predicate, 1)); + } elseif ($this->tokens($inner) !== null) { + $code .= $this->optional($inner, $build); + } else { + $u = $this->unique(); + $tokens = $this->start[$inner] ?? null; + $read = $this->match($inner, $build, "goto n{$u};") . "n{$u}:\n"; + $code .= $tokens === null + ? $read + : sprintf( + "if (%s) {\n%s} elseif (\$this->p > \$this->f) {\n\t\$this->rec(%d);\n}\n", + $this->in(array_keys($tokens)), + self::indent($read, 1), + $inner, + ); + } + } + + $this->known = null; + + return $code; + } + + private function alternation(int $id, Alternation $rule, bool $build, string $fail): string + { + $ok = 'a' . $this->unique(); + + // The alternatives worth trying at each token + $lists = []; + $groups = []; + foreach ($this->tokenIds as $token) { + $list = $this->choice[$id][$token] ?? $rule->ruleIds; + $key = implode(',', $list); + $lists[$key] = $list; + $groups[$key][] = $token; + } + + uasort($groups, static fn (array $a, array $b): int => count($b) <=> count($a)); + + $known = $this->takeKnown(); + $code = ''; + if (count($groups) === 1) { + $code .= $this->attempts($lists[array_key_first($groups)], $build, $ok, $known); + } else { + $code .= "switch (\$this->ids[\$this->p]) {\n"; + $first = true; + foreach ($groups as $key => $tokens) { + $caseKnown = null; + if ($first) { + $code .= "\tdefault:\n"; + $first = false; + } else { + $caseKnown = array_fill_keys($tokens, true); + foreach ($tokens as $token) { + $code .= sprintf("\tcase %d:\n", $token); + } + } + + $code .= self::indent($this->attempts($lists[$key], $build, $ok, $caseKnown), 2) . "\t\tbreak;\n"; + } + + $code .= "}\n"; + } + + return $code . sprintf("\nif (\$this->p > \$this->f) {\n\t\$this->rec(%d);\n}\n\n%s\n%s:\n", $id, $fail, $ok); + } + + /** + * @param list $alternatives + * @param array|null $known the tokens the reading is known to + * be at, which it is at again whenever an alternative is given up + */ + private function attempts(array $alternatives, bool $build, string $ok, ?array $known): string + { + $code = ''; + foreach ($alternatives as $inner) { + $this->known = null; + if ($inner < 0) { + // A token predicted by the very token the reading is at + return $code . $this->push(-$inner - 1, $build) . "goto {$ok};\n"; + } + + $tokens = $this->tokens($inner); + if ($tokens !== null && self::implied($known, $tokens[0])) { + // the alternative cannot fail, so nothing after it is tried + return $code . $this->read($inner, $build) . "goto {$ok};\n"; + } + + if ($tokens !== null) { + $code .= sprintf( + "if (%s) {\n%s\tgoto %s;\n}\n\nif (\$this->p %s \$this->f) {\n\t\$this->rec(%d);\n}\n", + $this->in($tokens[0]), + self::indent($this->read($inner, $build), 1), + $ok, + $tokens[1], + $inner, + ); + continue; + } + + $next = 'n' . $this->unique(); + $this->known = $known; + $read = $this->match($inner, $build, "goto {$next};") . "goto {$ok};\n"; + $code .= $read . "{$next}:\n"; + } + + $this->known = null; + + return $code; + } + + private function repetition(Repetition $rule, bool $build, string $fail): string + { + $this->known = null; + $inner = $rule->ruleId; + $min = $rule->min; + $max = $rule->max; + $counted = $min > 0 || $max !== INF; + $u = $this->unique(); + $d = count($this->stack); + $end = "goto e{$u};"; + + $code = $counted ? "\$k{$d} = 0;\n" : ''; + $code .= $max === INF ? "while (true) {\n" : sprintf("while (\$k%d < %d) {\n", $d, $max); + $code .= "\t\$b{$d} = \$this->p;\n"; + + $body = ''; + $tokens = $this->tokens($inner); + if ($tokens !== null) { + $body .= sprintf( + "if (!%s) {\n\tif (\$b%d %s \$this->f) {\n\t\t\$this->rec(%d);\n\t}\n\n\t%s\n}\n\n%s", + $this->in($tokens[0]), + $d, + $tokens[1], + $inner, + $end, + $this->read($inner, $build), + ); + } else { + $start = $this->start[$inner] ?? null; + if ($start !== null) { + $body .= sprintf( + "if (!%s) {\n\tif (\$b%d > \$this->f) {\n\t\t\$this->rec(%d);\n\t}\n\n\t%s\n}\n\n", + $this->in(array_keys($start)), + $d, + $inner, + $end, + ); + } + + $body .= $this->match($inner, $build, $end); + // A body reading nothing would be read forever + $body .= "if (\$this->p === \$b{$d}) {\n" . ($counted ? sprintf("\t\$k%d = %d;\n", $d, $min) : '') . "\t{$end}\n}\n"; + } + + $code .= self::indent($body, 1); + $code .= $counted ? "\n\t\$k{$d}++;\n}\n" : "}\n"; + $code .= "e{$u}:\n"; + + if ($min > 0) { + $code .= sprintf("\nif (\$k%d < %d) {\n\t%s\n}\n", $d, $min, $fail); + } + + return $code; + } + + private function optional(int $inner, bool $build): string + { + $this->known = null; + $tokens = $this->tokens($inner); + if ($tokens !== null) { + return sprintf( + "if (%s) {\n%s} elseif (\$this->p %s \$this->f) {\n\t\$this->rec(%d);\n}\n", + $this->in($tokens[0]), + self::indent($this->read($inner, $build), 1), + $tokens[1], + $inner, + ); + } + + $u = $this->unique(); + + return $this->match($inner, $build, "goto n{$u};") . "n{$u}:\n"; + } + + /** + * @param bool $predicted whether the caller has already seen the rule + * inside may begin at the token the reading is at + */ + private function predicate(Predicate $rule, string $fail, bool $predicted = false): string + { + $this->known = null; + $inner = $rule->ruleId; + $tokens = $this->start[$inner] ?? null; + + $set = $this->tokens($inner); + if ($set !== null) { + if ($rule->isExpected) { + return sprintf( + "if (!%s) {\n\tif (\$this->p > \$this->f) {\n\t\t\$this->rec(%d);\n\t}\n\n%s}\n", + $this->in($set[0]), + $inner, + self::indent($fail, 1), + ); + } + + return sprintf("if (%s) {\n%s%s}\n", $this->in($set[0]), self::indent(self::UNEXPECTED, 1), self::indent($fail, 1)); + } + + $u = $this->unique(); + $check = sprintf( + "\$sf = \$this->f;\n\$se = \$this->er;\n\$sp = \$this->p;\n\$matched = \$this->%2\$s();\n\$this->f = \$sf;\n\$this->er = \$se;\n\$this->p = \$sp;\nif (%3\$s\$matched) {\n%4\$s%5\$s}\n", + 0, + $this->request($inner, false), + $rule->isExpected ? '!' : '', + self::indent(self::UNEXPECTED, 1), + self::indent($fail, 1), + ); + + if ($tokens === null || $predicted) { + return $check; + } + + if ($rule->isExpected) { + return sprintf( + "if (!%s) {\n\tif (\$this->p > \$this->f) {\n\t\t\$this->rec(%d);\n\t}\n\n%s}\n\n%s", + $this->in(array_keys($tokens)), + $inner, + self::indent($fail, 1), + $check, + ); + } + + return sprintf("if (%s) {\n%s}\n", $this->in(array_keys($tokens)), self::indent($check, 1)); + } + + /** + * Reads the token the reading is at, which the given rule reads. + */ + private function read(int $id, bool $build): string + { + if ($this->grammar[$id] instanceof Lexeme) { + return $this->push($id, $build); + } + + if (!$build || array_diff_key(array_flip($this->tokens($id)[0]), $this->silent) === []) { + return "\$this->p++;\n"; + } + + return "\$this->v[\$this->n++] = \$this->token(\$this->p++);\n"; + } + + /** + * The tokens a rule reads one of, in case that is all it does: a lexeme, + * or an alternation of lexemes building nothing of its own. + * + * @return array{list, string}|null the tokens, and the comparison + * with the furthest failure a failure to read one is recorded by + */ + private function tokens(int $id): ?array + { + $rule = $this->grammar[$id]; + if ($rule instanceof Lexeme) { + return [[$rule->tokenId], '>=']; + } + + if (!$rule instanceof Alternation || isset($this->reducers[$id])) { + return null; + } + + $tokens = []; + foreach ($rule->ruleIds as $alternative) { + $definition = $this->grammar[$alternative]; + if (!$definition instanceof Lexeme || isset($this->reducers[$alternative])) { + return null; + } + + $tokens[$definition->tokenId] = true; + } + + // The alternation is entered at the very tokens it reads + $start = $this->start[$id] ?? []; + ksort($start); + ksort($tokens); + if ($start !== $tokens) { + return null; + } + + return [array_keys($tokens), '>']; + } + + /** + * Reads the token the reading is at as the given lexeme. + */ + private function push(int $lexeme, bool $build): string + { + $definition = $this->grammar[$lexeme]; + if (!$build || (isset($this->silent[$definition->tokenId]) && !isset($this->reducers[$lexeme]))) { + return "\$this->p++;\n"; + } + + $reducer = $this->reducers[$lexeme] ?? null; + if ($reducer !== null) { + return sprintf( + $reducer[2] + ? "\$this->%s(\$this->indexes[\$this->p], \$this->indexes[\$this->p]%s);\n\$this->p++;\n" + : "\$this->v[\$this->n++] = \$this->%s(\$this->indexes[\$this->p], \$this->indexes[\$this->p]%s);\n\$this->p++;\n", + $reducer[0], + $reducer[1] ? ', [$this->token($this->p)]' : '', + ); + } + + return "\$this->v[\$this->n++] = \$this->token(\$this->p++);\n"; + } + + /** + * @param list $tokens + */ + private function in(array $tokens): string + { + sort($tokens); + if (count($tokens) === 1) { + return sprintf('($this->ids[$this->p] === %d)', $tokens[0]); + } + + $name = 'T' . substr(md5(implode(',', $tokens)), 0, 8); + $this->sets[$name] = '[' . implode(',', array_map(static fn (int $t): string => $t . '=>true', $tokens)) . ']'; + + return sprintf('isset(self::%s[$this->ids[$this->p]])', $name); + } + + /** + * The index of the first and of the last token of the lexer a rule + * entered at the given position has read up to the position the reading + * is at. A rule that has read nothing ends right before it begins, right + * after what has been read before it. + */ + private static function span(string $origin): string + { + return strtr( + '(O < $this->p ? $this->indexes[O] : (O > 0 ? $this->indexes[O - 1] + 1 : 0)), (O < $this->p ? $this->indexes[$this->p - 1] : (O > 0 ? $this->indexes[O - 1] : -1))', + ['O' => $origin], + ); + } + + private static function indent(string $code, int $levels): string + { + $prefix = str_repeat("\t", $levels); + + return preg_replace('/^(?=.)/m', $prefix, $code); + } + +} diff --git a/tools/phplrt/build.php b/tools/phplrt/build.php new file mode 100644 index 00000000..ed1c94a7 --- /dev/null +++ b/tools/phplrt/build.php @@ -0,0 +1,383 @@ +] + * + * @internal this is a development tool, not part of the library + */ + +declare(strict_types=1); + +use Phplrt\Compiler\Compiler; +use Phplrt\Lexer\Builder\LexerBuilderResult; +use Phplrt\Parser\Builder\Compiler\ParserBuildingContext; +use Phplrt\Parser\Builder\Compiler\ParserCompilerPassInterface; +use Phplrt\Parser\Builder\Definition\AlternationRuleDefinition; +use Phplrt\Parser\Builder\Definition\RuleDefinition; +use Phplrt\Parser\Builder\ParserBuilder; +use Phplrt\Parser\Grammar\Alternation; +use Phplrt\Parser\Grammar\Lexeme; +use Phplrt\Source\FileSource; + +// The upstream runtime the compiler is written against has to win over the +// downgraded one the library itself depends on +require __DIR__ . '/vendor/autoload.php'; + +require __DIR__ . '/ParserGenerator.php'; +require __DIR__ . '/../../src/Lexer/Lexer.php'; + +$output = $argv[1] ?? __DIR__ . '/../../src/Parser/Generated/GeneratedParser.php'; + +/** + * The rules the parsers are started at. + */ +const ENTRYPOINTS = ['PhpDoc', 'Type', 'ConstantExpr', 'KnownTag', 'UnreadTagChild', 'PhpDocChild']; + +/** + * The reducers of "src/Parser/AstBuilder.php", by the name of the rule they + * reduce, along with whether they read what the rule contains. The source is + * read rather than the class, which extends the very class written here. + * + * @var array $reducers + */ +$reducers = []; +preg_match_all('/function (reduce(\w+))\(([^)]*)\)(: \??\w+)?/', file_get_contents(__DIR__ . '/../../src/Parser/AstBuilder.php'), $matches, PREG_SET_ORDER); +foreach ($matches as $match) { + [, $method, $rule, $parameters] = $match; + // A reducer returning nothing builds nothing: the value of the rule is + // left out of the values of the rule around it + $reducers[$rule] = [$method, strpos($parameters, '$children') !== false, ($match[4] ?? '') === ': void']; +} + +/** @var array $entrypoints */ +$entrypoints = array_fill_keys(array_keys($reducers), true) + array_fill_keys(ENTRYPOINTS, true); + +$compiler = (new Compiler()) + ->load(FileSource::createFromPathname(__DIR__ . '/../../doc/grammars/phpdoc.pp3')); + +/** + * The grammars describe a PHPDoc written correctly, while the parser reads a + * broken one as well: a tag whose value cannot be read keeps the rest of its + * line as its value, and a type alias whose type cannot be read keeps its name. + * Both are written here as alternatives tried once everything else has failed, + * so that the grammars stay the description of the language they are. + * + * InvalidTag : TagToken() Text() ; + * InvalidTypeAliasTag : Identifier() ? Text() ; + */ +$builder = $compiler->parser; +$invalidTag = $builder->addConcatenation([ + $builder->addRuleReference('TagToken'), + $builder->addRuleReference('Text'), +], 'InvalidTag'); +$invalidTypeAliasTag = $builder->addConcatenation([ + $builder->addTokenReference('T_TAG_TYPE_ALIAS'), + $builder->addRuleReference('Identifier'), + $builder->addOptional($builder->addTokenReference('T_EQUAL')), + $builder->addRuleReference('Text'), +], 'InvalidTypeAliasTag'); + +foreach ($builder->rules as $rule) { + if ($rule->name === 'PhpDocChild') { + // KnownTag | InvalidTag | !TagToken() TextChild() + $alternatives = $rule->rules; + array_splice($alternatives, 1, 0, [$invalidTag]); + $rule->setRules($alternatives); + } elseif ($rule->name === 'KnownTag') { + $alternatives = []; + foreach ($rule->rules as $alternative) { + $alternatives[] = $alternative; + if ((string) $alternative->rules[0] === '') { + $alternatives[] = $invalidTypeAliasTag; + } + } + $rule->setRules($alternatives); + } +} + +$found = []; + +foreach ($compiler->parser->rules as $rule) { + if ($rule->name === null || !isset($entrypoints[$rule->name])) { + continue; + } + + $found[$rule->name] = true; + + if (in_array($rule->name, ENTRYPOINTS, true)) { + $rule->setEntrypoint(); + } + + if (isset($reducers[$rule->name])) { + // The reducer is only a mark that keeps the rule in the trace: the + // parser written calls the one of the AST builder + $rule->setReducer(static fn () => null); + } +} + +$missing = array_diff_key($entrypoints, $found); +if ($missing !== []) { + fwrite(STDERR, sprintf("The grammar has no rule named %s\n", implode(', ', array_keys($missing)))); + exit(1); +} + +/** + * Joins an alternation with the alternations nested into it. + * + * Upstream leaves them nested, so that an alternation the token at hand cannot + * start is skipped along with all of its alternatives by a single lookup. Here + * every alternation is entered through its choice prediction, which already + * names the very alternatives worth trying, so a nested one is only a call per + * token more: the free-form text of a PHPDoc is read by three alternations + * nested into each other, one call each per word. + */ +final class NestedAlternationParserCompilerPass implements ParserCompilerPassInterface +{ + + public function process(ParserBuildingContext $context, LexerBuilderResult $lexer): void + { + foreach ($context->rules as $rule) { + if (!$rule instanceof AlternationRuleDefinition) { + continue; + } + + $rule->setRules($this->expand($rule, $context)); + } + + $context->rules = $context->collectReachableRules(); + } + + /** + * @return list + */ + private function expand(AlternationRuleDefinition $rule, ParserBuildingContext $context): array + { + $result = []; + + foreach ($rule->rules as $child) { + if ( + $child instanceof AlternationRuleDefinition + && $child->reducer === null + && $child->message === null + && !$context->isEntrypoint($child) + ) { + foreach ($this->expand($child, $context) as $inner) { + $result[] = $inner; + } + + continue; + } + + $result[] = $child; + } + + return $result; + } + +} + +$compiler->parser->addCompilerPass(new NestedAlternationParserCompilerPass(), ParserBuilder::PASS_PRIORITY_OPTIMIZE - 1); + +$result = $compiler->build(); +$parser = $result->parser; + +/** + * Writes the choice prediction down for every token there is. + * + * Upstream only writes a row for a token some alternative is known to begin + * with, and an alternation is read by trying every one of its alternatives at + * a token it has no row for. An alternative that may begin with anything at + * all, like a line of text, is therefore what every other alternative is tried + * along with, on every token nothing else begins with: a line of a description + * is tried as each of the tags first. A row for each of those tokens says that + * only such alternatives are worth trying. + * + * @return array>> + */ +function completeChoicePrediction(Phplrt\Parser\Builder\ParserBuilderResult $parser, array $tokenIds): array +{ + $result = $parser->choicePrediction; + + foreach ($parser->grammar as $id => $rule) { + if (!$rule instanceof Alternation) { + continue; + } + + $firsts = []; + foreach ($rule->ruleIds as $alternative) { + $definition = $parser->grammar[$alternative]; + $firsts[$alternative] = $definition instanceof Lexeme + ? [$definition->tokenId => true] + : $parser->startPrediction[$alternative] ?? null; + } + + foreach ($tokenIds as $token) { + if (isset($result[$id][$token])) { + continue; + } + + $candidates = []; + foreach ($rule->ruleIds as $alternative) { + $first = $firsts[$alternative]; + if ($first !== null && !isset($first[$token])) { + continue; + } + + $definition = $parser->grammar[$alternative]; + $candidates[] = $definition instanceof Lexeme && $definition->tokenId === $token + ? -$alternative - 1 + : $alternative; + } + + if ($candidates === $rule->ruleIds) { + continue; + } + + $result[$id][$token] = $candidates; + } + + if (isset($result[$id])) { + ksort($result[$id]); + } + } + + ksort($result); + + return $result; +} + +$tokenIds = array_keys($result->lexer->names); +// The end of the input, which the runtime reports on its own +$tokenIds[] = -1; + +$choicePrediction = completeChoicePrediction($parser, $tokenIds); + +/** + * @param mixed $value + */ +function export($value): string +{ + if (is_array($value)) { + if ($value === []) { + return '[]'; + } + + $isList = array_is_list($value); + $items = []; + foreach ($value as $key => $item) { + $items[] = ($isList ? '' : var_export($key, true) . ' => ') . export($item); + } + + return '[' . implode(', ', $items) . ']'; + } + + return var_export($value, true); +} + +$rules = []; +foreach ($parser->constants as $name => $id) { + if (in_array($name, ENTRYPOINTS, true)) { + $rules[$name] = $id; + } +} + +$reducerIds = []; +$abstracts = []; +foreach ($reducers as $name => $reducer) { + $id = $parser->constants[$name]; + $reducerIds[$id] = $reducer; + $abstracts[] = $reducer[1] + ? sprintf("\t/**\n\t * @param list \$children\n\t * @return mixed\n\t */\n\tabstract protected function %s(int \$begin, int \$end, \$children);\n", $reducer[0]) + : ($reducer[2] + ? sprintf("\tabstract protected function %s(int \$begin, int \$end): void;\n", $reducer[0]) + : sprintf("\t/**\n\t * @return mixed\n\t */\n\tabstract protected function %s(int \$begin, int \$end);\n", $reducer[0])); +} + +// The tokens no reducer reads: they are only what the other tokens are +// written in between +$silent = []; +foreach (['T_PHPDOC_EOL', 'T_OPEN_PHPDOC', 'T_CLOSE_PHPDOC', 'T_COMMENT'] as $name) { + $silent[] = array_flip($result->lexer->names)[$name]; +} + +/** + * Whether the given token is one the lexer does not read on its own: a token + * it reads as another one, and only "TokenStream" tells apart, by its value or + * by its surroundings. See "doc/grammars/lexemes.pp3". + */ +function isClassified(string $name): bool +{ + return strncmp($name, 'T_KEYWORD_', 10) === 0 + || strncmp($name, 'T_TAG_', 6) === 0 + || ($name !== 'T_HORIZONTAL_WS' && substr($name, -3) === '_WS') + || $name === 'T_OPEN_ANGLE_BRACKET_HTML'; +} + +/** + * The pattern of "Lexer": every token it reads on its own, in the order the + * grammar declares them, marked by the identifier the grammar gives it. Along + * with it, the type of "Lexer" each of those tokens is. + */ +if (($result->lexer->names[0] ?? null) !== 'T_HORIZONTAL_WS') { + // "TokenStream::tokenize()" tells the whitespace by this very identifier + fwrite(STDERR, "T_HORIZONTAL_WS has to be the first token of doc/grammars/lexemes.pp3\n"); + exit(1); +} + +$lexerPatterns = []; +$lexerTypes = []; +foreach ($result->lexer->tokens as $id => $definition) { + $name = $result->lexer->names[$id] ?? null; + if ($name === null || isClassified($name)) { + continue; + } + + $type = 'PHPStan\\PhpDocParser\\Lexer\\Lexer::TOKEN_' . substr($name, 2); + if (!defined($type)) { + fwrite(STDERR, sprintf("The lexer has no token %s for %s\n", $type, $name)); + exit(1); + } + + $lexerPatterns[] = '(?:' . $definition->regex . ')(*MARK:' . $id . ')'; + $lexerTypes[$id] = constant($type); +} +$lexerPattern = '~' . implode('|', $lexerPatterns) . '~Asi'; + +[$methods, $constants] = (new ParserGenerator($parser, $choicePrediction, $reducerIds, $tokenIds, $silent))->generate($rules); + +$template = file_get_contents(__DIR__ . '/GeneratedParser.template.php'); +$generated = strtr($template, [ + '/*RULES*/[]' => export($rules), + '/*TOKENS*/[]' => export(array_flip($result->lexer->names)), + '/*EXPECTATIONS*/[]' => export($parser->expectations), + "/*LEXER_PATTERN*/''" => export($lexerPattern), + '/*LEXER_TYPES*/[]' => export($lexerTypes), + "\t/*CONSTANTS*/\n" => $constants, + "\t/*REDUCERS*/\n" => implode("\n", $abstracts), + "\t/*METHODS*/\n" => $methods, +]); + +if (!is_dir(dirname($output))) { + mkdir(dirname($output), 0777, true); +} + +file_put_contents($output, $generated); + +fwrite(STDERR, sprintf("%d rules written to %s\n", count($parser->grammar), $output)); diff --git a/tools/phplrt/composer.json b/tools/phplrt/composer.json index 75edac07..38f3e774 100644 --- a/tools/phplrt/composer.json +++ b/tools/phplrt/composer.json @@ -1,7 +1,7 @@ { "description": "Dev-only toolchain for compiling the phplrt grammars in doc/grammars into generated parsers.", "require": { - "phplrt/phplrt": "4.0.0-rc1" + "phplrt/phplrt": "4.2.4" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/tools/phplrt/composer.lock b/tools/phplrt/composer.lock index 8101c845..947246a9 100644 --- a/tools/phplrt/composer.lock +++ b/tools/phplrt/composer.lock @@ -4,93 +4,30 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "31e0382729bc7f44d23ee49bea1427eb", + "content-hash": "9c0c07f1d160a690b9a5bbb0cd1f061a", "packages": [ - { - "name": "laminas/laminas-code", - "version": "4.17.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-code.git", - "reference": "40d61e2899ec17c5d08bbc0a2d586b3ca17ab9bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/40d61e2899ec17c5d08bbc0a2d586b3ca17ab9bd", - "reference": "40d61e2899ec17c5d08bbc0a2d586b3ca17ab9bd", - "shasum": "" - }, - "require": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0.1", - "ext-phar": "*", - "laminas/laminas-coding-standard": "^3.0.0", - "laminas/laminas-stdlib": "^3.18.0", - "phpunit/phpunit": "^10.5.58", - "psalm/plugin-phpunit": "^0.19.0", - "vimeo/psalm": "^5.15.0" - }, - "suggest": { - "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", - "laminas/laminas-stdlib": "Laminas\\Stdlib component" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Code\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", - "homepage": "https://laminas.dev", - "keywords": [ - "code", - "laminas", - "laminasframework" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-code/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-code/issues", - "rss": "https://github.com/laminas/laminas-code/releases.atom", - "source": "https://github.com/laminas/laminas-code" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2025-11-01T09:38:14+00:00" - }, { "name": "phplrt/phplrt", - "version": "4.0.0-rc1", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/phplrt/phplrt.git", - "reference": "348cd166f750d0021aa95e3f87ea6f17e29b2147" + "reference": "3c95515be58c33df462dc65f9288b90e999c8ef3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phplrt/phplrt/zipball/348cd166f750d0021aa95e3f87ea6f17e29b2147", - "reference": "348cd166f750d0021aa95e3f87ea6f17e29b2147", + "url": "https://api.github.com/repos/phplrt/phplrt/zipball/3c95515be58c33df462dc65f9288b90e999c8ef3", + "reference": "3c95515be58c33df462dc65f9288b90e999c8ef3", "shasum": "" }, "require": { - "composer-runtime-api": "^2.2", + "composer-runtime-api": "^2.0", "ext-json": "*", "ext-pcre": "*", - "laminas/laminas-code": "^4.17", - "php": "^8.4", - "symfony/console": "^7.4|^8.0", - "twig/twig": "^3.28" + "php": "^8.1", + "psr/log": "^3.0", + "symfony/console": "^6.4|^7.0|^8.0", + "twig/twig": "^3.30" }, "provide": { "phplrt/lexer-contracts-implementation": "^4.0", @@ -121,16 +58,20 @@ "ext-intl": "*", "ext-mbstring": "*", "friendsofphp/php-cs-fixer": "^3.95", - "phpstan/phpstan": "^2.2", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^13.2", + "phpstan/phpstan": "^2.3", + "phpstan/phpstan-strict-rules": "^2.1", "symfony/var-dumper": "^6.4|^7.0|^8.0", - "symplify/monorepo-builder": "^12.7" + "testo/testo": "^0.10.45" }, "bin": [ "libs/components/compiler/bin/phplrt" ], "type": "library", + "extra": { + "skills": { + "source": "skills" + } + }, "autoload": { "files": [ "libs/components/source/src/polyfill.php" @@ -172,7 +113,7 @@ "issues": "https://github.com/phplrt/phplrt/issues", "source": "https://github.com/phplrt/phplrt" }, - "time": "2026-08-25T09:57:58+00:00" + "time": "2026-10-16T08:42:58+00:00" }, { "name": "psr/container", @@ -227,6 +168,56 @@ }, "time": "2021-11-05T16:47:00+00:00" }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, { "name": "symfony/console", "version": "v8.0.15", @@ -473,16 +464,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.41.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d" + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5cac8f4db97208823aa353f59a01faad2da52c75", + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75", "shasum": "" }, "require": { @@ -531,7 +522,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.41.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.43.0" }, "funding": [ { @@ -551,20 +542,20 @@ "type": "tidelift" } ], - "time": "2026-07-28T08:25:59+00:00" + "time": "2026-09-25T15:46:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.42.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502" + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/aa20edea75bd9c48cfecc8360922e5a6e5c44502", - "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/ebd57ccc7edb93d632e184efbe7693d2517bab3b", + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b", "shasum": "" }, "require": { @@ -616,7 +607,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.42.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.43.0" }, "funding": [ { @@ -636,20 +627,20 @@ "type": "tidelift" } ], - "time": "2026-08-07T06:33:24+00:00" + "time": "2026-09-23T22:02:09+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.38.2", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", "shasum": "" }, "require": { @@ -701,7 +692,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.43.0" }, "funding": [ { @@ -721,20 +712,20 @@ "type": "tidelift" } ], - "time": "2026-05-27T06:59:30+00:00" + "time": "2026-09-24T15:19:04+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.7.1", + "version": "v3.7.3", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0" + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0", - "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", "shasum": "" }, "require": { @@ -788,7 +779,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.7.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.3" }, "funding": [ { @@ -808,7 +799,7 @@ "type": "tidelift" } ], - "time": "2026-06-16T09:55:08+00:00" + "time": "2026-07-27T15:39:01+00:00" }, { "name": "symfony/string", @@ -902,16 +893,16 @@ }, { "name": "twig/twig", - "version": "v3.28.0", + "version": "v3.30.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b" + "reference": "8c737079b726af72ff8ef3c595be9f6a810ea1ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", - "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/8c737079b726af72ff8ef3c595be9f6a810ea1ef", + "reference": "8c737079b726af72ff8ef3c595be9f6a810ea1ef", "shasum": "" }, "require": { @@ -966,7 +957,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.28.0" + "source": "https://github.com/twigphp/Twig/tree/v3.30.0" }, "funding": [ { @@ -978,7 +969,7 @@ "type": "tidelift" } ], - "time": "2026-07-03T20:44:34+00:00" + "time": "2026-09-25T13:20:01+00:00" } ], "packages-dev": [],