1<?php
2
3namespace Shellbox\ShellParser;
4
5
6	use WikiPEG\InternalError;
7	// @phan-file-suppress PhanUnusedGotoLabel
8	// @phan-file-suppress PhanNoopSwitchCases
9	// @phan-file-suppress PhanTypeMismatchArgument
10	// @phan-file-suppress PhanTypeComparisonFromArray
11
12
13class PEGParser extends \WikiPEG\PEGParserBase {
14  // initializer
15
16  	/**
17  	 * Overridable tree node constructor
18  	 *
19  	 * @stable to override
20  	 * @param string $type
21  	 * @param array|Node|string $contents
22  	 * @return Node
23  	 */
24  	protected function node( $type, $contents ) {
25  		return new Node( $type, $contents );
26  	}
27
28  	/**
29  	 * Combine arrays and non-array items into a single flat array.
30  	 *
31  	 * @param array|Node|string|null ...$items
32  	 * @return array
33  	 * @phan-return array<Node|string>
34  	 */
35  	private function merge( ...$items ) {
36  		if ( !$items ) {
37  			return [];
38  		}
39  		$mergeArgs = [];
40  		foreach ( $items as $item ) {
41  			if ( $item !== null ) {
42  				if ( !is_array( $item ) ) {
43  					$mergeArgs[] = [ $item ];
44  				} else {
45  					$mergeArgs[] = $item;
46  				}
47  			}
48  		}
49  		return array_merge( ...$mergeArgs );
50  	}
51
52
53  // cache init
54    protected $cache = [];
55
56  // expectations
57  protected $expectations = [
58    0 => ["type" => "end", "description" => "end of input"],
59    1 => ["type" => "literal", "value" => "\x0a", "description" => "\"\\n\""],
60    2 => ["type" => "class", "value" => "[ \\t\\v\\r\\f]", "description" => "[ \\t\\v\\r\\f]"],
61    3 => ["type" => "literal", "value" => "#", "description" => "\"#\""],
62    4 => ["type" => "class", "value" => "[^\\n]", "description" => "[^\\n]"],
63    5 => ["type" => "literal", "value" => "&&", "description" => "\"&&\""],
64    6 => ["type" => "literal", "value" => "||", "description" => "\"||\""],
65    7 => ["type" => "literal", "value" => "&", "description" => "\"&\""],
66    8 => ["type" => "literal", "value" => ";", "description" => "\";\""],
67    9 => ["type" => "literal", "value" => "!", "description" => "\"!\""],
68    10 => ["type" => "literal", "value" => ";;", "description" => "\";;\""],
69    11 => ["type" => "literal", "value" => "|", "description" => "\"|\""],
70    12 => ["type" => "class", "value" => "[_a-zA-Z]", "description" => "[_a-zA-Z]"],
71    13 => ["type" => "class", "value" => "[_a-zA-Z0-9]", "description" => "[_a-zA-Z0-9]"],
72    14 => ["type" => "literal", "value" => "(", "description" => "\"(\""],
73    15 => ["type" => "literal", "value" => ")", "description" => "\")\""],
74    16 => ["type" => "literal", "value" => "=", "description" => "\"=\""],
75    17 => ["type" => "literal", "value" => "{", "description" => "\"{\""],
76    18 => ["type" => "literal", "value" => "}", "description" => "\"}\""],
77    19 => ["type" => "literal", "value" => "for", "description" => "\"for\""],
78    20 => ["type" => "literal", "value" => "case", "description" => "\"case\""],
79    21 => ["type" => "literal", "value" => "esac", "description" => "\"esac\""],
80    22 => ["type" => "literal", "value" => "if", "description" => "\"if\""],
81    23 => ["type" => "literal", "value" => "then", "description" => "\"then\""],
82    24 => ["type" => "literal", "value" => "fi", "description" => "\"fi\""],
83    25 => ["type" => "literal", "value" => "while", "description" => "\"while\""],
84    26 => ["type" => "literal", "value" => "until", "description" => "\"until\""],
85    27 => ["type" => "class", "value" => "[0-9]", "description" => "[0-9]"],
86    28 => ["type" => "literal", "value" => "'", "description" => "\"'\""],
87    29 => ["type" => "class", "value" => "[^']", "description" => "[^']"],
88    30 => ["type" => "literal", "value" => "\"", "description" => "\"\\\"\""],
89    31 => ["type" => "literal", "value" => "\\", "description" => "\"\\\\\""],
90    32 => ["type" => "class", "value" => "[^\"`\$\\\\]", "description" => "[^\"`\$\\\\]"],
91    33 => ["type" => "literal", "value" => "`", "description" => "\"`\""],
92    34 => ["type" => "literal", "value" => "\$", "description" => "\"\$\""],
93    35 => ["type" => "class", "value" => "[^`\$\\\\]", "description" => "[^`\$\\\\]"],
94    36 => ["type" => "class", "value" => "[^'\"\\\\`\$ \\t\\v\\r\\f\\n&|;<>(){}]", "description" => "[^'\"\\\\`\$ \\t\\v\\r\\f\\n&|;<>(){}]"],
95    37 => ["type" => "class", "value" => "[^'\"\\\\`\$ \\t\\v\\r\\f\\n&|;<>()]", "description" => "[^'\"\\\\`\$ \\t\\v\\r\\f\\n&|;<>()]"],
96    38 => ["type" => "literal", "value" => "else", "description" => "\"else\""],
97    39 => ["type" => "literal", "value" => "elif", "description" => "\"elif\""],
98    40 => ["type" => "literal", "value" => "do", "description" => "\"do\""],
99    41 => ["type" => "literal", "value" => "done", "description" => "\"done\""],
100    42 => ["type" => "literal", "value" => "in", "description" => "\"in\""],
101    43 => ["type" => "literal", "value" => "<&", "description" => "\"<&\""],
102    44 => ["type" => "literal", "value" => "<>", "description" => "\"<>\""],
103    45 => ["type" => "literal", "value" => "<", "description" => "\"<\""],
104    46 => ["type" => "literal", "value" => ">&", "description" => "\">&\""],
105    47 => ["type" => "literal", "value" => ">>", "description" => "\">>\""],
106    48 => ["type" => "literal", "value" => ">|", "description" => "\">|\""],
107    49 => ["type" => "literal", "value" => ">", "description" => "\">\""],
108    50 => ["type" => "literal", "value" => "<<-", "description" => "\"<<-\""],
109    51 => ["type" => "literal", "value" => "<<", "description" => "\"<<\""],
110    52 => ["type" => "class", "value" => "[\$`\"\\\\\\n]", "description" => "[\$`\"\\\\\\n]"],
111    53 => ["type" => "class", "value" => "[\$\\\\]", "description" => "[\$\\\\]"],
112    54 => ["type" => "literal", "value" => "\\`", "description" => "\"\\\\`\""],
113    55 => ["type" => "class", "value" => "[@*#?\\-\$!0]", "description" => "[@*#?\\-\$!0]"],
114    56 => ["type" => "class", "value" => "[1-9]", "description" => "[1-9]"],
115    57 => ["type" => "literal", "value" => "((", "description" => "\"((\""],
116    58 => ["type" => "literal", "value" => "))", "description" => "\"))\""],
117    59 => ["type" => "literal", "value" => ":", "description" => "\":\""],
118    60 => ["type" => "class", "value" => "[\\-=?+]", "description" => "[\\-=?+]"],
119    61 => ["type" => "literal", "value" => "%%", "description" => "\"%%\""],
120    62 => ["type" => "literal", "value" => "##", "description" => "\"##\""],
121    63 => ["type" => "class", "value" => "[%#\\-=?+]", "description" => "[%#\\-=?+]"],
122  ];
123
124  // actions
125  private function a0($commands) {
126
127  		return $this->node( 'program', $commands );
128
129  }
130  private function a1() {
131
132  		return $this->node( 'program', [] );
133
134  }
135  private function a2($c) {
136
137  			return $c;
138
139  }
140  private function a3($item, $separator) {
141
142  				if ( $separator && $separator[0] === '&' ) {
143  					return $this->node( 'background', $item );
144  				} else {
145  					return $item;
146  				}
147
148  }
149  private function a4($nodes, $last) {
150
151  			if ( $last ) {
152                  $nodes[] = $last;
153              }
154              if ( count( $nodes ) > 1 ) {
155                  return $this->node( 'list', $nodes );
156              } else {
157                  return $nodes[0];
158              }
159
160  }
161  private function a5($list) {
162
163  	return $this->node( 'complete_command', $list );
164
165  }
166  private function a6($first, $pipeline) {
167
168  			return $this->node( 'and_if', $pipeline );
169
170  }
171  private function a7($first, $pipeline) {
172
173  			return $this->node( 'or_if', $pipeline );
174
175  }
176  private function a8($first, $rest) {
177
178  	return $this->merge( $first, $rest );
179
180  }
181  private function a9($bang, $pipeline) {
182
183  	if ( $bang !== null ) {
184  		return $this->node( 'bang', $pipeline );
185  	} else {
186  		return $pipeline;
187  	}
188
189  }
190  private function a10($first, $command) {
191
192  			return $command;
193
194  }
195  private function a11($first, $rest) {
196
197  	if ( count( $rest ) ) {
198  		return $this->node( 'pipeline', $this->merge( $first, $rest ) );
199  	} else {
200  		return $first;
201  	}
202
203  }
204  private function a12($c, $r) {
205
206  		if ( $r !== null ) {
207  			return $this->merge( $c, $r );
208  		} else {
209  			return $c;
210  		}
211
212  }
213  private function a13($fname, $body) {
214
215  	return $this->node( 'function_definition',
216  		$this->merge( $this->node( 'function_name', $fname ), $body ) );
217
218  }
219  private function a14($prefix, $word, $suffix) {
220
221  		$contents = [ $prefix, $word ];
222  		if ( $suffix !== null ) {
223  			$contents = array_merge( $contents, $suffix );
224  		}
225  		return $this->node( 'simple_command', $contents );
226
227  }
228  private function a15($prefix) {
229
230  		return $this->node( 'simple_command', [ $prefix ] );
231
232  }
233  private function a16($name, $suffix) {
234
235  		$contents = [ $name ];
236  		if ( $suffix ) {
237  			$contents = array_merge( $contents, $suffix );
238  		}
239  		return $this->node( 'simple_command', $contents );
240
241  }
242  private function a17($c, $r) {
243
244  	if ( $r !== null ) {
245  		return $this->merge( $c, $r );
246  	} else {
247  		return $c;
248  	}
249
250  }
251  private function a18($contents) {
252
253  	return $this->node( 'cmd_prefix', $contents );
254
255  }
256  private function a19($parts) {
257
258  	return $this->node( 'word', $parts );
259
260  }
261  private function a20($word) {
262
263  	return $word;
264
265  }
266  private function a21($list) {
267
268  	return $this->node( 'brace_group', $list );
269
270  }
271  private function a22($list) {
272
273  	return $this->node( 'subshell', $list );
274
275  }
276  private function a23($name, $wordlist, $do_group) {
277
278  			return $this->node( 'for', [ $name, $this->node( 'in', $wordlist ?: [] ), $do_group ] );
279
280  }
281  private function a24($name, $do_group) {
282
283  			return $this->node( 'for', [ $name, $do_group ] );
284
285  }
286  private function a25($word, $list_esac) {
287
288  	if ( is_array( $list_esac ) ) {
289  		$list = $list_esac[0];
290  	} else {
291  		$list = [];
292  	}
293  	return $this->node( 'case', [ $word, $this->node( 'in', $list ) ] );
294
295  }
296  private function a26($condition, $consequent, $else_part) {
297
298  	$contents = [
299  		$this->node( 'condition', $condition ),
300  		$this->node( 'consequent', $consequent )
301  	];
302  	if ( $else_part !== null ) {
303  		$contents = $this->merge( $contents, $else_part );
304  	}
305  	return $this->node( 'if', $contents );
306
307  }
308  private function a27($list, $body) {
309
310  	return $this->node( 'while', [
311  		$this->node( 'condition', $list ),
312  		$body
313  	] );
314
315  }
316  private function a28($list, $body) {
317
318  	return $this->node( 'until', [
319  		$this->node( 'condition', $list ),
320  		$body
321  	] );
322
323  }
324  private function a29($number, $file_or_here) {
325
326  		$contents = [];
327  		if ( $number !== null ) {
328  			$contents[] = $this->node( 'io_subject', $number );
329  		}
330  		$contents[] = $file_or_here;
331  		return $this->node( 'io_redirect', $contents );
332
333  }
334  private function a30($name, $word) {
335
336  	return $this->node( 'assignment', [ $this->node( 'name', $name ), $word ] );
337
338  }
339  private function a31($term, $separator) {
340
341  			if ( $separator && $separator[0] === '&' ) {
342  				return $this->node( 'background', $term );
343  			} else {
344  				return $term;
345  			}
346
347  }
348  private function a32($terms, $last) {
349
350  		if ( $last ) {
351  			$terms[] = $last;
352  		}
353  		return $terms;
354
355  }
356  private function a33($term) {
357
358  		if ( $term === null ) {
359  			// Phan is convinced $term may be null, not sure how
360  			return [];
361  		} else {
362  			return $term;
363  		}
364
365  }
366  private function a34($name) {
367
368  	return $name;
369
370  }
371  private function a35($list) {
372
373  	return $this->node( 'do', $list );
374
375  }
376  private function a36($list, $item) {
377
378  		$list[] = $item;
379  		return $list;
380
381  }
382  private function a37($item) {
383
384  		return [ $item ];
385
386  }
387  private function a38($condition, $consequent, $else_part) {
388
389  		$contents = [
390  			$this->node( 'elif_condition', $condition ),
391  			$this->node( 'elif_consequent', $consequent )
392  		];
393  		if ( $else_part !== null ) {
394  			$contents = $this->merge( $contents, $else_part );
395  		}
396  		return $contents;
397
398  }
399  private function a39($alternative) {
400
401  		return [ $this->node( 'else', $alternative ) ];
402
403  }
404  private function a40($filename) {
405
406  		return $this->node( 'duplicate_input', $filename );
407
408  }
409  private function a41($filename) {
410
411  		return $this->node( 'read_and_write', $filename );
412
413  }
414  private function a42($filename) {
415
416  		return $this->node( 'input', $filename );
417
418  }
419  private function a43($filename) {
420
421  		return $this->node( 'duplicate_output', $filename );
422
423  }
424  private function a44($filename) {
425
426  		return $this->node( 'append_output', $filename );
427
428  }
429  private function a45($filename) {
430
431  		return $this->node( 'clobber', $filename );
432
433  }
434  private function a46($filename) {
435
436  		return $this->node( 'output', $filename );
437
438  }
439  private function a47() {
440   return 'io_here_strip';
441  }
442  private function a48() {
443   return 'io_here';
444  }
445  private function a49($op, $end) {
446
447  	// TODO: this is quite complicated to implement, especially given the way
448  	// the parser is structured.
449  	throw new UnimplementedError( 'heredoc is not implemented' );
450  	// For phan
451  	return $this->node( 'io_here', '' );
452
453  }
454  private function a50($contents) {
455
456  	return $this->node( 'single_quote', $contents );
457
458  }
459  private function a51($contents) {
460
461  	return $this->node( 'double_quote', $contents );
462
463  }
464  private function a52($contents) {
465
466  	return $this->node( 'bare_escape', $contents );
467
468  }
469  private function a53($parts) {
470
471  	return $this->node( 'backquote', $parts );
472
473  }
474  private function a54($contents) {
475
476  	return $contents;
477
478  }
479  private function a55($plain) {
480
481  	return $this->node( 'unquoted_literal', $plain );
482
483  }
484  private function a56($pattern, $list) {
485
486  		return $this->node( 'case_item', [
487  			$pattern,
488  			$this->node( 'case_consequent', $list )
489  		] );
490
491  }
492  private function a57($pattern) {
493
494  		return $this->node( 'case_item', $pattern );
495
496  }
497  private function a58($pattern) {
498
499  		return $this->node( 'case_item', [ $pattern ] );
500
501  }
502  private function a59($contents) {
503
504  	return $this->node( 'dquoted_escape', $contents );
505
506  }
507  private function a60($contents) {
508
509  	return $this->node( 'backquoted_escape', $contents );
510
511  }
512  private function a61($parts) {
513
514  	return $this->node( 'double_backquote', $parts );
515
516  }
517  private function a62($contents) {
518
519  	return $this->node( 'special_parameter', $contents );
520
521  }
522  private function a63($contents) {
523
524  	return $this->node( 'positional_parameter', $contents );
525
526  }
527  private function a64($words) {
528
529  	return $this->node( 'arithmetic_expansion', $words );
530
531  }
532  private function a65($command) {
533
534  	return $this->node( 'command_expansion', $command );
535
536  }
537  private function a66($name) {
538
539  	return $this->node( 'named_parameter', $name );
540
541  }
542  private function a67($first, $rest) {
543
544  	$patterns = [ $first ];
545  	foreach ( $rest as $pattern ) {
546  		$patterns[] = $pattern[1];
547  	}
548  	return $this->node( 'case_pattern', $patterns );
549
550  }
551  private function a68($parameter, $operator, $word) {
552
553  	$names = [
554  		':-' => 'use_default',
555  		'-' => 'use_default_unset',
556  		':=' => 'assign_default',
557  		'=' => 'assign_default_unset',
558  		':?' => 'indicate_error',
559  		'?' => 'indicate_error_unset',
560  		':+' => 'use_alternative',
561  		'+' => 'use_alternative_unset',
562  		'%' => 'remove_smallest_suffix',
563  		'%%' => 'remove_largest_suffix',
564  		'#' => 'remove_smallest_prefix',
565  		'##' => 'remove_largest_prefix'
566  	];
567  	if ( !isset( $names[$operator] ) ) {
568  		throw new InternalError( "Unable to find operator \"$operator\"" );
569  	}
570  	return $this->node( $names[$operator], [ $parameter, $word ?? '' ] );
571
572  }
573  private function a69($parameter) {
574
575  	return $this->node( 'string_length', $parameter );
576
577  }
578  private function a70($parameter) {
579
580  	return $this->node( 'braced_parameter_expansion', $parameter );
581
582  }
583  private function a71($parameter) {
584
585  	return $this->node( 'positional_parameter', $parameter );
586
587  }
588
589  // generated
590  private function parseprogram($silence) {
591    $key = json_encode([208, $this->currPos]);
592    $cached = $this->cache[$key] ?? null;
593      if ($cached) {
594        $this->currPos = $cached['nextPos'];
595
596        return $cached['result'];
597      }
598
599    // start choice_1
600    $p2 = $this->currPos;
601    // start seq_1
602    $p3 = $this->currPos;
603    $r4 = $this->discardlinebreak($silence);
604    if ($r4===self::$FAILED) {
605      $r1 = self::$FAILED;
606      goto seq_1;
607    }
608    $r5 = $this->parsecomplete_commands($silence);
609    // commands <- $r5
610    if ($r5===self::$FAILED) {
611      $this->currPos = $p3;
612      $r1 = self::$FAILED;
613      goto seq_1;
614    }
615    $r6 = $this->discardlinebreak($silence);
616    if ($r6===self::$FAILED) {
617      $this->currPos = $p3;
618      $r1 = self::$FAILED;
619      goto seq_1;
620    }
621    $r1 = true;
622    seq_1:
623    if ($r1!==self::$FAILED) {
624      $this->savedPos = $p2;
625      $r1 = $this->a0($r5);
626      goto choice_1;
627    }
628    // free $p3
629    $p3 = $this->currPos;
630    $r1 = $this->discardlinebreak($silence);
631    if ($r1!==self::$FAILED) {
632      $this->savedPos = $p3;
633      $r1 = $this->a1();
634    }
635    choice_1:
636    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
637
638    $this->cache[$key] = $cached;
639    return $r1;
640  }
641  private function discardlinebreak($silence) {
642    $key = json_encode([285, $this->currPos]);
643    $cached = $this->cache[$key] ?? null;
644      if ($cached) {
645        $this->currPos = $cached['nextPos'];
646
647        return $cached['result'];
648      }
649
650    $r1 = $this->discardnewline_list($silence);
651    if ($r1===self::$FAILED) {
652      $r1 = null;
653    }
654    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
655
656    $this->cache[$key] = $cached;
657    return $r1;
658  }
659  private function parsecomplete_commands($silence) {
660    $key = json_encode([210, $this->currPos]);
661    $cached = $this->cache[$key] ?? null;
662      if ($cached) {
663        $this->currPos = $cached['nextPos'];
664
665        return $cached['result'];
666      }
667
668    $r1 = [];
669    for (;;) {
670      // start choice_1
671      $p3 = $this->currPos;
672      // start seq_1
673      $p4 = $this->currPos;
674      $r5 = $this->parsecomplete_command($silence, 0x0);
675      // c <- $r5
676      if ($r5===self::$FAILED) {
677        $r2 = self::$FAILED;
678        goto seq_1;
679      }
680      $r6 = $this->discardnewline_list($silence);
681      if ($r6===self::$FAILED) {
682        $this->currPos = $p4;
683        $r2 = self::$FAILED;
684        goto seq_1;
685      }
686      $r2 = true;
687      seq_1:
688      if ($r2!==self::$FAILED) {
689        $this->savedPos = $p3;
690        $r2 = $this->a2($r5);
691        goto choice_1;
692      }
693      // free $p4
694      $r2 = $this->parsecomplete_command($silence, 0x0);
695      choice_1:
696      if ($r2!==self::$FAILED) {
697        $r1[] = $r2;
698      } else {
699        break;
700      }
701    }
702    // free $r2
703    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
704
705    $this->cache[$key] = $cached;
706    return $r1;
707  }
708  private function discardnewline_list($silence) {
709    $key = json_encode([283, $this->currPos]);
710    $cached = $this->cache[$key] ?? null;
711      if ($cached) {
712        $this->currPos = $cached['nextPos'];
713
714        return $cached['result'];
715      }
716
717    $r1 = self::$FAILED;
718    for (;;) {
719      $r2 = $this->discardNEWLINE($silence);
720      if ($r2!==self::$FAILED) {
721        $r1 = true;
722      } else {
723        break;
724      }
725    }
726    // free $r2
727    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
728
729    $this->cache[$key] = $cached;
730    return $r1;
731  }
732  private function parsecomplete_command($silence, $boolParams) {
733    $key = json_encode([212, $this->currPos, $boolParams & 0x1]);
734    $cached = $this->cache[$key] ?? null;
735      if ($cached) {
736        $this->currPos = $cached['nextPos'];
737
738        return $cached['result'];
739      }
740
741    $p2 = $this->currPos;
742    // start seq_1
743    $p3 = $this->currPos;
744    $r4 = $this->discardOWS($silence);
745    if ($r4===self::$FAILED) {
746      $r1 = self::$FAILED;
747      goto seq_1;
748    }
749    // start choice_1
750    $p6 = $this->currPos;
751    // start seq_2
752    $p7 = $this->currPos;
753    $r8 = [];
754    for (;;) {
755      $p10 = $this->currPos;
756      // start seq_3
757      $p11 = $this->currPos;
758      $r12 = $this->parseand_or($silence, $boolParams);
759      // item <- $r12
760      if ($r12===self::$FAILED) {
761        $r9 = self::$FAILED;
762        goto seq_3;
763      }
764      $p14 = $this->currPos;
765      $r13 = $this->discardseparator_op($silence);
766      // separator <- $r13
767      if ($r13!==self::$FAILED) {
768        $r13 = substr($this->input, $p14, $this->currPos - $p14);
769      } else {
770        $r13 = self::$FAILED;
771        $this->currPos = $p11;
772        $r9 = self::$FAILED;
773        goto seq_3;
774      }
775      // free $p14
776      $r9 = true;
777      seq_3:
778      if ($r9!==self::$FAILED) {
779        $this->savedPos = $p10;
780        $r9 = $this->a3($r12, $r13);
781        $r8[] = $r9;
782      } else {
783        break;
784      }
785      // free $p11
786    }
787    if (count($r8) === 0) {
788      $r8 = self::$FAILED;
789    }
790    // nodes <- $r8
791    if ($r8===self::$FAILED) {
792      $r5 = self::$FAILED;
793      goto seq_2;
794    }
795    // free $r9
796    $r9 = $this->parseand_or($silence, $boolParams);
797    if ($r9===self::$FAILED) {
798      $r9 = null;
799    }
800    // last <- $r9
801    $r5 = true;
802    seq_2:
803    if ($r5!==self::$FAILED) {
804      $this->savedPos = $p6;
805      $r5 = $this->a4($r8, $r9);
806      goto choice_1;
807    }
808    // free $p7
809    $r5 = $this->parseand_or($silence, $boolParams);
810    choice_1:
811    // list <- $r5
812    if ($r5===self::$FAILED) {
813      $this->currPos = $p3;
814      $r1 = self::$FAILED;
815      goto seq_1;
816    }
817    $r1 = true;
818    seq_1:
819    if ($r1!==self::$FAILED) {
820      $this->savedPos = $p2;
821      $r1 = $this->a5($r5);
822    }
823    // free $p3
824    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
825
826    $this->cache[$key] = $cached;
827    return $r1;
828  }
829  private function discardNEWLINE($silence) {
830    $key = json_encode([413, $this->currPos]);
831    $cached = $this->cache[$key] ?? null;
832      if ($cached) {
833        $this->currPos = $cached['nextPos'];
834
835        return $cached['result'];
836      }
837
838    // start seq_1
839    $p1 = $this->currPos;
840    if (($this->input[$this->currPos] ?? null) === "\x0a") {
841      $this->currPos++;
842      $r3 = "\x0a";
843    } else {
844      if (!$silence) {$this->fail(1);}
845      $r3 = self::$FAILED;
846      $r2 = self::$FAILED;
847      goto seq_1;
848    }
849    $r4 = $this->discardOWS($silence);
850    if ($r4===self::$FAILED) {
851      $this->currPos = $p1;
852      $r2 = self::$FAILED;
853      goto seq_1;
854    }
855    $r2 = true;
856    seq_1:
857    // free $r2,$p1
858    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
859
860    $this->cache[$key] = $cached;
861    return $r2;
862  }
863  private function discardOWS($silence) {
864    $key = json_encode([361, $this->currPos]);
865    $cached = $this->cache[$key] ?? null;
866      if ($cached) {
867        $this->currPos = $cached['nextPos'];
868
869        return $cached['result'];
870      }
871
872    // start seq_1
873    $p1 = $this->currPos;
874    for (;;) {
875      if (strspn($this->input, " \x09\x0b\x0d\x0c", $this->currPos, 1) !== 0) {
876        $r4 = $this->input[$this->currPos++];
877      } else {
878        $r4 = self::$FAILED;
879        if (!$silence) {$this->fail(2);}
880        break;
881      }
882    }
883    // free $r4
884    $r3 = true;
885    if ($r3===self::$FAILED) {
886      $r2 = self::$FAILED;
887      goto seq_1;
888    }
889    // free $r3
890    // start seq_2
891    $p5 = $this->currPos;
892    if (($this->input[$this->currPos] ?? null) === "#") {
893      $this->currPos++;
894      $r4 = "#";
895    } else {
896      if (!$silence) {$this->fail(3);}
897      $r4 = self::$FAILED;
898      $r3 = self::$FAILED;
899      goto seq_2;
900    }
901    for (;;) {
902      $r7 = self::charAt($this->input, $this->currPos);
903      if ($r7 !== '' && !($r7 === "\x0a")) {
904        $this->currPos += strlen($r7);
905      } else {
906        $r7 = self::$FAILED;
907        if (!$silence) {$this->fail(4);}
908        break;
909      }
910    }
911    // free $r7
912    $r6 = true;
913    if ($r6===self::$FAILED) {
914      $this->currPos = $p5;
915      $r3 = self::$FAILED;
916      goto seq_2;
917    }
918    // free $r6
919    $r3 = true;
920    seq_2:
921    if ($r3===self::$FAILED) {
922      $r3 = null;
923    }
924    // free $p5
925    $r2 = true;
926    seq_1:
927    // free $r2,$p1
928    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
929
930    $this->cache[$key] = $cached;
931    return $r2;
932  }
933  private function parseand_or($silence, $boolParams) {
934    $key = json_encode([214, $this->currPos, $boolParams & 0x1]);
935    $cached = $this->cache[$key] ?? null;
936      if ($cached) {
937        $this->currPos = $cached['nextPos'];
938
939        return $cached['result'];
940      }
941
942    $p2 = $this->currPos;
943    // start seq_1
944    $p3 = $this->currPos;
945    $r4 = $this->parsepipeline($silence, $boolParams);
946    // first <- $r4
947    if ($r4===self::$FAILED) {
948      $r1 = self::$FAILED;
949      goto seq_1;
950    }
951    $r5 = [];
952    for (;;) {
953      // start choice_1
954      $p7 = $this->currPos;
955      // start seq_2
956      $p8 = $this->currPos;
957      $r9 = $this->discardAND_IF($silence);
958      if ($r9===self::$FAILED) {
959        $r6 = self::$FAILED;
960        goto seq_2;
961      }
962      $r10 = $this->discardlinebreak($silence);
963      if ($r10===self::$FAILED) {
964        $this->currPos = $p8;
965        $r6 = self::$FAILED;
966        goto seq_2;
967      }
968      $r11 = $this->parsepipeline($silence, $boolParams);
969      // pipeline <- $r11
970      if ($r11===self::$FAILED) {
971        $this->currPos = $p8;
972        $r6 = self::$FAILED;
973        goto seq_2;
974      }
975      $r6 = true;
976      seq_2:
977      if ($r6!==self::$FAILED) {
978        $this->savedPos = $p7;
979        $r6 = $this->a6($r4, $r11);
980        goto choice_1;
981      }
982      // free $p8
983      $p8 = $this->currPos;
984      // start seq_3
985      $p12 = $this->currPos;
986      $r13 = $this->discardOR_IF($silence);
987      if ($r13===self::$FAILED) {
988        $r6 = self::$FAILED;
989        goto seq_3;
990      }
991      $r14 = $this->discardlinebreak($silence);
992      if ($r14===self::$FAILED) {
993        $this->currPos = $p12;
994        $r6 = self::$FAILED;
995        goto seq_3;
996      }
997      $r15 = $this->parsepipeline($silence, $boolParams);
998      // pipeline <- $r15
999      if ($r15===self::$FAILED) {
1000        $this->currPos = $p12;
1001        $r6 = self::$FAILED;
1002        goto seq_3;
1003      }
1004      $r6 = true;
1005      seq_3:
1006      if ($r6!==self::$FAILED) {
1007        $this->savedPos = $p8;
1008        $r6 = $this->a7($r4, $r15);
1009        goto choice_1;
1010      }
1011      // free $p12
1012      $r6 = $this->parsepipeline($silence, $boolParams);
1013      choice_1:
1014      if ($r6!==self::$FAILED) {
1015        $r5[] = $r6;
1016      } else {
1017        break;
1018      }
1019    }
1020    // rest <- $r5
1021    // free $r6
1022    $r1 = true;
1023    seq_1:
1024    if ($r1!==self::$FAILED) {
1025      $this->savedPos = $p2;
1026      $r1 = $this->a8($r4, $r5);
1027    }
1028    // free $p3
1029    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1030
1031    $this->cache[$key] = $cached;
1032    return $r1;
1033  }
1034  private function discardseparator_op($silence) {
1035    $key = json_encode([287, $this->currPos]);
1036    $cached = $this->cache[$key] ?? null;
1037      if ($cached) {
1038        $this->currPos = $cached['nextPos'];
1039
1040        return $cached['result'];
1041      }
1042
1043    // start choice_1
1044    $r1 = $this->discardAND($silence);
1045    if ($r1!==self::$FAILED) {
1046      goto choice_1;
1047    }
1048    $r1 = $this->discardSEMI($silence);
1049    choice_1:
1050    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1051
1052    $this->cache[$key] = $cached;
1053    return $r1;
1054  }
1055  private function parsepipeline($silence, $boolParams) {
1056    $key = json_encode([216, $this->currPos, $boolParams & 0x1]);
1057    $cached = $this->cache[$key] ?? null;
1058      if ($cached) {
1059        $this->currPos = $cached['nextPos'];
1060
1061        return $cached['result'];
1062      }
1063
1064    $p2 = $this->currPos;
1065    // start seq_1
1066    $p3 = $this->currPos;
1067    $r4 = $this->parseBang($silence);
1068    if ($r4===self::$FAILED) {
1069      $r4 = null;
1070    }
1071    // bang <- $r4
1072    $r5 = $this->parsepipe_sequence($silence, $boolParams);
1073    // pipeline <- $r5
1074    if ($r5===self::$FAILED) {
1075      $this->currPos = $p3;
1076      $r1 = self::$FAILED;
1077      goto seq_1;
1078    }
1079    $r1 = true;
1080    seq_1:
1081    if ($r1!==self::$FAILED) {
1082      $this->savedPos = $p2;
1083      $r1 = $this->a9($r4, $r5);
1084    }
1085    // free $p3
1086    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1087
1088    $this->cache[$key] = $cached;
1089    return $r1;
1090  }
1091  private function discardAND_IF($silence) {
1092    $key = json_encode([293, $this->currPos]);
1093    $cached = $this->cache[$key] ?? null;
1094      if ($cached) {
1095        $this->currPos = $cached['nextPos'];
1096
1097        return $cached['result'];
1098      }
1099
1100    // start seq_1
1101    $p1 = $this->currPos;
1102    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "&&", $this->currPos, 2, false) === 0) {
1103      $r3 = "&&";
1104      $this->currPos += 2;
1105    } else {
1106      if (!$silence) {$this->fail(5);}
1107      $r3 = self::$FAILED;
1108      $r2 = self::$FAILED;
1109      goto seq_1;
1110    }
1111    $r4 = $this->discardOWS($silence);
1112    if ($r4===self::$FAILED) {
1113      $this->currPos = $p1;
1114      $r2 = self::$FAILED;
1115      goto seq_1;
1116    }
1117    $r2 = true;
1118    seq_1:
1119    // free $r2,$p1
1120    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1121
1122    $this->cache[$key] = $cached;
1123    return $r2;
1124  }
1125  private function discardOR_IF($silence) {
1126    $key = json_encode([295, $this->currPos]);
1127    $cached = $this->cache[$key] ?? null;
1128      if ($cached) {
1129        $this->currPos = $cached['nextPos'];
1130
1131        return $cached['result'];
1132      }
1133
1134    // start seq_1
1135    $p1 = $this->currPos;
1136    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "||", $this->currPos, 2, false) === 0) {
1137      $r3 = "||";
1138      $this->currPos += 2;
1139    } else {
1140      if (!$silence) {$this->fail(6);}
1141      $r3 = self::$FAILED;
1142      $r2 = self::$FAILED;
1143      goto seq_1;
1144    }
1145    $r4 = $this->discardOWS($silence);
1146    if ($r4===self::$FAILED) {
1147      $this->currPos = $p1;
1148      $r2 = self::$FAILED;
1149      goto seq_1;
1150    }
1151    $r2 = true;
1152    seq_1:
1153    // free $r2,$p1
1154    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1155
1156    $this->cache[$key] = $cached;
1157    return $r2;
1158  }
1159  private function discardAND($silence) {
1160    $key = json_encode([347, $this->currPos]);
1161    $cached = $this->cache[$key] ?? null;
1162      if ($cached) {
1163        $this->currPos = $cached['nextPos'];
1164
1165        return $cached['result'];
1166      }
1167
1168    // start seq_1
1169    $p1 = $this->currPos;
1170    $p3 = $this->currPos;
1171    $r4 = $this->discardAND_IF(true);
1172    if ($r4 === self::$FAILED) {
1173      $r4 = false;
1174    } else {
1175      $r4 = self::$FAILED;
1176      $this->currPos = $p3;
1177      $r2 = self::$FAILED;
1178      goto seq_1;
1179    }
1180    // free $p3
1181    if (($this->input[$this->currPos] ?? null) === "&") {
1182      $this->currPos++;
1183      $r5 = "&";
1184    } else {
1185      if (!$silence) {$this->fail(7);}
1186      $r5 = self::$FAILED;
1187      $this->currPos = $p1;
1188      $r2 = self::$FAILED;
1189      goto seq_1;
1190    }
1191    $r6 = $this->discardOWS($silence);
1192    if ($r6===self::$FAILED) {
1193      $this->currPos = $p1;
1194      $r2 = self::$FAILED;
1195      goto seq_1;
1196    }
1197    $r2 = true;
1198    seq_1:
1199    // free $r2,$p1
1200    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1201
1202    $this->cache[$key] = $cached;
1203    return $r2;
1204  }
1205  private function discardSEMI($silence) {
1206    $key = json_encode([349, $this->currPos]);
1207    $cached = $this->cache[$key] ?? null;
1208      if ($cached) {
1209        $this->currPos = $cached['nextPos'];
1210
1211        return $cached['result'];
1212      }
1213
1214    // start seq_1
1215    $p1 = $this->currPos;
1216    $p3 = $this->currPos;
1217    $r4 = $this->discardDSEMI(true);
1218    if ($r4 === self::$FAILED) {
1219      $r4 = false;
1220    } else {
1221      $r4 = self::$FAILED;
1222      $this->currPos = $p3;
1223      $r2 = self::$FAILED;
1224      goto seq_1;
1225    }
1226    // free $p3
1227    if (($this->input[$this->currPos] ?? null) === ";") {
1228      $this->currPos++;
1229      $r5 = ";";
1230    } else {
1231      if (!$silence) {$this->fail(8);}
1232      $r5 = self::$FAILED;
1233      $this->currPos = $p1;
1234      $r2 = self::$FAILED;
1235      goto seq_1;
1236    }
1237    $r6 = $this->discardOWS($silence);
1238    if ($r6===self::$FAILED) {
1239      $this->currPos = $p1;
1240      $r2 = self::$FAILED;
1241      goto seq_1;
1242    }
1243    $r2 = true;
1244    seq_1:
1245    // free $r2,$p1
1246    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1247
1248    $this->cache[$key] = $cached;
1249    return $r2;
1250  }
1251  private function parseBang($silence) {
1252    $key = json_encode([340, $this->currPos]);
1253    $cached = $this->cache[$key] ?? null;
1254      if ($cached) {
1255        $this->currPos = $cached['nextPos'];
1256
1257        return $cached['result'];
1258      }
1259
1260    // start seq_1
1261    $p1 = $this->currPos;
1262    if (($this->input[$this->currPos] ?? null) === "!") {
1263      $this->currPos++;
1264      $r3 = "!";
1265    } else {
1266      if (!$silence) {$this->fail(9);}
1267      $r3 = self::$FAILED;
1268      $r2 = self::$FAILED;
1269      goto seq_1;
1270    }
1271    $r4 = $this->parseDELIM($silence);
1272    if ($r4===self::$FAILED) {
1273      $this->currPos = $p1;
1274      $r2 = self::$FAILED;
1275      goto seq_1;
1276    }
1277    $r2 = [$r3,$r4];
1278    seq_1:
1279    // free $r2,$p1
1280    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1281
1282    $this->cache[$key] = $cached;
1283    return $r2;
1284  }
1285  private function parsepipe_sequence($silence, $boolParams) {
1286    $key = json_encode([218, $this->currPos, $boolParams & 0x1]);
1287    $cached = $this->cache[$key] ?? null;
1288      if ($cached) {
1289        $this->currPos = $cached['nextPos'];
1290
1291        return $cached['result'];
1292      }
1293
1294    $p2 = $this->currPos;
1295    // start seq_1
1296    $p3 = $this->currPos;
1297    $r4 = $this->parsecommand($silence, $boolParams);
1298    // first <- $r4
1299    if ($r4===self::$FAILED) {
1300      $r1 = self::$FAILED;
1301      goto seq_1;
1302    }
1303    $r5 = [];
1304    for (;;) {
1305      $p7 = $this->currPos;
1306      // start seq_2
1307      $p8 = $this->currPos;
1308      $r9 = $this->discardPIPE($silence);
1309      if ($r9===self::$FAILED) {
1310        $r6 = self::$FAILED;
1311        goto seq_2;
1312      }
1313      $r10 = $this->discardlinebreak($silence);
1314      if ($r10===self::$FAILED) {
1315        $this->currPos = $p8;
1316        $r6 = self::$FAILED;
1317        goto seq_2;
1318      }
1319      $r11 = $this->parsecommand($silence, $boolParams);
1320      // command <- $r11
1321      if ($r11===self::$FAILED) {
1322        $this->currPos = $p8;
1323        $r6 = self::$FAILED;
1324        goto seq_2;
1325      }
1326      $r6 = true;
1327      seq_2:
1328      if ($r6!==self::$FAILED) {
1329        $this->savedPos = $p7;
1330        $r6 = $this->a10($r4, $r11);
1331        $r5[] = $r6;
1332      } else {
1333        break;
1334      }
1335      // free $p8
1336    }
1337    // rest <- $r5
1338    // free $r6
1339    $r1 = true;
1340    seq_1:
1341    if ($r1!==self::$FAILED) {
1342      $this->savedPos = $p2;
1343      $r1 = $this->a11($r4, $r5);
1344    }
1345    // free $p3
1346    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1347
1348    $this->cache[$key] = $cached;
1349    return $r1;
1350  }
1351  private function discardDSEMI($silence) {
1352    $key = json_encode([297, $this->currPos]);
1353    $cached = $this->cache[$key] ?? null;
1354      if ($cached) {
1355        $this->currPos = $cached['nextPos'];
1356
1357        return $cached['result'];
1358      }
1359
1360    // start seq_1
1361    $p1 = $this->currPos;
1362    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, ";;", $this->currPos, 2, false) === 0) {
1363      $r3 = ";;";
1364      $this->currPos += 2;
1365    } else {
1366      if (!$silence) {$this->fail(10);}
1367      $r3 = self::$FAILED;
1368      $r2 = self::$FAILED;
1369      goto seq_1;
1370    }
1371    $r4 = $this->discardOWS($silence);
1372    if ($r4===self::$FAILED) {
1373      $this->currPos = $p1;
1374      $r2 = self::$FAILED;
1375      goto seq_1;
1376    }
1377    $r2 = true;
1378    seq_1:
1379    // free $r2,$p1
1380    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1381
1382    $this->cache[$key] = $cached;
1383    return $r2;
1384  }
1385  private function parseDELIM($silence) {
1386    $key = json_encode([362, $this->currPos]);
1387    $cached = $this->cache[$key] ?? null;
1388      if ($cached) {
1389        $this->currPos = $cached['nextPos'];
1390
1391        return $cached['result'];
1392      }
1393
1394    // start choice_1
1395    $r1 = [];
1396    for (;;) {
1397      if (strspn($this->input, " \x09\x0b\x0d\x0c", $this->currPos, 1) !== 0) {
1398        $r2 = $this->input[$this->currPos++];
1399        $r1[] = $r2;
1400      } else {
1401        $r2 = self::$FAILED;
1402        if (!$silence) {$this->fail(2);}
1403        break;
1404      }
1405    }
1406    if (count($r1) === 0) {
1407      $r1 = self::$FAILED;
1408    }
1409    if ($r1!==self::$FAILED) {
1410      goto choice_1;
1411    }
1412    // free $r2
1413    $p3 = $this->currPos;
1414    if ($this->currPos < $this->inputLength) {
1415      $r1 = self::consumeChar($this->input, $this->currPos);;
1416    } else {
1417      $r1 = self::$FAILED;
1418    }
1419    if ($r1 === self::$FAILED) {
1420      $r1 = false;
1421      goto choice_1;
1422    } else {
1423      $r1 = self::$FAILED;
1424      $this->currPos = $p3;
1425    }
1426    // free $p3
1427    $p3 = $this->currPos;
1428    if (($this->input[$this->currPos] ?? null) === "\x0a") {
1429      $this->currPos++;
1430      $r1 = "\x0a";
1431      $r1 = false;
1432      $this->currPos = $p3;
1433    } else {
1434      $r1 = self::$FAILED;
1435    }
1436    // free $p3
1437    choice_1:
1438    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1439
1440    $this->cache[$key] = $cached;
1441    return $r1;
1442  }
1443  private function parsecommand($silence, $boolParams) {
1444    $key = json_encode([220, $this->currPos, $boolParams & 0x1]);
1445    $cached = $this->cache[$key] ?? null;
1446      if ($cached) {
1447        $this->currPos = $cached['nextPos'];
1448
1449        return $cached['result'];
1450      }
1451
1452    // start choice_1
1453    $r1 = $this->parsefunction_definition($silence, $boolParams);
1454    if ($r1!==self::$FAILED) {
1455      goto choice_1;
1456    }
1457    $r1 = $this->parsesimple_command($silence, $boolParams);
1458    if ($r1!==self::$FAILED) {
1459      goto choice_1;
1460    }
1461    $p2 = $this->currPos;
1462    // start seq_1
1463    $p3 = $this->currPos;
1464    $r4 = $this->parsecompound_command($silence, $boolParams);
1465    // c <- $r4
1466    if ($r4===self::$FAILED) {
1467      $r1 = self::$FAILED;
1468      goto seq_1;
1469    }
1470    $r5 = $this->parseredirect_list($silence, $boolParams);
1471    if ($r5===self::$FAILED) {
1472      $r5 = null;
1473    }
1474    // r <- $r5
1475    $r1 = true;
1476    seq_1:
1477    if ($r1!==self::$FAILED) {
1478      $this->savedPos = $p2;
1479      $r1 = $this->a12($r4, $r5);
1480    }
1481    // free $p3
1482    choice_1:
1483    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1484
1485    $this->cache[$key] = $cached;
1486    return $r1;
1487  }
1488  private function discardPIPE($silence) {
1489    $key = json_encode([355, $this->currPos]);
1490    $cached = $this->cache[$key] ?? null;
1491      if ($cached) {
1492        $this->currPos = $cached['nextPos'];
1493
1494        return $cached['result'];
1495      }
1496
1497    // start seq_1
1498    $p1 = $this->currPos;
1499    $p3 = $this->currPos;
1500    $r4 = $this->discardOR_IF(true);
1501    if ($r4 === self::$FAILED) {
1502      $r4 = false;
1503    } else {
1504      $r4 = self::$FAILED;
1505      $this->currPos = $p3;
1506      $r2 = self::$FAILED;
1507      goto seq_1;
1508    }
1509    // free $p3
1510    if (($this->input[$this->currPos] ?? null) === "|") {
1511      $this->currPos++;
1512      $r5 = "|";
1513    } else {
1514      if (!$silence) {$this->fail(11);}
1515      $r5 = self::$FAILED;
1516      $this->currPos = $p1;
1517      $r2 = self::$FAILED;
1518      goto seq_1;
1519    }
1520    $r6 = $this->discardOWS($silence);
1521    if ($r6===self::$FAILED) {
1522      $this->currPos = $p1;
1523      $r2 = self::$FAILED;
1524      goto seq_1;
1525    }
1526    $r2 = true;
1527    seq_1:
1528    // free $r2,$p1
1529    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1530
1531    $this->cache[$key] = $cached;
1532    return $r2;
1533  }
1534  private function parsefunction_definition($silence, $boolParams) {
1535    $key = json_encode([256, $this->currPos, $boolParams & 0x1]);
1536    $cached = $this->cache[$key] ?? null;
1537      if ($cached) {
1538        $this->currPos = $cached['nextPos'];
1539
1540        return $cached['result'];
1541      }
1542
1543    $p2 = $this->currPos;
1544    // start seq_1
1545    $p3 = $this->currPos;
1546    $r4 = $this->parseNAME($silence);
1547    // fname <- $r4
1548    if ($r4===self::$FAILED) {
1549      $r1 = self::$FAILED;
1550      goto seq_1;
1551    }
1552    $r5 = $this->discardLPAREN($silence);
1553    if ($r5===self::$FAILED) {
1554      $this->currPos = $p3;
1555      $r1 = self::$FAILED;
1556      goto seq_1;
1557    }
1558    $r6 = $this->discardRPAREN($silence);
1559    if ($r6===self::$FAILED) {
1560      $this->currPos = $p3;
1561      $r1 = self::$FAILED;
1562      goto seq_1;
1563    }
1564    $r7 = $this->discardlinebreak($silence);
1565    if ($r7===self::$FAILED) {
1566      $this->currPos = $p3;
1567      $r1 = self::$FAILED;
1568      goto seq_1;
1569    }
1570    $r8 = $this->parsefunction_body($silence, $boolParams);
1571    // body <- $r8
1572    if ($r8===self::$FAILED) {
1573      $this->currPos = $p3;
1574      $r1 = self::$FAILED;
1575      goto seq_1;
1576    }
1577    $r1 = true;
1578    seq_1:
1579    if ($r1!==self::$FAILED) {
1580      $this->savedPos = $p2;
1581      $r1 = $this->a13($r4, $r8);
1582    }
1583    // free $p3
1584    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1585
1586    $this->cache[$key] = $cached;
1587    return $r1;
1588  }
1589  private function parsesimple_command($silence, $boolParams) {
1590    $key = json_encode([264, $this->currPos, $boolParams & 0x1]);
1591    $cached = $this->cache[$key] ?? null;
1592      if ($cached) {
1593        $this->currPos = $cached['nextPos'];
1594
1595        return $cached['result'];
1596      }
1597
1598    // start choice_1
1599    $p2 = $this->currPos;
1600    // start seq_1
1601    $p3 = $this->currPos;
1602    $r4 = $this->parsecmd_prefix($silence, $boolParams);
1603    // prefix <- $r4
1604    if ($r4===self::$FAILED) {
1605      $r1 = self::$FAILED;
1606      goto seq_1;
1607    }
1608    $r5 = $this->parseWORD($silence, $boolParams);
1609    // word <- $r5
1610    if ($r5===self::$FAILED) {
1611      $this->currPos = $p3;
1612      $r1 = self::$FAILED;
1613      goto seq_1;
1614    }
1615    $r6 = $this->parsecmd_suffix($silence, $boolParams);
1616    if ($r6===self::$FAILED) {
1617      $r6 = null;
1618    }
1619    // suffix <- $r6
1620    $r1 = true;
1621    seq_1:
1622    if ($r1!==self::$FAILED) {
1623      $this->savedPos = $p2;
1624      $r1 = $this->a14($r4, $r5, $r6);
1625      goto choice_1;
1626    }
1627    // free $p3
1628    $p3 = $this->currPos;
1629    $r7 = $this->parsecmd_prefix($silence, $boolParams);
1630    // prefix <- $r7
1631    $r1 = $r7;
1632    if ($r1!==self::$FAILED) {
1633      $this->savedPos = $p3;
1634      $r1 = $this->a15($r7);
1635      goto choice_1;
1636    }
1637    $p8 = $this->currPos;
1638    // start seq_2
1639    $p9 = $this->currPos;
1640    $r10 = $this->parsecmd_name($silence, $boolParams);
1641    // name <- $r10
1642    if ($r10===self::$FAILED) {
1643      $r1 = self::$FAILED;
1644      goto seq_2;
1645    }
1646    $r11 = $this->parsecmd_suffix($silence, $boolParams);
1647    if ($r11===self::$FAILED) {
1648      $r11 = null;
1649    }
1650    // suffix <- $r11
1651    $r1 = true;
1652    seq_2:
1653    if ($r1!==self::$FAILED) {
1654      $this->savedPos = $p8;
1655      $r1 = $this->a16($r10, $r11);
1656    }
1657    // free $p9
1658    choice_1:
1659    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1660
1661    $this->cache[$key] = $cached;
1662    return $r1;
1663  }
1664  private function parsecompound_command($silence, $boolParams) {
1665    $key = json_encode([222, $this->currPos, $boolParams & 0x1]);
1666    $cached = $this->cache[$key] ?? null;
1667      if ($cached) {
1668        $this->currPos = $cached['nextPos'];
1669
1670        return $cached['result'];
1671      }
1672
1673    // start choice_1
1674    $r1 = $this->parsebrace_group($silence);
1675    if ($r1!==self::$FAILED) {
1676      goto choice_1;
1677    }
1678    $r1 = $this->parsesubshell($silence);
1679    if ($r1!==self::$FAILED) {
1680      goto choice_1;
1681    }
1682    $r1 = $this->parsefor_clause($silence, $boolParams);
1683    if ($r1!==self::$FAILED) {
1684      goto choice_1;
1685    }
1686    $r1 = $this->parsecase_clause($silence, $boolParams);
1687    if ($r1!==self::$FAILED) {
1688      goto choice_1;
1689    }
1690    $r1 = $this->parseif_clause($silence);
1691    if ($r1!==self::$FAILED) {
1692      goto choice_1;
1693    }
1694    $r1 = $this->parsewhile_clause($silence);
1695    if ($r1!==self::$FAILED) {
1696      goto choice_1;
1697    }
1698    $r1 = $this->parseuntil_clause($silence);
1699    choice_1:
1700    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1701
1702    $this->cache[$key] = $cached;
1703    return $r1;
1704  }
1705  private function parseredirect_list($silence, $boolParams) {
1706    $key = json_encode([272, $this->currPos, $boolParams & 0x1]);
1707    $cached = $this->cache[$key] ?? null;
1708      if ($cached) {
1709        $this->currPos = $cached['nextPos'];
1710
1711        return $cached['result'];
1712      }
1713
1714    $r1 = [];
1715    for (;;) {
1716      $r2 = $this->parseio_redirect($silence, $boolParams);
1717      if ($r2!==self::$FAILED) {
1718        $r1[] = $r2;
1719      } else {
1720        break;
1721      }
1722    }
1723    if (count($r1) === 0) {
1724      $r1 = self::$FAILED;
1725    }
1726    // free $r2
1727    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1728
1729    $this->cache[$key] = $cached;
1730    return $r1;
1731  }
1732  private function parseNAME($silence) {
1733    $key = json_encode([410, $this->currPos]);
1734    $cached = $this->cache[$key] ?? null;
1735      if ($cached) {
1736        $this->currPos = $cached['nextPos'];
1737
1738        return $cached['result'];
1739      }
1740
1741    $p1 = $this->currPos;
1742    // start seq_1
1743    $p3 = $this->currPos;
1744    $r4 = $this->input[$this->currPos] ?? '';
1745    if (preg_match("/^[_a-zA-Z]/", $r4)) {
1746      $this->currPos++;
1747    } else {
1748      $r4 = self::$FAILED;
1749      if (!$silence) {$this->fail(12);}
1750      $r2 = self::$FAILED;
1751      goto seq_1;
1752    }
1753    for (;;) {
1754      $r6 = $this->input[$this->currPos] ?? '';
1755      if (preg_match("/^[_a-zA-Z0-9]/", $r6)) {
1756        $this->currPos++;
1757      } else {
1758        $r6 = self::$FAILED;
1759        if (!$silence) {$this->fail(13);}
1760        break;
1761      }
1762    }
1763    // free $r6
1764    $r5 = true;
1765    if ($r5===self::$FAILED) {
1766      $this->currPos = $p3;
1767      $r2 = self::$FAILED;
1768      goto seq_1;
1769    }
1770    // free $r5
1771    $r2 = true;
1772    seq_1:
1773    if ($r2!==self::$FAILED) {
1774      $r2 = substr($this->input, $p1, $this->currPos - $p1);
1775    } else {
1776      $r2 = self::$FAILED;
1777    }
1778    // free $p3
1779    // free $p1
1780    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1781
1782    $this->cache[$key] = $cached;
1783    return $r2;
1784  }
1785  private function discardLPAREN($silence) {
1786    $key = json_encode([357, $this->currPos]);
1787    $cached = $this->cache[$key] ?? null;
1788      if ($cached) {
1789        $this->currPos = $cached['nextPos'];
1790
1791        return $cached['result'];
1792      }
1793
1794    // start seq_1
1795    $p1 = $this->currPos;
1796    if (($this->input[$this->currPos] ?? null) === "(") {
1797      $this->currPos++;
1798      $r3 = "(";
1799    } else {
1800      if (!$silence) {$this->fail(14);}
1801      $r3 = self::$FAILED;
1802      $r2 = self::$FAILED;
1803      goto seq_1;
1804    }
1805    $r4 = $this->discardOWS($silence);
1806    if ($r4===self::$FAILED) {
1807      $this->currPos = $p1;
1808      $r2 = self::$FAILED;
1809      goto seq_1;
1810    }
1811    $r2 = true;
1812    seq_1:
1813    // free $r2,$p1
1814    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1815
1816    $this->cache[$key] = $cached;
1817    return $r2;
1818  }
1819  private function discardRPAREN($silence) {
1820    $key = json_encode([359, $this->currPos]);
1821    $cached = $this->cache[$key] ?? null;
1822      if ($cached) {
1823        $this->currPos = $cached['nextPos'];
1824
1825        return $cached['result'];
1826      }
1827
1828    // start seq_1
1829    $p1 = $this->currPos;
1830    if (($this->input[$this->currPos] ?? null) === ")") {
1831      $this->currPos++;
1832      $r3 = ")";
1833    } else {
1834      if (!$silence) {$this->fail(15);}
1835      $r3 = self::$FAILED;
1836      $r2 = self::$FAILED;
1837      goto seq_1;
1838    }
1839    $r4 = $this->discardOWS($silence);
1840    if ($r4===self::$FAILED) {
1841      $this->currPos = $p1;
1842      $r2 = self::$FAILED;
1843      goto seq_1;
1844    }
1845    $r2 = true;
1846    seq_1:
1847    // free $r2,$p1
1848    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
1849
1850    $this->cache[$key] = $cached;
1851    return $r2;
1852  }
1853  private function parsefunction_body($silence, $boolParams) {
1854    $key = json_encode([258, $this->currPos, $boolParams & 0x1]);
1855    $cached = $this->cache[$key] ?? null;
1856      if ($cached) {
1857        $this->currPos = $cached['nextPos'];
1858
1859        return $cached['result'];
1860      }
1861
1862    $p2 = $this->currPos;
1863    // start seq_1
1864    $p3 = $this->currPos;
1865    $r4 = $this->parsecompound_command($silence, $boolParams);
1866    // c <- $r4
1867    if ($r4===self::$FAILED) {
1868      $r1 = self::$FAILED;
1869      goto seq_1;
1870    }
1871    $r5 = $this->parseredirect_list($silence, $boolParams);
1872    if ($r5===self::$FAILED) {
1873      $r5 = null;
1874    }
1875    // r <- $r5
1876    $r1 = true;
1877    seq_1:
1878    if ($r1!==self::$FAILED) {
1879      $this->savedPos = $p2;
1880      $r1 = $this->a17($r4, $r5);
1881    }
1882    // free $p3
1883    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1884
1885    $this->cache[$key] = $cached;
1886    return $r1;
1887  }
1888  private function parsecmd_prefix($silence, $boolParams) {
1889    $key = json_encode([268, $this->currPos, $boolParams & 0x1]);
1890    $cached = $this->cache[$key] ?? null;
1891      if ($cached) {
1892        $this->currPos = $cached['nextPos'];
1893
1894        return $cached['result'];
1895      }
1896
1897    $p2 = $this->currPos;
1898    $r3 = [];
1899    for (;;) {
1900      // start choice_1
1901      $r4 = $this->parseio_redirect($silence, $boolParams);
1902      if ($r4!==self::$FAILED) {
1903        goto choice_1;
1904      }
1905      $r4 = $this->parseASSIGNMENT_WORD($silence, $boolParams);
1906      choice_1:
1907      if ($r4!==self::$FAILED) {
1908        $r3[] = $r4;
1909      } else {
1910        break;
1911      }
1912    }
1913    if (count($r3) === 0) {
1914      $r3 = self::$FAILED;
1915    }
1916    // contents <- $r3
1917    // free $r4
1918    $r1 = $r3;
1919    if ($r1!==self::$FAILED) {
1920      $this->savedPos = $p2;
1921      $r1 = $this->a18($r3);
1922    }
1923    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1924
1925    $this->cache[$key] = $cached;
1926    return $r1;
1927  }
1928  private function parseWORD($silence, $boolParams) {
1929    $key = json_encode([364, $this->currPos, $boolParams & 0x1]);
1930    $cached = $this->cache[$key] ?? null;
1931      if ($cached) {
1932        $this->currPos = $cached['nextPos'];
1933
1934        return $cached['result'];
1935      }
1936
1937    $p2 = $this->currPos;
1938    // start seq_1
1939    $p3 = $this->currPos;
1940    $r4 = [];
1941    for (;;) {
1942      $r5 = $this->parseword_part($silence, $boolParams);
1943      if ($r5!==self::$FAILED) {
1944        $r4[] = $r5;
1945      } else {
1946        break;
1947      }
1948    }
1949    if (count($r4) === 0) {
1950      $r4 = self::$FAILED;
1951    }
1952    // parts <- $r4
1953    if ($r4===self::$FAILED) {
1954      $r1 = self::$FAILED;
1955      goto seq_1;
1956    }
1957    // free $r5
1958    $r5 = $this->discardOWS($silence);
1959    if ($r5===self::$FAILED) {
1960      $this->currPos = $p3;
1961      $r1 = self::$FAILED;
1962      goto seq_1;
1963    }
1964    $r1 = true;
1965    seq_1:
1966    if ($r1!==self::$FAILED) {
1967      $this->savedPos = $p2;
1968      $r1 = $this->a19($r4);
1969    }
1970    // free $p3
1971    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
1972
1973    $this->cache[$key] = $cached;
1974    return $r1;
1975  }
1976  private function parsecmd_suffix($silence, $boolParams) {
1977    $key = json_encode([270, $this->currPos, $boolParams & 0x1]);
1978    $cached = $this->cache[$key] ?? null;
1979      if ($cached) {
1980        $this->currPos = $cached['nextPos'];
1981
1982        return $cached['result'];
1983      }
1984
1985    $r1 = [];
1986    for (;;) {
1987      // start choice_1
1988      $r2 = $this->parseio_redirect($silence, $boolParams);
1989      if ($r2!==self::$FAILED) {
1990        goto choice_1;
1991      }
1992      $r2 = $this->parseWORD($silence, $boolParams);
1993      choice_1:
1994      if ($r2!==self::$FAILED) {
1995        $r1[] = $r2;
1996      } else {
1997        break;
1998      }
1999    }
2000    if (count($r1) === 0) {
2001      $r1 = self::$FAILED;
2002    }
2003    // free $r2
2004    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2005
2006    $this->cache[$key] = $cached;
2007    return $r1;
2008  }
2009  private function parsecmd_name($silence, $boolParams) {
2010    $key = json_encode([266, $this->currPos, $boolParams & 0x1]);
2011    $cached = $this->cache[$key] ?? null;
2012      if ($cached) {
2013        $this->currPos = $cached['nextPos'];
2014
2015        return $cached['result'];
2016      }
2017
2018    $p2 = $this->currPos;
2019    // start seq_1
2020    $p3 = $this->currPos;
2021    $p4 = $this->currPos;
2022    $r5 = $this->discardreserved(true);
2023    if ($r5 === self::$FAILED) {
2024      $r5 = false;
2025    } else {
2026      $r5 = self::$FAILED;
2027      $this->currPos = $p4;
2028      $r1 = self::$FAILED;
2029      goto seq_1;
2030    }
2031    // free $p4
2032    $r6 = $this->parseWORD($silence, $boolParams);
2033    // word <- $r6
2034    if ($r6===self::$FAILED) {
2035      $this->currPos = $p3;
2036      $r1 = self::$FAILED;
2037      goto seq_1;
2038    }
2039    $r1 = true;
2040    seq_1:
2041    if ($r1!==self::$FAILED) {
2042      $this->savedPos = $p2;
2043      $r1 = $this->a20($r6);
2044    }
2045    // free $p3
2046    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2047
2048    $this->cache[$key] = $cached;
2049    return $r1;
2050  }
2051  private function parsebrace_group($silence) {
2052    $key = json_encode([260, $this->currPos]);
2053    $cached = $this->cache[$key] ?? null;
2054      if ($cached) {
2055        $this->currPos = $cached['nextPos'];
2056
2057        return $cached['result'];
2058      }
2059
2060    $p2 = $this->currPos;
2061    // start seq_1
2062    $p3 = $this->currPos;
2063    $r4 = $this->discardLbrace($silence);
2064    if ($r4===self::$FAILED) {
2065      $r1 = self::$FAILED;
2066      goto seq_1;
2067    }
2068    $r5 = $this->parsecompound_list($silence);
2069    // list <- $r5
2070    if ($r5===self::$FAILED) {
2071      $this->currPos = $p3;
2072      $r1 = self::$FAILED;
2073      goto seq_1;
2074    }
2075    $r6 = $this->discardRbrace($silence);
2076    if ($r6===self::$FAILED) {
2077      $this->currPos = $p3;
2078      $r1 = self::$FAILED;
2079      goto seq_1;
2080    }
2081    $r1 = true;
2082    seq_1:
2083    if ($r1!==self::$FAILED) {
2084      $this->savedPos = $p2;
2085      $r1 = $this->a21($r5);
2086    }
2087    // free $p3
2088    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2089
2090    $this->cache[$key] = $cached;
2091    return $r1;
2092  }
2093  private function parsesubshell($silence) {
2094    $key = json_encode([224, $this->currPos]);
2095    $cached = $this->cache[$key] ?? null;
2096      if ($cached) {
2097        $this->currPos = $cached['nextPos'];
2098
2099        return $cached['result'];
2100      }
2101
2102    $p2 = $this->currPos;
2103    // start seq_1
2104    $p3 = $this->currPos;
2105    $r4 = $this->discardLPAREN($silence);
2106    if ($r4===self::$FAILED) {
2107      $r1 = self::$FAILED;
2108      goto seq_1;
2109    }
2110    $r5 = $this->parsecompound_list($silence);
2111    // list <- $r5
2112    if ($r5===self::$FAILED) {
2113      $this->currPos = $p3;
2114      $r1 = self::$FAILED;
2115      goto seq_1;
2116    }
2117    $r6 = $this->discardRPAREN($silence);
2118    if ($r6===self::$FAILED) {
2119      $this->currPos = $p3;
2120      $r1 = self::$FAILED;
2121      goto seq_1;
2122    }
2123    $r1 = true;
2124    seq_1:
2125    if ($r1!==self::$FAILED) {
2126      $this->savedPos = $p2;
2127      $r1 = $this->a22($r5);
2128    }
2129    // free $p3
2130    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2131
2132    $this->cache[$key] = $cached;
2133    return $r1;
2134  }
2135  private function parsefor_clause($silence, $boolParams) {
2136    $key = json_encode([228, $this->currPos, $boolParams & 0x1]);
2137    $cached = $this->cache[$key] ?? null;
2138      if ($cached) {
2139        $this->currPos = $cached['nextPos'];
2140
2141        return $cached['result'];
2142      }
2143
2144    // start choice_1
2145    $p2 = $this->currPos;
2146    // start seq_1
2147    $p3 = $this->currPos;
2148    $r4 = $this->discardFor($silence);
2149    if ($r4===self::$FAILED) {
2150      $r1 = self::$FAILED;
2151      goto seq_1;
2152    }
2153    $r5 = $this->parsefor_name($silence);
2154    // name <- $r5
2155    if ($r5===self::$FAILED) {
2156      $this->currPos = $p3;
2157      $r1 = self::$FAILED;
2158      goto seq_1;
2159    }
2160    $r6 = $this->discardlinebreak($silence);
2161    if ($r6===self::$FAILED) {
2162      $this->currPos = $p3;
2163      $r1 = self::$FAILED;
2164      goto seq_1;
2165    }
2166    $r7 = $this->discardfor_case_in($silence);
2167    if ($r7===self::$FAILED) {
2168      $this->currPos = $p3;
2169      $r1 = self::$FAILED;
2170      goto seq_1;
2171    }
2172    $r8 = $this->parsewordlist($silence, $boolParams);
2173    if ($r8===self::$FAILED) {
2174      $r8 = null;
2175    }
2176    // wordlist <- $r8
2177    $r9 = $this->discardsequential_sep($silence);
2178    if ($r9===self::$FAILED) {
2179      $this->currPos = $p3;
2180      $r1 = self::$FAILED;
2181      goto seq_1;
2182    }
2183    $r10 = $this->parsedo_group($silence);
2184    // do_group <- $r10
2185    if ($r10===self::$FAILED) {
2186      $this->currPos = $p3;
2187      $r1 = self::$FAILED;
2188      goto seq_1;
2189    }
2190    $r1 = true;
2191    seq_1:
2192    if ($r1!==self::$FAILED) {
2193      $this->savedPos = $p2;
2194      $r1 = $this->a23($r5, $r8, $r10);
2195      goto choice_1;
2196    }
2197    // free $p3
2198    $p3 = $this->currPos;
2199    // start seq_2
2200    $p11 = $this->currPos;
2201    $r12 = $this->discardFor($silence);
2202    if ($r12===self::$FAILED) {
2203      $r1 = self::$FAILED;
2204      goto seq_2;
2205    }
2206    $r13 = $this->parsefor_name($silence);
2207    // name <- $r13
2208    if ($r13===self::$FAILED) {
2209      $this->currPos = $p11;
2210      $r1 = self::$FAILED;
2211      goto seq_2;
2212    }
2213    $r14 = $this->discardsequential_sep($silence);
2214    if ($r14===self::$FAILED) {
2215      $r14 = null;
2216    }
2217    $r15 = $this->parsedo_group($silence);
2218    // do_group <- $r15
2219    if ($r15===self::$FAILED) {
2220      $this->currPos = $p11;
2221      $r1 = self::$FAILED;
2222      goto seq_2;
2223    }
2224    $r1 = true;
2225    seq_2:
2226    if ($r1!==self::$FAILED) {
2227      $this->savedPos = $p3;
2228      $r1 = $this->a24($r13, $r15);
2229    }
2230    // free $p11
2231    choice_1:
2232    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2233
2234    $this->cache[$key] = $cached;
2235    return $r1;
2236  }
2237  private function parsecase_clause($silence, $boolParams) {
2238    $key = json_encode([236, $this->currPos, $boolParams & 0x1]);
2239    $cached = $this->cache[$key] ?? null;
2240      if ($cached) {
2241        $this->currPos = $cached['nextPos'];
2242
2243        return $cached['result'];
2244      }
2245
2246    $p2 = $this->currPos;
2247    // start seq_1
2248    $p3 = $this->currPos;
2249    $r4 = $this->discardCase($silence);
2250    if ($r4===self::$FAILED) {
2251      $r1 = self::$FAILED;
2252      goto seq_1;
2253    }
2254    $r5 = $this->parseWORD($silence, $boolParams);
2255    // word <- $r5
2256    if ($r5===self::$FAILED) {
2257      $this->currPos = $p3;
2258      $r1 = self::$FAILED;
2259      goto seq_1;
2260    }
2261    $r6 = $this->discardlinebreak($silence);
2262    if ($r6===self::$FAILED) {
2263      $this->currPos = $p3;
2264      $r1 = self::$FAILED;
2265      goto seq_1;
2266    }
2267    $r7 = $this->discardfor_case_in($silence);
2268    if ($r7===self::$FAILED) {
2269      $this->currPos = $p3;
2270      $r1 = self::$FAILED;
2271      goto seq_1;
2272    }
2273    $r8 = $this->discardlinebreak($silence);
2274    if ($r8===self::$FAILED) {
2275      $this->currPos = $p3;
2276      $r1 = self::$FAILED;
2277      goto seq_1;
2278    }
2279    // start choice_1
2280    // start seq_2
2281    $p10 = $this->currPos;
2282    $r11 = $this->parsecase_list($silence, $boolParams);
2283    if ($r11===self::$FAILED) {
2284      $r9 = self::$FAILED;
2285      goto seq_2;
2286    }
2287    $p12 = $this->currPos;
2288    $r13 = $this->discardEsac($silence);
2289    if ($r13!==self::$FAILED) {
2290      $r13 = substr($this->input, $p12, $this->currPos - $p12);
2291    } else {
2292      $r13 = self::$FAILED;
2293      $this->currPos = $p10;
2294      $r9 = self::$FAILED;
2295      goto seq_2;
2296    }
2297    // free $p12
2298    $r9 = [$r11,$r13];
2299    seq_2:
2300    if ($r9!==self::$FAILED) {
2301      goto choice_1;
2302    }
2303    // free $p10
2304    // start seq_3
2305    $p10 = $this->currPos;
2306    $r14 = $this->parsecase_list_ns($silence, $boolParams);
2307    if ($r14===self::$FAILED) {
2308      $r9 = self::$FAILED;
2309      goto seq_3;
2310    }
2311    $p12 = $this->currPos;
2312    $r15 = $this->discardEsac($silence);
2313    if ($r15!==self::$FAILED) {
2314      $r15 = substr($this->input, $p12, $this->currPos - $p12);
2315    } else {
2316      $r15 = self::$FAILED;
2317      $this->currPos = $p10;
2318      $r9 = self::$FAILED;
2319      goto seq_3;
2320    }
2321    // free $p12
2322    $r9 = [$r14,$r15];
2323    seq_3:
2324    if ($r9!==self::$FAILED) {
2325      goto choice_1;
2326    }
2327    // free $p10
2328    $p10 = $this->currPos;
2329    $r9 = $this->discardEsac($silence);
2330    if ($r9!==self::$FAILED) {
2331      $r9 = substr($this->input, $p10, $this->currPos - $p10);
2332    } else {
2333      $r9 = self::$FAILED;
2334    }
2335    // free $p10
2336    choice_1:
2337    // list_esac <- $r9
2338    if ($r9===self::$FAILED) {
2339      $this->currPos = $p3;
2340      $r1 = self::$FAILED;
2341      goto seq_1;
2342    }
2343    $r1 = true;
2344    seq_1:
2345    if ($r1!==self::$FAILED) {
2346      $this->savedPos = $p2;
2347      $r1 = $this->a25($r5, $r9);
2348    }
2349    // free $p3
2350    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2351
2352    $this->cache[$key] = $cached;
2353    return $r1;
2354  }
2355  private function parseif_clause($silence) {
2356    $key = json_encode([248, $this->currPos]);
2357    $cached = $this->cache[$key] ?? null;
2358      if ($cached) {
2359        $this->currPos = $cached['nextPos'];
2360
2361        return $cached['result'];
2362      }
2363
2364    $p2 = $this->currPos;
2365    // start seq_1
2366    $p3 = $this->currPos;
2367    $r4 = $this->discardIf($silence);
2368    if ($r4===self::$FAILED) {
2369      $r1 = self::$FAILED;
2370      goto seq_1;
2371    }
2372    $r5 = $this->parsecompound_list($silence);
2373    // condition <- $r5
2374    if ($r5===self::$FAILED) {
2375      $this->currPos = $p3;
2376      $r1 = self::$FAILED;
2377      goto seq_1;
2378    }
2379    $r6 = $this->discardThen($silence);
2380    if ($r6===self::$FAILED) {
2381      $this->currPos = $p3;
2382      $r1 = self::$FAILED;
2383      goto seq_1;
2384    }
2385    $r7 = $this->parsecompound_list($silence);
2386    // consequent <- $r7
2387    if ($r7===self::$FAILED) {
2388      $this->currPos = $p3;
2389      $r1 = self::$FAILED;
2390      goto seq_1;
2391    }
2392    $r8 = $this->parseelse_part($silence);
2393    if ($r8===self::$FAILED) {
2394      $r8 = null;
2395    }
2396    // else_part <- $r8
2397    $r9 = $this->discardFi($silence);
2398    if ($r9===self::$FAILED) {
2399      $this->currPos = $p3;
2400      $r1 = self::$FAILED;
2401      goto seq_1;
2402    }
2403    $r1 = true;
2404    seq_1:
2405    if ($r1!==self::$FAILED) {
2406      $this->savedPos = $p2;
2407      $r1 = $this->a26($r5, $r7, $r8);
2408    }
2409    // free $p3
2410    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2411
2412    $this->cache[$key] = $cached;
2413    return $r1;
2414  }
2415  private function parsewhile_clause($silence) {
2416    $key = json_encode([252, $this->currPos]);
2417    $cached = $this->cache[$key] ?? null;
2418      if ($cached) {
2419        $this->currPos = $cached['nextPos'];
2420
2421        return $cached['result'];
2422      }
2423
2424    $p2 = $this->currPos;
2425    // start seq_1
2426    $p3 = $this->currPos;
2427    $r4 = $this->discardWhile($silence);
2428    if ($r4===self::$FAILED) {
2429      $r1 = self::$FAILED;
2430      goto seq_1;
2431    }
2432    $r5 = $this->parsecompound_list($silence);
2433    // list <- $r5
2434    if ($r5===self::$FAILED) {
2435      $this->currPos = $p3;
2436      $r1 = self::$FAILED;
2437      goto seq_1;
2438    }
2439    $r6 = $this->parsedo_group($silence);
2440    // body <- $r6
2441    if ($r6===self::$FAILED) {
2442      $this->currPos = $p3;
2443      $r1 = self::$FAILED;
2444      goto seq_1;
2445    }
2446    $r1 = true;
2447    seq_1:
2448    if ($r1!==self::$FAILED) {
2449      $this->savedPos = $p2;
2450      $r1 = $this->a27($r5, $r6);
2451    }
2452    // free $p3
2453    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2454
2455    $this->cache[$key] = $cached;
2456    return $r1;
2457  }
2458  private function parseuntil_clause($silence) {
2459    $key = json_encode([254, $this->currPos]);
2460    $cached = $this->cache[$key] ?? null;
2461      if ($cached) {
2462        $this->currPos = $cached['nextPos'];
2463
2464        return $cached['result'];
2465      }
2466
2467    $p2 = $this->currPos;
2468    // start seq_1
2469    $p3 = $this->currPos;
2470    $r4 = $this->discardUntil($silence);
2471    if ($r4===self::$FAILED) {
2472      $r1 = self::$FAILED;
2473      goto seq_1;
2474    }
2475    $r5 = $this->parsecompound_list($silence);
2476    // list <- $r5
2477    if ($r5===self::$FAILED) {
2478      $this->currPos = $p3;
2479      $r1 = self::$FAILED;
2480      goto seq_1;
2481    }
2482    $r6 = $this->parsedo_group($silence);
2483    // body <- $r6
2484    if ($r6===self::$FAILED) {
2485      $this->currPos = $p3;
2486      $r1 = self::$FAILED;
2487      goto seq_1;
2488    }
2489    $r1 = true;
2490    seq_1:
2491    if ($r1!==self::$FAILED) {
2492      $this->savedPos = $p2;
2493      $r1 = $this->a28($r5, $r6);
2494    }
2495    // free $p3
2496    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2497
2498    $this->cache[$key] = $cached;
2499    return $r1;
2500  }
2501  private function parseio_redirect($silence, $boolParams) {
2502    $key = json_encode([274, $this->currPos, $boolParams & 0x1]);
2503    $cached = $this->cache[$key] ?? null;
2504      if ($cached) {
2505        $this->currPos = $cached['nextPos'];
2506
2507        return $cached['result'];
2508      }
2509
2510    $p2 = $this->currPos;
2511    // start seq_1
2512    $p3 = $this->currPos;
2513    $r4 = $this->parseIO_NUMBER($silence);
2514    if ($r4===self::$FAILED) {
2515      $r4 = null;
2516    }
2517    // number <- $r4
2518    // start choice_1
2519    $r5 = $this->parseio_file($silence, $boolParams);
2520    if ($r5!==self::$FAILED) {
2521      goto choice_1;
2522    }
2523    $r5 = $this->parseio_here($silence, $boolParams);
2524    choice_1:
2525    // file_or_here <- $r5
2526    if ($r5===self::$FAILED) {
2527      $this->currPos = $p3;
2528      $r1 = self::$FAILED;
2529      goto seq_1;
2530    }
2531    $r1 = true;
2532    seq_1:
2533    if ($r1!==self::$FAILED) {
2534      $this->savedPos = $p2;
2535      $r1 = $this->a29($r4, $r5);
2536    }
2537    // free $p3
2538    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2539
2540    $this->cache[$key] = $cached;
2541    return $r1;
2542  }
2543  private function parseASSIGNMENT_WORD($silence, $boolParams) {
2544    $key = json_encode([408, $this->currPos, $boolParams & 0x1]);
2545    $cached = $this->cache[$key] ?? null;
2546      if ($cached) {
2547        $this->currPos = $cached['nextPos'];
2548
2549        return $cached['result'];
2550      }
2551
2552    $p2 = $this->currPos;
2553    // start seq_1
2554    $p3 = $this->currPos;
2555    $r4 = $this->parseNAME($silence);
2556    // name <- $r4
2557    if ($r4===self::$FAILED) {
2558      $r1 = self::$FAILED;
2559      goto seq_1;
2560    }
2561    if (($this->input[$this->currPos] ?? null) === "=") {
2562      $this->currPos++;
2563      $r5 = "=";
2564    } else {
2565      if (!$silence) {$this->fail(16);}
2566      $r5 = self::$FAILED;
2567      $this->currPos = $p3;
2568      $r1 = self::$FAILED;
2569      goto seq_1;
2570    }
2571    $r6 = $this->parseWORD($silence, $boolParams);
2572    // word <- $r6
2573    if ($r6===self::$FAILED) {
2574      $this->currPos = $p3;
2575      $r1 = self::$FAILED;
2576      goto seq_1;
2577    }
2578    $r1 = true;
2579    seq_1:
2580    if ($r1!==self::$FAILED) {
2581      $this->savedPos = $p2;
2582      $r1 = $this->a30($r4, $r6);
2583    }
2584    // free $p3
2585    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2586
2587    $this->cache[$key] = $cached;
2588    return $r1;
2589  }
2590  private function parseword_part($silence, $boolParams) {
2591    $key = json_encode([366, $this->currPos, $boolParams & 0x1]);
2592    $cached = $this->cache[$key] ?? null;
2593      if ($cached) {
2594        $this->currPos = $cached['nextPos'];
2595
2596        return $cached['result'];
2597      }
2598
2599    // start choice_1
2600    $r1 = $this->parsesingle_quoted_part($silence);
2601    if ($r1!==self::$FAILED) {
2602      goto choice_1;
2603    }
2604    $r1 = $this->parsedouble_quoted_part($silence);
2605    if ($r1!==self::$FAILED) {
2606      goto choice_1;
2607    }
2608    $r1 = $this->parsebare_escape_sequence($silence);
2609    if ($r1!==self::$FAILED) {
2610      goto choice_1;
2611    }
2612    $r1 = $this->parsebackquote_expansion($silence);
2613    if ($r1!==self::$FAILED) {
2614      goto choice_1;
2615    }
2616    $r1 = $this->parsedollar_expansion($silence);
2617    if ($r1!==self::$FAILED) {
2618      goto choice_1;
2619    }
2620    $r1 = $this->parseplain_part($silence, $boolParams);
2621    choice_1:
2622    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2623
2624    $this->cache[$key] = $cached;
2625    return $r1;
2626  }
2627  private function discardreserved($silence) {
2628    $key = json_encode([345, $this->currPos]);
2629    $cached = $this->cache[$key] ?? null;
2630      if ($cached) {
2631        $this->currPos = $cached['nextPos'];
2632
2633        return $cached['result'];
2634      }
2635
2636    // start choice_1
2637    $r1 = $this->discardIf($silence);
2638    if ($r1!==self::$FAILED) {
2639      goto choice_1;
2640    }
2641    $r1 = $this->discardThen($silence);
2642    if ($r1!==self::$FAILED) {
2643      goto choice_1;
2644    }
2645    $r1 = $this->discardElse($silence);
2646    if ($r1!==self::$FAILED) {
2647      goto choice_1;
2648    }
2649    $r1 = $this->discardElif($silence);
2650    if ($r1!==self::$FAILED) {
2651      goto choice_1;
2652    }
2653    $r1 = $this->discardFi($silence);
2654    if ($r1!==self::$FAILED) {
2655      goto choice_1;
2656    }
2657    $r1 = $this->discardDo($silence);
2658    if ($r1!==self::$FAILED) {
2659      goto choice_1;
2660    }
2661    $r1 = $this->discardDone($silence);
2662    if ($r1!==self::$FAILED) {
2663      goto choice_1;
2664    }
2665    $r1 = $this->discardCase($silence);
2666    if ($r1!==self::$FAILED) {
2667      goto choice_1;
2668    }
2669    $r1 = $this->discardEsac($silence);
2670    if ($r1!==self::$FAILED) {
2671      goto choice_1;
2672    }
2673    $r1 = $this->discardWhile($silence);
2674    if ($r1!==self::$FAILED) {
2675      goto choice_1;
2676    }
2677    $r1 = $this->discardUntil($silence);
2678    if ($r1!==self::$FAILED) {
2679      goto choice_1;
2680    }
2681    $r1 = $this->discardFor($silence);
2682    if ($r1!==self::$FAILED) {
2683      goto choice_1;
2684    }
2685    $r1 = $this->discardLbrace($silence);
2686    if ($r1!==self::$FAILED) {
2687      goto choice_1;
2688    }
2689    $r1 = $this->discardRbrace($silence);
2690    if ($r1!==self::$FAILED) {
2691      goto choice_1;
2692    }
2693    $r1 = $this->discardBang($silence);
2694    if ($r1!==self::$FAILED) {
2695      goto choice_1;
2696    }
2697    $r1 = $this->discardIn($silence);
2698    choice_1:
2699    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2700
2701    $this->cache[$key] = $cached;
2702    return $r1;
2703  }
2704  private function discardLbrace($silence) {
2705    $key = json_encode([337, $this->currPos]);
2706    $cached = $this->cache[$key] ?? null;
2707      if ($cached) {
2708        $this->currPos = $cached['nextPos'];
2709
2710        return $cached['result'];
2711      }
2712
2713    // start seq_1
2714    $p1 = $this->currPos;
2715    if (($this->input[$this->currPos] ?? null) === "{") {
2716      $this->currPos++;
2717      $r3 = "{";
2718    } else {
2719      if (!$silence) {$this->fail(17);}
2720      $r3 = self::$FAILED;
2721      $r2 = self::$FAILED;
2722      goto seq_1;
2723    }
2724    $r4 = $this->discardDELIM($silence);
2725    if ($r4===self::$FAILED) {
2726      $this->currPos = $p1;
2727      $r2 = self::$FAILED;
2728      goto seq_1;
2729    }
2730    $r2 = true;
2731    seq_1:
2732    // free $r2,$p1
2733    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
2734
2735    $this->cache[$key] = $cached;
2736    return $r2;
2737  }
2738  private function parsecompound_list($silence) {
2739    $key = json_encode([226, $this->currPos]);
2740    $cached = $this->cache[$key] ?? null;
2741      if ($cached) {
2742        $this->currPos = $cached['nextPos'];
2743
2744        return $cached['result'];
2745      }
2746
2747    // start choice_1
2748    $p2 = $this->currPos;
2749    // start seq_1
2750    $p3 = $this->currPos;
2751    $r4 = $this->discardlinebreak($silence);
2752    if ($r4===self::$FAILED) {
2753      $r1 = self::$FAILED;
2754      goto seq_1;
2755    }
2756    $r5 = [];
2757    for (;;) {
2758      $p7 = $this->currPos;
2759      // start seq_2
2760      $p8 = $this->currPos;
2761      $r9 = $this->parseand_or($silence, 0x0);
2762      // term <- $r9
2763      if ($r9===self::$FAILED) {
2764        $r6 = self::$FAILED;
2765        goto seq_2;
2766      }
2767      $p11 = $this->currPos;
2768      $r10 = $this->discardseparator($silence);
2769      // separator <- $r10
2770      if ($r10!==self::$FAILED) {
2771        $r10 = substr($this->input, $p11, $this->currPos - $p11);
2772      } else {
2773        $r10 = self::$FAILED;
2774        $this->currPos = $p8;
2775        $r6 = self::$FAILED;
2776        goto seq_2;
2777      }
2778      // free $p11
2779      $r6 = true;
2780      seq_2:
2781      if ($r6!==self::$FAILED) {
2782        $this->savedPos = $p7;
2783        $r6 = $this->a31($r9, $r10);
2784        $r5[] = $r6;
2785      } else {
2786        break;
2787      }
2788      // free $p8
2789    }
2790    if (count($r5) === 0) {
2791      $r5 = self::$FAILED;
2792    }
2793    // terms <- $r5
2794    if ($r5===self::$FAILED) {
2795      $this->currPos = $p3;
2796      $r1 = self::$FAILED;
2797      goto seq_1;
2798    }
2799    // free $r6
2800    $r6 = $this->parseand_or($silence, 0x0);
2801    if ($r6===self::$FAILED) {
2802      $r6 = null;
2803    }
2804    // last <- $r6
2805    $r1 = true;
2806    seq_1:
2807    if ($r1!==self::$FAILED) {
2808      $this->savedPos = $p2;
2809      $r1 = $this->a32($r5, $r6);
2810      goto choice_1;
2811    }
2812    // free $p3
2813    $p3 = $this->currPos;
2814    // start seq_3
2815    $p8 = $this->currPos;
2816    $r12 = $this->discardlinebreak($silence);
2817    if ($r12===self::$FAILED) {
2818      $r1 = self::$FAILED;
2819      goto seq_3;
2820    }
2821    $r13 = $this->parseand_or($silence, 0x0);
2822    // term <- $r13
2823    if ($r13===self::$FAILED) {
2824      $this->currPos = $p8;
2825      $r1 = self::$FAILED;
2826      goto seq_3;
2827    }
2828    $r1 = true;
2829    seq_3:
2830    if ($r1!==self::$FAILED) {
2831      $this->savedPos = $p3;
2832      $r1 = $this->a33($r13);
2833    }
2834    // free $p8
2835    choice_1:
2836    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2837
2838    $this->cache[$key] = $cached;
2839    return $r1;
2840  }
2841  private function discardRbrace($silence) {
2842    $key = json_encode([339, $this->currPos]);
2843    $cached = $this->cache[$key] ?? null;
2844      if ($cached) {
2845        $this->currPos = $cached['nextPos'];
2846
2847        return $cached['result'];
2848      }
2849
2850    // start seq_1
2851    $p1 = $this->currPos;
2852    if (($this->input[$this->currPos] ?? null) === "}") {
2853      $this->currPos++;
2854      $r3 = "}";
2855    } else {
2856      if (!$silence) {$this->fail(18);}
2857      $r3 = self::$FAILED;
2858      $r2 = self::$FAILED;
2859      goto seq_1;
2860    }
2861    $r4 = $this->discardDELIM($silence);
2862    if ($r4===self::$FAILED) {
2863      $this->currPos = $p1;
2864      $r2 = self::$FAILED;
2865      goto seq_1;
2866    }
2867    $r2 = true;
2868    seq_1:
2869    // free $r2,$p1
2870    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
2871
2872    $this->cache[$key] = $cached;
2873    return $r2;
2874  }
2875  private function discardFor($silence) {
2876    $key = json_encode([335, $this->currPos]);
2877    $cached = $this->cache[$key] ?? null;
2878      if ($cached) {
2879        $this->currPos = $cached['nextPos'];
2880
2881        return $cached['result'];
2882      }
2883
2884    // start seq_1
2885    $p1 = $this->currPos;
2886    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "for", $this->currPos, 3, false) === 0) {
2887      $r3 = "for";
2888      $this->currPos += 3;
2889    } else {
2890      if (!$silence) {$this->fail(19);}
2891      $r3 = self::$FAILED;
2892      $r2 = self::$FAILED;
2893      goto seq_1;
2894    }
2895    $r4 = $this->discardDELIM($silence);
2896    if ($r4===self::$FAILED) {
2897      $this->currPos = $p1;
2898      $r2 = self::$FAILED;
2899      goto seq_1;
2900    }
2901    $r2 = true;
2902    seq_1:
2903    // free $r2,$p1
2904    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
2905
2906    $this->cache[$key] = $cached;
2907    return $r2;
2908  }
2909  private function parsefor_name($silence) {
2910    $key = json_encode([230, $this->currPos]);
2911    $cached = $this->cache[$key] ?? null;
2912      if ($cached) {
2913        $this->currPos = $cached['nextPos'];
2914
2915        return $cached['result'];
2916      }
2917
2918    $p2 = $this->currPos;
2919    // start seq_1
2920    $p3 = $this->currPos;
2921    $r4 = $this->parseNAME($silence);
2922    // name <- $r4
2923    if ($r4===self::$FAILED) {
2924      $r1 = self::$FAILED;
2925      goto seq_1;
2926    }
2927    $r5 = $this->discardOWS($silence);
2928    if ($r5===self::$FAILED) {
2929      $this->currPos = $p3;
2930      $r1 = self::$FAILED;
2931      goto seq_1;
2932    }
2933    $r1 = true;
2934    seq_1:
2935    if ($r1!==self::$FAILED) {
2936      $this->savedPos = $p2;
2937      $r1 = $this->a34($r4);
2938    }
2939    // free $p3
2940    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2941
2942    $this->cache[$key] = $cached;
2943    return $r1;
2944  }
2945  private function discardfor_case_in($silence) {
2946    $key = json_encode([233, $this->currPos]);
2947    $cached = $this->cache[$key] ?? null;
2948      if ($cached) {
2949        $this->currPos = $cached['nextPos'];
2950
2951        return $cached['result'];
2952      }
2953
2954    // start seq_1
2955    $p1 = $this->currPos;
2956    $r3 = $this->discardIn($silence);
2957    if ($r3===self::$FAILED) {
2958      $r2 = self::$FAILED;
2959      goto seq_1;
2960    }
2961    $r4 = $this->discardOWS($silence);
2962    if ($r4===self::$FAILED) {
2963      $this->currPos = $p1;
2964      $r2 = self::$FAILED;
2965      goto seq_1;
2966    }
2967    $r2 = true;
2968    seq_1:
2969    // free $r2,$p1
2970    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
2971
2972    $this->cache[$key] = $cached;
2973    return $r2;
2974  }
2975  private function parsewordlist($silence, $boolParams) {
2976    $key = json_encode([234, $this->currPos, $boolParams & 0x1]);
2977    $cached = $this->cache[$key] ?? null;
2978      if ($cached) {
2979        $this->currPos = $cached['nextPos'];
2980
2981        return $cached['result'];
2982      }
2983
2984    $r1 = [];
2985    for (;;) {
2986      $r2 = $this->parseWORD($silence, $boolParams);
2987      if ($r2!==self::$FAILED) {
2988        $r1[] = $r2;
2989      } else {
2990        break;
2991      }
2992    }
2993    if (count($r1) === 0) {
2994      $r1 = self::$FAILED;
2995    }
2996    // free $r2
2997    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
2998
2999    $this->cache[$key] = $cached;
3000    return $r1;
3001  }
3002  private function discardsequential_sep($silence) {
3003    $key = json_encode([291, $this->currPos]);
3004    $cached = $this->cache[$key] ?? null;
3005      if ($cached) {
3006        $this->currPos = $cached['nextPos'];
3007
3008        return $cached['result'];
3009      }
3010
3011    // start choice_1
3012    // start seq_1
3013    $p2 = $this->currPos;
3014    $r3 = $this->discardSEMI($silence);
3015    if ($r3===self::$FAILED) {
3016      $r1 = self::$FAILED;
3017      goto seq_1;
3018    }
3019    $r4 = $this->discardlinebreak($silence);
3020    if ($r4===self::$FAILED) {
3021      $this->currPos = $p2;
3022      $r1 = self::$FAILED;
3023      goto seq_1;
3024    }
3025    $r1 = true;
3026    seq_1:
3027    if ($r1!==self::$FAILED) {
3028      goto choice_1;
3029    }
3030    // free $p2
3031    $r1 = $this->discardnewline_list($silence);
3032    choice_1:
3033    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3034
3035    $this->cache[$key] = $cached;
3036    return $r1;
3037  }
3038  private function parsedo_group($silence) {
3039    $key = json_encode([262, $this->currPos]);
3040    $cached = $this->cache[$key] ?? null;
3041      if ($cached) {
3042        $this->currPos = $cached['nextPos'];
3043
3044        return $cached['result'];
3045      }
3046
3047    $p2 = $this->currPos;
3048    // start seq_1
3049    $p3 = $this->currPos;
3050    $r4 = $this->discardDo($silence);
3051    if ($r4===self::$FAILED) {
3052      $r1 = self::$FAILED;
3053      goto seq_1;
3054    }
3055    $r5 = $this->parsecompound_list($silence);
3056    // list <- $r5
3057    if ($r5===self::$FAILED) {
3058      $this->currPos = $p3;
3059      $r1 = self::$FAILED;
3060      goto seq_1;
3061    }
3062    $r6 = $this->discardDone($silence);
3063    if ($r6===self::$FAILED) {
3064      $this->currPos = $p3;
3065      $r1 = self::$FAILED;
3066      goto seq_1;
3067    }
3068    $r1 = true;
3069    seq_1:
3070    if ($r1!==self::$FAILED) {
3071      $this->savedPos = $p2;
3072      $r1 = $this->a35($r5);
3073    }
3074    // free $p3
3075    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3076
3077    $this->cache[$key] = $cached;
3078    return $r1;
3079  }
3080  private function discardCase($silence) {
3081    $key = json_encode([327, $this->currPos]);
3082    $cached = $this->cache[$key] ?? null;
3083      if ($cached) {
3084        $this->currPos = $cached['nextPos'];
3085
3086        return $cached['result'];
3087      }
3088
3089    // start seq_1
3090    $p1 = $this->currPos;
3091    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "case", $this->currPos, 4, false) === 0) {
3092      $r3 = "case";
3093      $this->currPos += 4;
3094    } else {
3095      if (!$silence) {$this->fail(20);}
3096      $r3 = self::$FAILED;
3097      $r2 = self::$FAILED;
3098      goto seq_1;
3099    }
3100    $r4 = $this->discardDELIM($silence);
3101    if ($r4===self::$FAILED) {
3102      $this->currPos = $p1;
3103      $r2 = self::$FAILED;
3104      goto seq_1;
3105    }
3106    $r2 = true;
3107    seq_1:
3108    // free $r2,$p1
3109    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3110
3111    $this->cache[$key] = $cached;
3112    return $r2;
3113  }
3114  private function parsecase_list($silence, $boolParams) {
3115    $key = json_encode([240, $this->currPos, $boolParams & 0x1]);
3116    $cached = $this->cache[$key] ?? null;
3117      if ($cached) {
3118        $this->currPos = $cached['nextPos'];
3119
3120        return $cached['result'];
3121      }
3122
3123    $r1 = [];
3124    for (;;) {
3125      $r2 = $this->parsecase_item($silence, $boolParams);
3126      if ($r2!==self::$FAILED) {
3127        $r1[] = $r2;
3128      } else {
3129        break;
3130      }
3131    }
3132    if (count($r1) === 0) {
3133      $r1 = self::$FAILED;
3134    }
3135    // free $r2
3136    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3137
3138    $this->cache[$key] = $cached;
3139    return $r1;
3140  }
3141  private function discardEsac($silence) {
3142    $key = json_encode([329, $this->currPos]);
3143    $cached = $this->cache[$key] ?? null;
3144      if ($cached) {
3145        $this->currPos = $cached['nextPos'];
3146
3147        return $cached['result'];
3148      }
3149
3150    // start seq_1
3151    $p1 = $this->currPos;
3152    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "esac", $this->currPos, 4, false) === 0) {
3153      $r3 = "esac";
3154      $this->currPos += 4;
3155    } else {
3156      if (!$silence) {$this->fail(21);}
3157      $r3 = self::$FAILED;
3158      $r2 = self::$FAILED;
3159      goto seq_1;
3160    }
3161    $r4 = $this->discardDELIM($silence);
3162    if ($r4===self::$FAILED) {
3163      $this->currPos = $p1;
3164      $r2 = self::$FAILED;
3165      goto seq_1;
3166    }
3167    $r2 = true;
3168    seq_1:
3169    // free $r2,$p1
3170    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3171
3172    $this->cache[$key] = $cached;
3173    return $r2;
3174  }
3175  private function parsecase_list_ns($silence, $boolParams) {
3176    $key = json_encode([238, $this->currPos, $boolParams & 0x1]);
3177    $cached = $this->cache[$key] ?? null;
3178      if ($cached) {
3179        $this->currPos = $cached['nextPos'];
3180
3181        return $cached['result'];
3182      }
3183
3184    // start choice_1
3185    $p2 = $this->currPos;
3186    // start seq_1
3187    $p3 = $this->currPos;
3188    $r4 = $this->parsecase_list($silence, $boolParams);
3189    // list <- $r4
3190    if ($r4===self::$FAILED) {
3191      $r1 = self::$FAILED;
3192      goto seq_1;
3193    }
3194    $r5 = $this->parsecase_item_ns($silence, $boolParams);
3195    // item <- $r5
3196    if ($r5===self::$FAILED) {
3197      $this->currPos = $p3;
3198      $r1 = self::$FAILED;
3199      goto seq_1;
3200    }
3201    $r1 = true;
3202    seq_1:
3203    if ($r1!==self::$FAILED) {
3204      $this->savedPos = $p2;
3205      $r1 = $this->a36($r4, $r5);
3206      goto choice_1;
3207    }
3208    // free $p3
3209    $p3 = $this->currPos;
3210    $r6 = $this->parsecase_item_ns($silence, $boolParams);
3211    // item <- $r6
3212    $r1 = $r6;
3213    if ($r1!==self::$FAILED) {
3214      $this->savedPos = $p3;
3215      $r1 = $this->a37($r6);
3216    }
3217    choice_1:
3218    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3219
3220    $this->cache[$key] = $cached;
3221    return $r1;
3222  }
3223  private function discardIf($silence) {
3224    $key = json_encode([313, $this->currPos]);
3225    $cached = $this->cache[$key] ?? null;
3226      if ($cached) {
3227        $this->currPos = $cached['nextPos'];
3228
3229        return $cached['result'];
3230      }
3231
3232    // start seq_1
3233    $p1 = $this->currPos;
3234    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "if", $this->currPos, 2, false) === 0) {
3235      $r3 = "if";
3236      $this->currPos += 2;
3237    } else {
3238      if (!$silence) {$this->fail(22);}
3239      $r3 = self::$FAILED;
3240      $r2 = self::$FAILED;
3241      goto seq_1;
3242    }
3243    $r4 = $this->discardDELIM($silence);
3244    if ($r4===self::$FAILED) {
3245      $this->currPos = $p1;
3246      $r2 = self::$FAILED;
3247      goto seq_1;
3248    }
3249    $r2 = true;
3250    seq_1:
3251    // free $r2,$p1
3252    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3253
3254    $this->cache[$key] = $cached;
3255    return $r2;
3256  }
3257  private function discardThen($silence) {
3258    $key = json_encode([315, $this->currPos]);
3259    $cached = $this->cache[$key] ?? null;
3260      if ($cached) {
3261        $this->currPos = $cached['nextPos'];
3262
3263        return $cached['result'];
3264      }
3265
3266    // start seq_1
3267    $p1 = $this->currPos;
3268    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "then", $this->currPos, 4, false) === 0) {
3269      $r3 = "then";
3270      $this->currPos += 4;
3271    } else {
3272      if (!$silence) {$this->fail(23);}
3273      $r3 = self::$FAILED;
3274      $r2 = self::$FAILED;
3275      goto seq_1;
3276    }
3277    $r4 = $this->discardDELIM($silence);
3278    if ($r4===self::$FAILED) {
3279      $this->currPos = $p1;
3280      $r2 = self::$FAILED;
3281      goto seq_1;
3282    }
3283    $r2 = true;
3284    seq_1:
3285    // free $r2,$p1
3286    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3287
3288    $this->cache[$key] = $cached;
3289    return $r2;
3290  }
3291  private function parseelse_part($silence) {
3292    $key = json_encode([250, $this->currPos]);
3293    $cached = $this->cache[$key] ?? null;
3294      if ($cached) {
3295        $this->currPos = $cached['nextPos'];
3296
3297        return $cached['result'];
3298      }
3299
3300    // start choice_1
3301    $p2 = $this->currPos;
3302    // start seq_1
3303    $p3 = $this->currPos;
3304    $r4 = $this->discardElif($silence);
3305    if ($r4===self::$FAILED) {
3306      $r1 = self::$FAILED;
3307      goto seq_1;
3308    }
3309    $r5 = $this->parsecompound_list($silence);
3310    // condition <- $r5
3311    if ($r5===self::$FAILED) {
3312      $this->currPos = $p3;
3313      $r1 = self::$FAILED;
3314      goto seq_1;
3315    }
3316    $r6 = $this->discardThen($silence);
3317    if ($r6===self::$FAILED) {
3318      $this->currPos = $p3;
3319      $r1 = self::$FAILED;
3320      goto seq_1;
3321    }
3322    $r7 = $this->parsecompound_list($silence);
3323    // consequent <- $r7
3324    if ($r7===self::$FAILED) {
3325      $this->currPos = $p3;
3326      $r1 = self::$FAILED;
3327      goto seq_1;
3328    }
3329    $r8 = $this->parseelse_part($silence);
3330    if ($r8===self::$FAILED) {
3331      $r8 = null;
3332    }
3333    // else_part <- $r8
3334    $r1 = true;
3335    seq_1:
3336    if ($r1!==self::$FAILED) {
3337      $this->savedPos = $p2;
3338      $r1 = $this->a38($r5, $r7, $r8);
3339      goto choice_1;
3340    }
3341    // free $p3
3342    $p3 = $this->currPos;
3343    // start seq_2
3344    $p9 = $this->currPos;
3345    $r10 = $this->discardElse($silence);
3346    if ($r10===self::$FAILED) {
3347      $r1 = self::$FAILED;
3348      goto seq_2;
3349    }
3350    $r11 = $this->parsecompound_list($silence);
3351    // alternative <- $r11
3352    if ($r11===self::$FAILED) {
3353      $this->currPos = $p9;
3354      $r1 = self::$FAILED;
3355      goto seq_2;
3356    }
3357    $r1 = true;
3358    seq_2:
3359    if ($r1!==self::$FAILED) {
3360      $this->savedPos = $p3;
3361      $r1 = $this->a39($r11);
3362    }
3363    // free $p9
3364    choice_1:
3365    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3366
3367    $this->cache[$key] = $cached;
3368    return $r1;
3369  }
3370  private function discardFi($silence) {
3371    $key = json_encode([321, $this->currPos]);
3372    $cached = $this->cache[$key] ?? null;
3373      if ($cached) {
3374        $this->currPos = $cached['nextPos'];
3375
3376        return $cached['result'];
3377      }
3378
3379    // start seq_1
3380    $p1 = $this->currPos;
3381    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "fi", $this->currPos, 2, false) === 0) {
3382      $r3 = "fi";
3383      $this->currPos += 2;
3384    } else {
3385      if (!$silence) {$this->fail(24);}
3386      $r3 = self::$FAILED;
3387      $r2 = self::$FAILED;
3388      goto seq_1;
3389    }
3390    $r4 = $this->discardDELIM($silence);
3391    if ($r4===self::$FAILED) {
3392      $this->currPos = $p1;
3393      $r2 = self::$FAILED;
3394      goto seq_1;
3395    }
3396    $r2 = true;
3397    seq_1:
3398    // free $r2,$p1
3399    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3400
3401    $this->cache[$key] = $cached;
3402    return $r2;
3403  }
3404  private function discardWhile($silence) {
3405    $key = json_encode([331, $this->currPos]);
3406    $cached = $this->cache[$key] ?? null;
3407      if ($cached) {
3408        $this->currPos = $cached['nextPos'];
3409
3410        return $cached['result'];
3411      }
3412
3413    // start seq_1
3414    $p1 = $this->currPos;
3415    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "while", $this->currPos, 5, false) === 0) {
3416      $r3 = "while";
3417      $this->currPos += 5;
3418    } else {
3419      if (!$silence) {$this->fail(25);}
3420      $r3 = self::$FAILED;
3421      $r2 = self::$FAILED;
3422      goto seq_1;
3423    }
3424    $r4 = $this->discardDELIM($silence);
3425    if ($r4===self::$FAILED) {
3426      $this->currPos = $p1;
3427      $r2 = self::$FAILED;
3428      goto seq_1;
3429    }
3430    $r2 = true;
3431    seq_1:
3432    // free $r2,$p1
3433    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3434
3435    $this->cache[$key] = $cached;
3436    return $r2;
3437  }
3438  private function discardUntil($silence) {
3439    $key = json_encode([333, $this->currPos]);
3440    $cached = $this->cache[$key] ?? null;
3441      if ($cached) {
3442        $this->currPos = $cached['nextPos'];
3443
3444        return $cached['result'];
3445      }
3446
3447    // start seq_1
3448    $p1 = $this->currPos;
3449    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "until", $this->currPos, 5, false) === 0) {
3450      $r3 = "until";
3451      $this->currPos += 5;
3452    } else {
3453      if (!$silence) {$this->fail(26);}
3454      $r3 = self::$FAILED;
3455      $r2 = self::$FAILED;
3456      goto seq_1;
3457    }
3458    $r4 = $this->discardDELIM($silence);
3459    if ($r4===self::$FAILED) {
3460      $this->currPos = $p1;
3461      $r2 = self::$FAILED;
3462      goto seq_1;
3463    }
3464    $r2 = true;
3465    seq_1:
3466    // free $r2,$p1
3467    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3468
3469    $this->cache[$key] = $cached;
3470    return $r2;
3471  }
3472  private function parseIO_NUMBER($silence) {
3473    $key = json_encode([414, $this->currPos]);
3474    $cached = $this->cache[$key] ?? null;
3475      if ($cached) {
3476        $this->currPos = $cached['nextPos'];
3477
3478        return $cached['result'];
3479      }
3480
3481    $p1 = $this->currPos;
3482    $r2 = self::$FAILED;
3483    for (;;) {
3484      $r3 = $this->input[$this->currPos] ?? '';
3485      if (preg_match("/^[0-9]/", $r3)) {
3486        $this->currPos++;
3487        $r2 = true;
3488      } else {
3489        $r3 = self::$FAILED;
3490        if (!$silence) {$this->fail(27);}
3491        break;
3492      }
3493    }
3494    if ($r2!==self::$FAILED) {
3495      $r2 = substr($this->input, $p1, $this->currPos - $p1);
3496    } else {
3497      $r2 = self::$FAILED;
3498    }
3499    // free $r3
3500    // free $p1
3501    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
3502
3503    $this->cache[$key] = $cached;
3504    return $r2;
3505  }
3506  private function parseio_file($silence, $boolParams) {
3507    $key = json_encode([276, $this->currPos, $boolParams & 0x1]);
3508    $cached = $this->cache[$key] ?? null;
3509      if ($cached) {
3510        $this->currPos = $cached['nextPos'];
3511
3512        return $cached['result'];
3513      }
3514
3515    // start choice_1
3516    $p2 = $this->currPos;
3517    // start seq_1
3518    $p3 = $this->currPos;
3519    $r4 = $this->discardLESSAND($silence);
3520    if ($r4===self::$FAILED) {
3521      $r1 = self::$FAILED;
3522      goto seq_1;
3523    }
3524    $r5 = $this->parseWORD($silence, $boolParams);
3525    // filename <- $r5
3526    if ($r5===self::$FAILED) {
3527      $this->currPos = $p3;
3528      $r1 = self::$FAILED;
3529      goto seq_1;
3530    }
3531    $r1 = true;
3532    seq_1:
3533    if ($r1!==self::$FAILED) {
3534      $this->savedPos = $p2;
3535      $r1 = $this->a40($r5);
3536      goto choice_1;
3537    }
3538    // free $p3
3539    $p3 = $this->currPos;
3540    // start seq_2
3541    $p6 = $this->currPos;
3542    $r7 = $this->discardLESSGREAT($silence);
3543    if ($r7===self::$FAILED) {
3544      $r1 = self::$FAILED;
3545      goto seq_2;
3546    }
3547    $r8 = $this->parseWORD($silence, $boolParams);
3548    // filename <- $r8
3549    if ($r8===self::$FAILED) {
3550      $this->currPos = $p6;
3551      $r1 = self::$FAILED;
3552      goto seq_2;
3553    }
3554    $r1 = true;
3555    seq_2:
3556    if ($r1!==self::$FAILED) {
3557      $this->savedPos = $p3;
3558      $r1 = $this->a41($r8);
3559      goto choice_1;
3560    }
3561    // free $p6
3562    $p6 = $this->currPos;
3563    // start seq_3
3564    $p9 = $this->currPos;
3565    $r10 = $this->discardLESS($silence);
3566    if ($r10===self::$FAILED) {
3567      $r1 = self::$FAILED;
3568      goto seq_3;
3569    }
3570    $r11 = $this->parseWORD($silence, $boolParams);
3571    // filename <- $r11
3572    if ($r11===self::$FAILED) {
3573      $this->currPos = $p9;
3574      $r1 = self::$FAILED;
3575      goto seq_3;
3576    }
3577    $r1 = true;
3578    seq_3:
3579    if ($r1!==self::$FAILED) {
3580      $this->savedPos = $p6;
3581      $r1 = $this->a42($r11);
3582      goto choice_1;
3583    }
3584    // free $p9
3585    $p9 = $this->currPos;
3586    // start seq_4
3587    $p12 = $this->currPos;
3588    $r13 = $this->discardGREATAND($silence);
3589    if ($r13===self::$FAILED) {
3590      $r1 = self::$FAILED;
3591      goto seq_4;
3592    }
3593    $r14 = $this->parseWORD($silence, $boolParams);
3594    // filename <- $r14
3595    if ($r14===self::$FAILED) {
3596      $this->currPos = $p12;
3597      $r1 = self::$FAILED;
3598      goto seq_4;
3599    }
3600    $r1 = true;
3601    seq_4:
3602    if ($r1!==self::$FAILED) {
3603      $this->savedPos = $p9;
3604      $r1 = $this->a43($r14);
3605      goto choice_1;
3606    }
3607    // free $p12
3608    $p12 = $this->currPos;
3609    // start seq_5
3610    $p15 = $this->currPos;
3611    $r16 = $this->discardDGREAT($silence);
3612    if ($r16===self::$FAILED) {
3613      $r1 = self::$FAILED;
3614      goto seq_5;
3615    }
3616    $r17 = $this->parseWORD($silence, $boolParams);
3617    // filename <- $r17
3618    if ($r17===self::$FAILED) {
3619      $this->currPos = $p15;
3620      $r1 = self::$FAILED;
3621      goto seq_5;
3622    }
3623    $r1 = true;
3624    seq_5:
3625    if ($r1!==self::$FAILED) {
3626      $this->savedPos = $p12;
3627      $r1 = $this->a44($r17);
3628      goto choice_1;
3629    }
3630    // free $p15
3631    $p15 = $this->currPos;
3632    // start seq_6
3633    $p18 = $this->currPos;
3634    $r19 = $this->discardCLOBBER($silence);
3635    if ($r19===self::$FAILED) {
3636      $r1 = self::$FAILED;
3637      goto seq_6;
3638    }
3639    $r20 = $this->parseWORD($silence, $boolParams);
3640    // filename <- $r20
3641    if ($r20===self::$FAILED) {
3642      $this->currPos = $p18;
3643      $r1 = self::$FAILED;
3644      goto seq_6;
3645    }
3646    $r1 = true;
3647    seq_6:
3648    if ($r1!==self::$FAILED) {
3649      $this->savedPos = $p15;
3650      $r1 = $this->a45($r20);
3651      goto choice_1;
3652    }
3653    // free $p18
3654    $p18 = $this->currPos;
3655    // start seq_7
3656    $p21 = $this->currPos;
3657    $r22 = $this->discardGREAT($silence);
3658    if ($r22===self::$FAILED) {
3659      $r1 = self::$FAILED;
3660      goto seq_7;
3661    }
3662    $r23 = $this->parseWORD($silence, $boolParams);
3663    // filename <- $r23
3664    if ($r23===self::$FAILED) {
3665      $this->currPos = $p21;
3666      $r1 = self::$FAILED;
3667      goto seq_7;
3668    }
3669    $r1 = true;
3670    seq_7:
3671    if ($r1!==self::$FAILED) {
3672      $this->savedPos = $p18;
3673      $r1 = $this->a46($r23);
3674    }
3675    // free $p21
3676    choice_1:
3677    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3678
3679    $this->cache[$key] = $cached;
3680    return $r1;
3681  }
3682  private function parseio_here($silence, $boolParams) {
3683    $key = json_encode([278, $this->currPos, $boolParams & 0x1]);
3684    $cached = $this->cache[$key] ?? null;
3685      if ($cached) {
3686        $this->currPos = $cached['nextPos'];
3687
3688        return $cached['result'];
3689      }
3690
3691    $p2 = $this->currPos;
3692    // start seq_1
3693    $p3 = $this->currPos;
3694    // start choice_1
3695    $p5 = $this->currPos;
3696    $r4 = $this->discardDLESSDASH($silence);
3697    if ($r4!==self::$FAILED) {
3698      $this->savedPos = $p5;
3699      $r4 = $this->a47();
3700      goto choice_1;
3701    }
3702    $p6 = $this->currPos;
3703    $r4 = $this->discardDLESS($silence);
3704    if ($r4!==self::$FAILED) {
3705      $this->savedPos = $p6;
3706      $r4 = $this->a48();
3707    }
3708    choice_1:
3709    // op <- $r4
3710    if ($r4===self::$FAILED) {
3711      $r1 = self::$FAILED;
3712      goto seq_1;
3713    }
3714    $r7 = $this->parsehere_end($silence, $boolParams);
3715    // end <- $r7
3716    if ($r7===self::$FAILED) {
3717      $this->currPos = $p3;
3718      $r1 = self::$FAILED;
3719      goto seq_1;
3720    }
3721    $r1 = true;
3722    seq_1:
3723    if ($r1!==self::$FAILED) {
3724      $this->savedPos = $p2;
3725      $r1 = $this->a49($r4, $r7);
3726    }
3727    // free $p3
3728    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3729
3730    $this->cache[$key] = $cached;
3731    return $r1;
3732  }
3733  private function parsesingle_quoted_part($silence) {
3734    $key = json_encode([368, $this->currPos]);
3735    $cached = $this->cache[$key] ?? null;
3736      if ($cached) {
3737        $this->currPos = $cached['nextPos'];
3738
3739        return $cached['result'];
3740      }
3741
3742    $p2 = $this->currPos;
3743    // start seq_1
3744    $p3 = $this->currPos;
3745    if (($this->input[$this->currPos] ?? null) === "'") {
3746      $this->currPos++;
3747      $r4 = "'";
3748    } else {
3749      if (!$silence) {$this->fail(28);}
3750      $r4 = self::$FAILED;
3751      $r1 = self::$FAILED;
3752      goto seq_1;
3753    }
3754    $p6 = $this->currPos;
3755    for (;;) {
3756      $r7 = self::charAt($this->input, $this->currPos);
3757      if ($r7 !== '' && !($r7 === "'")) {
3758        $this->currPos += strlen($r7);
3759      } else {
3760        $r7 = self::$FAILED;
3761        if (!$silence) {$this->fail(29);}
3762        break;
3763      }
3764    }
3765    // free $r7
3766    $r5 = true;
3767    // contents <- $r5
3768    if ($r5!==self::$FAILED) {
3769      $r5 = substr($this->input, $p6, $this->currPos - $p6);
3770    } else {
3771      $r5 = self::$FAILED;
3772      $this->currPos = $p3;
3773      $r1 = self::$FAILED;
3774      goto seq_1;
3775    }
3776    // free $p6
3777    if (($this->input[$this->currPos] ?? null) === "'") {
3778      $this->currPos++;
3779      $r7 = "'";
3780    } else {
3781      if (!$silence) {$this->fail(28);}
3782      $r7 = self::$FAILED;
3783      $this->currPos = $p3;
3784      $r1 = self::$FAILED;
3785      goto seq_1;
3786    }
3787    $r1 = true;
3788    seq_1:
3789    if ($r1!==self::$FAILED) {
3790      $this->savedPos = $p2;
3791      $r1 = $this->a50($r5);
3792    }
3793    // free $p3
3794    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3795
3796    $this->cache[$key] = $cached;
3797    return $r1;
3798  }
3799  private function parsedouble_quoted_part($silence) {
3800    $key = json_encode([370, $this->currPos]);
3801    $cached = $this->cache[$key] ?? null;
3802      if ($cached) {
3803        $this->currPos = $cached['nextPos'];
3804
3805        return $cached['result'];
3806      }
3807
3808    $p2 = $this->currPos;
3809    // start seq_1
3810    $p3 = $this->currPos;
3811    if (($this->input[$this->currPos] ?? null) === "\"") {
3812      $this->currPos++;
3813      $r4 = "\"";
3814    } else {
3815      if (!$silence) {$this->fail(30);}
3816      $r4 = self::$FAILED;
3817      $r1 = self::$FAILED;
3818      goto seq_1;
3819    }
3820    $r5 = [];
3821    for (;;) {
3822      // start choice_1
3823      $r6 = $this->parsedquoted_escape($silence);
3824      if ($r6!==self::$FAILED) {
3825        goto choice_1;
3826      }
3827      $r6 = $this->parsebackquote_expansion($silence);
3828      if ($r6!==self::$FAILED) {
3829        goto choice_1;
3830      }
3831      $r6 = $this->parsedollar_expansion($silence);
3832      if ($r6!==self::$FAILED) {
3833        goto choice_1;
3834      }
3835      if (($this->input[$this->currPos] ?? null) === "\\") {
3836        $this->currPos++;
3837        $r6 = "\\";
3838        goto choice_1;
3839      } else {
3840        if (!$silence) {$this->fail(31);}
3841        $r6 = self::$FAILED;
3842      }
3843      $p7 = $this->currPos;
3844      $r6 = self::$FAILED;
3845      for (;;) {
3846        if (strcspn($this->input, "\"`\$\\", $this->currPos, 1) !== 0) {
3847          $r8 = self::consumeChar($this->input, $this->currPos);
3848          $r6 = true;
3849        } else {
3850          $r8 = self::$FAILED;
3851          if (!$silence) {$this->fail(32);}
3852          break;
3853        }
3854      }
3855      if ($r6!==self::$FAILED) {
3856        $r6 = substr($this->input, $p7, $this->currPos - $p7);
3857      } else {
3858        $r6 = self::$FAILED;
3859      }
3860      // free $r8
3861      // free $p7
3862      choice_1:
3863      if ($r6!==self::$FAILED) {
3864        $r5[] = $r6;
3865      } else {
3866        break;
3867      }
3868    }
3869    // contents <- $r5
3870    // free $r6
3871    if (($this->input[$this->currPos] ?? null) === "\"") {
3872      $this->currPos++;
3873      $r6 = "\"";
3874    } else {
3875      if (!$silence) {$this->fail(30);}
3876      $r6 = self::$FAILED;
3877      $this->currPos = $p3;
3878      $r1 = self::$FAILED;
3879      goto seq_1;
3880    }
3881    $r1 = true;
3882    seq_1:
3883    if ($r1!==self::$FAILED) {
3884      $this->savedPos = $p2;
3885      $r1 = $this->a51($r5);
3886    }
3887    // free $p3
3888    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3889
3890    $this->cache[$key] = $cached;
3891    return $r1;
3892  }
3893  private function parsebare_escape_sequence($silence) {
3894    $key = json_encode([374, $this->currPos]);
3895    $cached = $this->cache[$key] ?? null;
3896      if ($cached) {
3897        $this->currPos = $cached['nextPos'];
3898
3899        return $cached['result'];
3900      }
3901
3902    $p2 = $this->currPos;
3903    // start seq_1
3904    $p3 = $this->currPos;
3905    if (($this->input[$this->currPos] ?? null) === "\\") {
3906      $this->currPos++;
3907      $r4 = "\\";
3908    } else {
3909      if (!$silence) {$this->fail(31);}
3910      $r4 = self::$FAILED;
3911      $r1 = self::$FAILED;
3912      goto seq_1;
3913    }
3914    $r5 = self::charAt($this->input, $this->currPos);
3915    // contents <- $r5
3916    if ($r5 !== '' && !($r5 === "\x0a")) {
3917      $this->currPos += strlen($r5);
3918    } else {
3919      $r5 = self::$FAILED;
3920      if (!$silence) {$this->fail(4);}
3921      $this->currPos = $p3;
3922      $r1 = self::$FAILED;
3923      goto seq_1;
3924    }
3925    $r1 = true;
3926    seq_1:
3927    if ($r1!==self::$FAILED) {
3928      $this->savedPos = $p2;
3929      $r1 = $this->a52($r5);
3930    }
3931    // free $p3
3932    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
3933
3934    $this->cache[$key] = $cached;
3935    return $r1;
3936  }
3937  private function parsebackquote_expansion($silence) {
3938    $key = json_encode([376, $this->currPos]);
3939    $cached = $this->cache[$key] ?? null;
3940      if ($cached) {
3941        $this->currPos = $cached['nextPos'];
3942
3943        return $cached['result'];
3944      }
3945
3946    $p2 = $this->currPos;
3947    // start seq_1
3948    $p3 = $this->currPos;
3949    if (($this->input[$this->currPos] ?? null) === "`") {
3950      $this->currPos++;
3951      $r4 = "`";
3952    } else {
3953      if (!$silence) {$this->fail(33);}
3954      $r4 = self::$FAILED;
3955      $r1 = self::$FAILED;
3956      goto seq_1;
3957    }
3958    $r5 = [];
3959    for (;;) {
3960      // start choice_1
3961      $r6 = $this->parsebackquoted_escape($silence);
3962      if ($r6!==self::$FAILED) {
3963        goto choice_1;
3964      }
3965      $r6 = $this->parsedollar_expansion($silence);
3966      if ($r6!==self::$FAILED) {
3967        goto choice_1;
3968      }
3969      $r6 = $this->parsedouble_backquote_expansion($silence);
3970      if ($r6!==self::$FAILED) {
3971        goto choice_1;
3972      }
3973      if (($this->input[$this->currPos] ?? null) === "\$") {
3974        $this->currPos++;
3975        $r6 = "\$";
3976        goto choice_1;
3977      } else {
3978        if (!$silence) {$this->fail(34);}
3979        $r6 = self::$FAILED;
3980      }
3981      if (($this->input[$this->currPos] ?? null) === "\\") {
3982        $this->currPos++;
3983        $r6 = "\\";
3984        goto choice_1;
3985      } else {
3986        if (!$silence) {$this->fail(31);}
3987        $r6 = self::$FAILED;
3988      }
3989      $p7 = $this->currPos;
3990      $r6 = self::$FAILED;
3991      for (;;) {
3992        if (strcspn($this->input, "`\$\\", $this->currPos, 1) !== 0) {
3993          $r8 = self::consumeChar($this->input, $this->currPos);
3994          $r6 = true;
3995        } else {
3996          $r8 = self::$FAILED;
3997          if (!$silence) {$this->fail(35);}
3998          break;
3999        }
4000      }
4001      if ($r6!==self::$FAILED) {
4002        $r6 = substr($this->input, $p7, $this->currPos - $p7);
4003      } else {
4004        $r6 = self::$FAILED;
4005      }
4006      // free $r8
4007      // free $p7
4008      choice_1:
4009      if ($r6!==self::$FAILED) {
4010        $r5[] = $r6;
4011      } else {
4012        break;
4013      }
4014    }
4015    // parts <- $r5
4016    // free $r6
4017    if (($this->input[$this->currPos] ?? null) === "`") {
4018      $this->currPos++;
4019      $r6 = "`";
4020    } else {
4021      if (!$silence) {$this->fail(33);}
4022      $r6 = self::$FAILED;
4023      $this->currPos = $p3;
4024      $r1 = self::$FAILED;
4025      goto seq_1;
4026    }
4027    $r1 = true;
4028    seq_1:
4029    if ($r1!==self::$FAILED) {
4030      $this->savedPos = $p2;
4031      $r1 = $this->a53($r5);
4032    }
4033    // free $p3
4034    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
4035
4036    $this->cache[$key] = $cached;
4037    return $r1;
4038  }
4039  private function parsedollar_expansion($silence) {
4040    $key = json_encode([382, $this->currPos]);
4041    $cached = $this->cache[$key] ?? null;
4042      if ($cached) {
4043        $this->currPos = $cached['nextPos'];
4044
4045        return $cached['result'];
4046      }
4047
4048    $p2 = $this->currPos;
4049    // start seq_1
4050    $p3 = $this->currPos;
4051    if (($this->input[$this->currPos] ?? null) === "\$") {
4052      $this->currPos++;
4053      $r4 = "\$";
4054    } else {
4055      if (!$silence) {$this->fail(34);}
4056      $r4 = self::$FAILED;
4057      $r1 = self::$FAILED;
4058      goto seq_1;
4059    }
4060    // start choice_1
4061    $r5 = $this->parsespecial_parameter($silence);
4062    if ($r5!==self::$FAILED) {
4063      goto choice_1;
4064    }
4065    $r5 = $this->parseshort_positional_parameter($silence);
4066    if ($r5!==self::$FAILED) {
4067      goto choice_1;
4068    }
4069    $r5 = $this->parsebrace_expansion($silence);
4070    if ($r5!==self::$FAILED) {
4071      goto choice_1;
4072    }
4073    $r5 = $this->parsearithmetic_expansion($silence);
4074    if ($r5!==self::$FAILED) {
4075      goto choice_1;
4076    }
4077    $r5 = $this->parsecommand_expansion($silence);
4078    if ($r5!==self::$FAILED) {
4079      goto choice_1;
4080    }
4081    $r5 = $this->parsenamed_parameter($silence);
4082    choice_1:
4083    // contents <- $r5
4084    if ($r5===self::$FAILED) {
4085      $this->currPos = $p3;
4086      $r1 = self::$FAILED;
4087      goto seq_1;
4088    }
4089    $r1 = true;
4090    seq_1:
4091    if ($r1!==self::$FAILED) {
4092      $this->savedPos = $p2;
4093      $r1 = $this->a54($r5);
4094    }
4095    // free $p3
4096    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
4097
4098    $this->cache[$key] = $cached;
4099    return $r1;
4100  }
4101  private function parseplain_part($silence, $boolParams) {
4102    $key = json_encode([406, $this->currPos, $boolParams & 0x1]);
4103    $cached = $this->cache[$key] ?? null;
4104      if ($cached) {
4105        $this->currPos = $cached['nextPos'];
4106
4107        return $cached['result'];
4108      }
4109
4110    $p2 = $this->currPos;
4111    // start choice_1
4112    $p4 = $this->currPos;
4113    // start seq_1
4114    $p5 = $this->currPos;
4115    if (/*no_rbrace*/($boolParams & 0x1) !== 0) {
4116      $r6 = false;
4117    } else {
4118      $r6 = self::$FAILED;
4119      $r3 = self::$FAILED;
4120      goto seq_1;
4121    }
4122    $r7 = self::$FAILED;
4123    for (;;) {
4124      if (strcspn($this->input, "'\"\\`\$ \x09\x0b\x0d\x0c\x0a&|;<>(){}", $this->currPos, 1) !== 0) {
4125        $r8 = self::consumeChar($this->input, $this->currPos);
4126        $r7 = true;
4127      } else {
4128        $r8 = self::$FAILED;
4129        if (!$silence) {$this->fail(36);}
4130        break;
4131      }
4132    }
4133    if ($r7===self::$FAILED) {
4134      $this->currPos = $p5;
4135      $r3 = self::$FAILED;
4136      goto seq_1;
4137    }
4138    // free $r8
4139    $r3 = true;
4140    seq_1:
4141    if ($r3!==self::$FAILED) {
4142      $r3 = substr($this->input, $p4, $this->currPos - $p4);
4143      goto choice_1;
4144    } else {
4145      $r3 = self::$FAILED;
4146    }
4147    // free $p5
4148    // free $p4
4149    $p4 = $this->currPos;
4150    // start seq_2
4151    $p5 = $this->currPos;
4152    if (!(/*no_rbrace*/($boolParams & 0x1) !== 0)) {
4153      $r8 = false;
4154    } else {
4155      $r8 = self::$FAILED;
4156      $r3 = self::$FAILED;
4157      goto seq_2;
4158    }
4159    $r9 = self::$FAILED;
4160    for (;;) {
4161      if (strcspn($this->input, "'\"\\`\$ \x09\x0b\x0d\x0c\x0a&|;<>()", $this->currPos, 1) !== 0) {
4162        $r10 = self::consumeChar($this->input, $this->currPos);
4163        $r9 = true;
4164      } else {
4165        $r10 = self::$FAILED;
4166        if (!$silence) {$this->fail(37);}
4167        break;
4168      }
4169    }
4170    if ($r9===self::$FAILED) {
4171      $this->currPos = $p5;
4172      $r3 = self::$FAILED;
4173      goto seq_2;
4174    }
4175    // free $r10
4176    $r3 = true;
4177    seq_2:
4178    if ($r3!==self::$FAILED) {
4179      $r3 = substr($this->input, $p4, $this->currPos - $p4);
4180    } else {
4181      $r3 = self::$FAILED;
4182    }
4183    // free $p5
4184    // free $p4
4185    choice_1:
4186    // plain <- $r3
4187    $r1 = $r3;
4188    if ($r1!==self::$FAILED) {
4189      $this->savedPos = $p2;
4190      $r1 = $this->a55($r3);
4191    }
4192    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
4193
4194    $this->cache[$key] = $cached;
4195    return $r1;
4196  }
4197  private function discardElse($silence) {
4198    $key = json_encode([317, $this->currPos]);
4199    $cached = $this->cache[$key] ?? null;
4200      if ($cached) {
4201        $this->currPos = $cached['nextPos'];
4202
4203        return $cached['result'];
4204      }
4205
4206    // start seq_1
4207    $p1 = $this->currPos;
4208    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "else", $this->currPos, 4, false) === 0) {
4209      $r3 = "else";
4210      $this->currPos += 4;
4211    } else {
4212      if (!$silence) {$this->fail(38);}
4213      $r3 = self::$FAILED;
4214      $r2 = self::$FAILED;
4215      goto seq_1;
4216    }
4217    $r4 = $this->discardDELIM($silence);
4218    if ($r4===self::$FAILED) {
4219      $this->currPos = $p1;
4220      $r2 = self::$FAILED;
4221      goto seq_1;
4222    }
4223    $r2 = true;
4224    seq_1:
4225    // free $r2,$p1
4226    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4227
4228    $this->cache[$key] = $cached;
4229    return $r2;
4230  }
4231  private function discardElif($silence) {
4232    $key = json_encode([319, $this->currPos]);
4233    $cached = $this->cache[$key] ?? null;
4234      if ($cached) {
4235        $this->currPos = $cached['nextPos'];
4236
4237        return $cached['result'];
4238      }
4239
4240    // start seq_1
4241    $p1 = $this->currPos;
4242    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "elif", $this->currPos, 4, false) === 0) {
4243      $r3 = "elif";
4244      $this->currPos += 4;
4245    } else {
4246      if (!$silence) {$this->fail(39);}
4247      $r3 = self::$FAILED;
4248      $r2 = self::$FAILED;
4249      goto seq_1;
4250    }
4251    $r4 = $this->discardDELIM($silence);
4252    if ($r4===self::$FAILED) {
4253      $this->currPos = $p1;
4254      $r2 = self::$FAILED;
4255      goto seq_1;
4256    }
4257    $r2 = true;
4258    seq_1:
4259    // free $r2,$p1
4260    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4261
4262    $this->cache[$key] = $cached;
4263    return $r2;
4264  }
4265  private function discardDo($silence) {
4266    $key = json_encode([323, $this->currPos]);
4267    $cached = $this->cache[$key] ?? null;
4268      if ($cached) {
4269        $this->currPos = $cached['nextPos'];
4270
4271        return $cached['result'];
4272      }
4273
4274    // start seq_1
4275    $p1 = $this->currPos;
4276    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "do", $this->currPos, 2, false) === 0) {
4277      $r3 = "do";
4278      $this->currPos += 2;
4279    } else {
4280      if (!$silence) {$this->fail(40);}
4281      $r3 = self::$FAILED;
4282      $r2 = self::$FAILED;
4283      goto seq_1;
4284    }
4285    $r4 = $this->discardDELIM($silence);
4286    if ($r4===self::$FAILED) {
4287      $this->currPos = $p1;
4288      $r2 = self::$FAILED;
4289      goto seq_1;
4290    }
4291    $r2 = true;
4292    seq_1:
4293    // free $r2,$p1
4294    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4295
4296    $this->cache[$key] = $cached;
4297    return $r2;
4298  }
4299  private function discardDone($silence) {
4300    $key = json_encode([325, $this->currPos]);
4301    $cached = $this->cache[$key] ?? null;
4302      if ($cached) {
4303        $this->currPos = $cached['nextPos'];
4304
4305        return $cached['result'];
4306      }
4307
4308    // start seq_1
4309    $p1 = $this->currPos;
4310    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "done", $this->currPos, 4, false) === 0) {
4311      $r3 = "done";
4312      $this->currPos += 4;
4313    } else {
4314      if (!$silence) {$this->fail(41);}
4315      $r3 = self::$FAILED;
4316      $r2 = self::$FAILED;
4317      goto seq_1;
4318    }
4319    $r4 = $this->discardDELIM($silence);
4320    if ($r4===self::$FAILED) {
4321      $this->currPos = $p1;
4322      $r2 = self::$FAILED;
4323      goto seq_1;
4324    }
4325    $r2 = true;
4326    seq_1:
4327    // free $r2,$p1
4328    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4329
4330    $this->cache[$key] = $cached;
4331    return $r2;
4332  }
4333  private function discardBang($silence) {
4334    $key = json_encode([341, $this->currPos]);
4335    $cached = $this->cache[$key] ?? null;
4336      if ($cached) {
4337        $this->currPos = $cached['nextPos'];
4338
4339        return $cached['result'];
4340      }
4341
4342    // start seq_1
4343    $p1 = $this->currPos;
4344    if (($this->input[$this->currPos] ?? null) === "!") {
4345      $this->currPos++;
4346      $r3 = "!";
4347    } else {
4348      if (!$silence) {$this->fail(9);}
4349      $r3 = self::$FAILED;
4350      $r2 = self::$FAILED;
4351      goto seq_1;
4352    }
4353    $r4 = $this->discardDELIM($silence);
4354    if ($r4===self::$FAILED) {
4355      $this->currPos = $p1;
4356      $r2 = self::$FAILED;
4357      goto seq_1;
4358    }
4359    $r2 = true;
4360    seq_1:
4361    // free $r2,$p1
4362    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4363
4364    $this->cache[$key] = $cached;
4365    return $r2;
4366  }
4367  private function discardIn($silence) {
4368    $key = json_encode([343, $this->currPos]);
4369    $cached = $this->cache[$key] ?? null;
4370      if ($cached) {
4371        $this->currPos = $cached['nextPos'];
4372
4373        return $cached['result'];
4374      }
4375
4376    // start seq_1
4377    $p1 = $this->currPos;
4378    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "in", $this->currPos, 2, false) === 0) {
4379      $r3 = "in";
4380      $this->currPos += 2;
4381    } else {
4382      if (!$silence) {$this->fail(42);}
4383      $r3 = self::$FAILED;
4384      $r2 = self::$FAILED;
4385      goto seq_1;
4386    }
4387    $r4 = $this->discardDELIM($silence);
4388    if ($r4===self::$FAILED) {
4389      $this->currPos = $p1;
4390      $r2 = self::$FAILED;
4391      goto seq_1;
4392    }
4393    $r2 = true;
4394    seq_1:
4395    // free $r2,$p1
4396    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4397
4398    $this->cache[$key] = $cached;
4399    return $r2;
4400  }
4401  private function discardDELIM($silence) {
4402    $key = json_encode([363, $this->currPos]);
4403    $cached = $this->cache[$key] ?? null;
4404      if ($cached) {
4405        $this->currPos = $cached['nextPos'];
4406
4407        return $cached['result'];
4408      }
4409
4410    // start choice_1
4411    $r1 = self::$FAILED;
4412    for (;;) {
4413      if (strspn($this->input, " \x09\x0b\x0d\x0c", $this->currPos, 1) !== 0) {
4414        $r2 = $this->input[$this->currPos++];
4415        $r1 = true;
4416      } else {
4417        $r2 = self::$FAILED;
4418        if (!$silence) {$this->fail(2);}
4419        break;
4420      }
4421    }
4422    if ($r1!==self::$FAILED) {
4423      goto choice_1;
4424    }
4425    // free $r2
4426    $p3 = $this->currPos;
4427    if ($this->currPos < $this->inputLength) {
4428      $r1 = self::consumeChar($this->input, $this->currPos);;
4429    } else {
4430      $r1 = self::$FAILED;
4431    }
4432    if ($r1 === self::$FAILED) {
4433      $r1 = false;
4434      goto choice_1;
4435    } else {
4436      $r1 = self::$FAILED;
4437      $this->currPos = $p3;
4438    }
4439    // free $p3
4440    $p3 = $this->currPos;
4441    if (($this->input[$this->currPos] ?? null) === "\x0a") {
4442      $this->currPos++;
4443      $r1 = "\x0a";
4444      $r1 = false;
4445      $this->currPos = $p3;
4446    } else {
4447      $r1 = self::$FAILED;
4448    }
4449    // free $p3
4450    choice_1:
4451    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
4452
4453    $this->cache[$key] = $cached;
4454    return $r1;
4455  }
4456  private function discardseparator($silence) {
4457    $key = json_encode([289, $this->currPos]);
4458    $cached = $this->cache[$key] ?? null;
4459      if ($cached) {
4460        $this->currPos = $cached['nextPos'];
4461
4462        return $cached['result'];
4463      }
4464
4465    // start choice_1
4466    // start seq_1
4467    $p2 = $this->currPos;
4468    $r3 = $this->discardseparator_op($silence);
4469    if ($r3===self::$FAILED) {
4470      $r1 = self::$FAILED;
4471      goto seq_1;
4472    }
4473    $r4 = $this->discardlinebreak($silence);
4474    if ($r4===self::$FAILED) {
4475      $this->currPos = $p2;
4476      $r1 = self::$FAILED;
4477      goto seq_1;
4478    }
4479    $r1 = true;
4480    seq_1:
4481    if ($r1!==self::$FAILED) {
4482      goto choice_1;
4483    }
4484    // free $p2
4485    $r1 = $this->discardnewline_list($silence);
4486    choice_1:
4487    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
4488
4489    $this->cache[$key] = $cached;
4490    return $r1;
4491  }
4492  private function parsecase_item($silence, $boolParams) {
4493    $key = json_encode([244, $this->currPos, $boolParams & 0x1]);
4494    $cached = $this->cache[$key] ?? null;
4495      if ($cached) {
4496        $this->currPos = $cached['nextPos'];
4497
4498        return $cached['result'];
4499      }
4500
4501    // start choice_1
4502    $p2 = $this->currPos;
4503    // start seq_1
4504    $p3 = $this->currPos;
4505    $r4 = $this->discardLPAREN($silence);
4506    if ($r4===self::$FAILED) {
4507      $r4 = null;
4508    }
4509    $r5 = $this->parsepattern($silence, $boolParams);
4510    // pattern <- $r5
4511    if ($r5===self::$FAILED) {
4512      $this->currPos = $p3;
4513      $r1 = self::$FAILED;
4514      goto seq_1;
4515    }
4516    $r6 = $this->discardRPAREN($silence);
4517    if ($r6===self::$FAILED) {
4518      $this->currPos = $p3;
4519      $r1 = self::$FAILED;
4520      goto seq_1;
4521    }
4522    $r7 = $this->parsecompound_list($silence);
4523    // list <- $r7
4524    if ($r7===self::$FAILED) {
4525      $this->currPos = $p3;
4526      $r1 = self::$FAILED;
4527      goto seq_1;
4528    }
4529    $r8 = $this->discardDSEMI($silence);
4530    if ($r8===self::$FAILED) {
4531      $this->currPos = $p3;
4532      $r1 = self::$FAILED;
4533      goto seq_1;
4534    }
4535    $r9 = $this->discardlinebreak($silence);
4536    if ($r9===self::$FAILED) {
4537      $this->currPos = $p3;
4538      $r1 = self::$FAILED;
4539      goto seq_1;
4540    }
4541    $r1 = true;
4542    seq_1:
4543    if ($r1!==self::$FAILED) {
4544      $this->savedPos = $p2;
4545      $r1 = $this->a56($r5, $r7);
4546      goto choice_1;
4547    }
4548    // free $p3
4549    $p3 = $this->currPos;
4550    // start seq_2
4551    $p10 = $this->currPos;
4552    $r11 = $this->discardLPAREN($silence);
4553    if ($r11===self::$FAILED) {
4554      $r11 = null;
4555    }
4556    $r12 = $this->parsepattern($silence, $boolParams);
4557    // pattern <- $r12
4558    if ($r12===self::$FAILED) {
4559      $this->currPos = $p10;
4560      $r1 = self::$FAILED;
4561      goto seq_2;
4562    }
4563    $r13 = $this->discardRPAREN($silence);
4564    if ($r13===self::$FAILED) {
4565      $this->currPos = $p10;
4566      $r1 = self::$FAILED;
4567      goto seq_2;
4568    }
4569    $r14 = $this->discardlinebreak($silence);
4570    if ($r14===self::$FAILED) {
4571      $this->currPos = $p10;
4572      $r1 = self::$FAILED;
4573      goto seq_2;
4574    }
4575    $r15 = $this->discardDSEMI($silence);
4576    if ($r15===self::$FAILED) {
4577      $this->currPos = $p10;
4578      $r1 = self::$FAILED;
4579      goto seq_2;
4580    }
4581    $r16 = $this->discardlinebreak($silence);
4582    if ($r16===self::$FAILED) {
4583      $this->currPos = $p10;
4584      $r1 = self::$FAILED;
4585      goto seq_2;
4586    }
4587    $r1 = true;
4588    seq_2:
4589    if ($r1!==self::$FAILED) {
4590      $this->savedPos = $p3;
4591      $r1 = $this->a57($r12);
4592    }
4593    // free $p10
4594    choice_1:
4595    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
4596
4597    $this->cache[$key] = $cached;
4598    return $r1;
4599  }
4600  private function parsecase_item_ns($silence, $boolParams) {
4601    $key = json_encode([242, $this->currPos, $boolParams & 0x1]);
4602    $cached = $this->cache[$key] ?? null;
4603      if ($cached) {
4604        $this->currPos = $cached['nextPos'];
4605
4606        return $cached['result'];
4607      }
4608
4609    // start choice_1
4610    $p2 = $this->currPos;
4611    // start seq_1
4612    $p3 = $this->currPos;
4613    $r4 = $this->discardLPAREN($silence);
4614    if ($r4===self::$FAILED) {
4615      $r4 = null;
4616    }
4617    $r5 = $this->parsepattern($silence, $boolParams);
4618    // pattern <- $r5
4619    if ($r5===self::$FAILED) {
4620      $this->currPos = $p3;
4621      $r1 = self::$FAILED;
4622      goto seq_1;
4623    }
4624    $r6 = $this->discardRPAREN($silence);
4625    if ($r6===self::$FAILED) {
4626      $this->currPos = $p3;
4627      $r1 = self::$FAILED;
4628      goto seq_1;
4629    }
4630    $r7 = $this->parsecompound_list($silence);
4631    // list <- $r7
4632    if ($r7===self::$FAILED) {
4633      $this->currPos = $p3;
4634      $r1 = self::$FAILED;
4635      goto seq_1;
4636    }
4637    $r1 = true;
4638    seq_1:
4639    if ($r1!==self::$FAILED) {
4640      $this->savedPos = $p2;
4641      $r1 = $this->a56($r5, $r7);
4642      goto choice_1;
4643    }
4644    // free $p3
4645    $p3 = $this->currPos;
4646    // start seq_2
4647    $p8 = $this->currPos;
4648    $r9 = $this->discardLPAREN($silence);
4649    if ($r9===self::$FAILED) {
4650      $r9 = null;
4651    }
4652    $r10 = $this->parsepattern($silence, $boolParams);
4653    // pattern <- $r10
4654    if ($r10===self::$FAILED) {
4655      $this->currPos = $p8;
4656      $r1 = self::$FAILED;
4657      goto seq_2;
4658    }
4659    $r11 = $this->discardRPAREN($silence);
4660    if ($r11===self::$FAILED) {
4661      $this->currPos = $p8;
4662      $r1 = self::$FAILED;
4663      goto seq_2;
4664    }
4665    $r12 = $this->discardlinebreak($silence);
4666    if ($r12===self::$FAILED) {
4667      $this->currPos = $p8;
4668      $r1 = self::$FAILED;
4669      goto seq_2;
4670    }
4671    $r1 = true;
4672    seq_2:
4673    if ($r1!==self::$FAILED) {
4674      $this->savedPos = $p3;
4675      $r1 = $this->a58($r10);
4676    }
4677    // free $p8
4678    choice_1:
4679    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
4680
4681    $this->cache[$key] = $cached;
4682    return $r1;
4683  }
4684  private function discardLESSAND($silence) {
4685    $key = json_encode([303, $this->currPos]);
4686    $cached = $this->cache[$key] ?? null;
4687      if ($cached) {
4688        $this->currPos = $cached['nextPos'];
4689
4690        return $cached['result'];
4691      }
4692
4693    // start seq_1
4694    $p1 = $this->currPos;
4695    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "<&", $this->currPos, 2, false) === 0) {
4696      $r3 = "<&";
4697      $this->currPos += 2;
4698    } else {
4699      if (!$silence) {$this->fail(43);}
4700      $r3 = self::$FAILED;
4701      $r2 = self::$FAILED;
4702      goto seq_1;
4703    }
4704    $r4 = $this->discardOWS($silence);
4705    if ($r4===self::$FAILED) {
4706      $this->currPos = $p1;
4707      $r2 = self::$FAILED;
4708      goto seq_1;
4709    }
4710    $r2 = true;
4711    seq_1:
4712    // free $r2,$p1
4713    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4714
4715    $this->cache[$key] = $cached;
4716    return $r2;
4717  }
4718  private function discardLESSGREAT($silence) {
4719    $key = json_encode([307, $this->currPos]);
4720    $cached = $this->cache[$key] ?? null;
4721      if ($cached) {
4722        $this->currPos = $cached['nextPos'];
4723
4724        return $cached['result'];
4725      }
4726
4727    // start seq_1
4728    $p1 = $this->currPos;
4729    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "<>", $this->currPos, 2, false) === 0) {
4730      $r3 = "<>";
4731      $this->currPos += 2;
4732    } else {
4733      if (!$silence) {$this->fail(44);}
4734      $r3 = self::$FAILED;
4735      $r2 = self::$FAILED;
4736      goto seq_1;
4737    }
4738    $r4 = $this->discardOWS($silence);
4739    if ($r4===self::$FAILED) {
4740      $this->currPos = $p1;
4741      $r2 = self::$FAILED;
4742      goto seq_1;
4743    }
4744    $r2 = true;
4745    seq_1:
4746    // free $r2,$p1
4747    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4748
4749    $this->cache[$key] = $cached;
4750    return $r2;
4751  }
4752  private function discardLESS($silence) {
4753    $key = json_encode([351, $this->currPos]);
4754    $cached = $this->cache[$key] ?? null;
4755      if ($cached) {
4756        $this->currPos = $cached['nextPos'];
4757
4758        return $cached['result'];
4759      }
4760
4761    // start seq_1
4762    $p1 = $this->currPos;
4763    $p3 = $this->currPos;
4764    $r4 = $this->discardDLESS(true);
4765    if ($r4 === self::$FAILED) {
4766      $r4 = false;
4767    } else {
4768      $r4 = self::$FAILED;
4769      $this->currPos = $p3;
4770      $r2 = self::$FAILED;
4771      goto seq_1;
4772    }
4773    // free $p3
4774    $p3 = $this->currPos;
4775    $r5 = $this->discardLESSAND(true);
4776    if ($r5 === self::$FAILED) {
4777      $r5 = false;
4778    } else {
4779      $r5 = self::$FAILED;
4780      $this->currPos = $p3;
4781      $this->currPos = $p1;
4782      $r2 = self::$FAILED;
4783      goto seq_1;
4784    }
4785    // free $p3
4786    $p3 = $this->currPos;
4787    $r6 = $this->discardLESSGREAT(true);
4788    if ($r6 === self::$FAILED) {
4789      $r6 = false;
4790    } else {
4791      $r6 = self::$FAILED;
4792      $this->currPos = $p3;
4793      $this->currPos = $p1;
4794      $r2 = self::$FAILED;
4795      goto seq_1;
4796    }
4797    // free $p3
4798    $p3 = $this->currPos;
4799    $r7 = $this->discardDLESSDASH(true);
4800    if ($r7 === self::$FAILED) {
4801      $r7 = false;
4802    } else {
4803      $r7 = self::$FAILED;
4804      $this->currPos = $p3;
4805      $this->currPos = $p1;
4806      $r2 = self::$FAILED;
4807      goto seq_1;
4808    }
4809    // free $p3
4810    if (($this->input[$this->currPos] ?? null) === "<") {
4811      $this->currPos++;
4812      $r8 = "<";
4813    } else {
4814      if (!$silence) {$this->fail(45);}
4815      $r8 = self::$FAILED;
4816      $this->currPos = $p1;
4817      $r2 = self::$FAILED;
4818      goto seq_1;
4819    }
4820    $r9 = $this->discardOWS($silence);
4821    if ($r9===self::$FAILED) {
4822      $this->currPos = $p1;
4823      $r2 = self::$FAILED;
4824      goto seq_1;
4825    }
4826    $r2 = true;
4827    seq_1:
4828    // free $r2,$p1
4829    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4830
4831    $this->cache[$key] = $cached;
4832    return $r2;
4833  }
4834  private function discardGREATAND($silence) {
4835    $key = json_encode([305, $this->currPos]);
4836    $cached = $this->cache[$key] ?? null;
4837      if ($cached) {
4838        $this->currPos = $cached['nextPos'];
4839
4840        return $cached['result'];
4841      }
4842
4843    // start seq_1
4844    $p1 = $this->currPos;
4845    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, ">&", $this->currPos, 2, false) === 0) {
4846      $r3 = ">&";
4847      $this->currPos += 2;
4848    } else {
4849      if (!$silence) {$this->fail(46);}
4850      $r3 = self::$FAILED;
4851      $r2 = self::$FAILED;
4852      goto seq_1;
4853    }
4854    $r4 = $this->discardOWS($silence);
4855    if ($r4===self::$FAILED) {
4856      $this->currPos = $p1;
4857      $r2 = self::$FAILED;
4858      goto seq_1;
4859    }
4860    $r2 = true;
4861    seq_1:
4862    // free $r2,$p1
4863    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4864
4865    $this->cache[$key] = $cached;
4866    return $r2;
4867  }
4868  private function discardDGREAT($silence) {
4869    $key = json_encode([301, $this->currPos]);
4870    $cached = $this->cache[$key] ?? null;
4871      if ($cached) {
4872        $this->currPos = $cached['nextPos'];
4873
4874        return $cached['result'];
4875      }
4876
4877    // start seq_1
4878    $p1 = $this->currPos;
4879    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, ">>", $this->currPos, 2, false) === 0) {
4880      $r3 = ">>";
4881      $this->currPos += 2;
4882    } else {
4883      if (!$silence) {$this->fail(47);}
4884      $r3 = self::$FAILED;
4885      $r2 = self::$FAILED;
4886      goto seq_1;
4887    }
4888    $r4 = $this->discardOWS($silence);
4889    if ($r4===self::$FAILED) {
4890      $this->currPos = $p1;
4891      $r2 = self::$FAILED;
4892      goto seq_1;
4893    }
4894    $r2 = true;
4895    seq_1:
4896    // free $r2,$p1
4897    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4898
4899    $this->cache[$key] = $cached;
4900    return $r2;
4901  }
4902  private function discardCLOBBER($silence) {
4903    $key = json_encode([311, $this->currPos]);
4904    $cached = $this->cache[$key] ?? null;
4905      if ($cached) {
4906        $this->currPos = $cached['nextPos'];
4907
4908        return $cached['result'];
4909      }
4910
4911    // start seq_1
4912    $p1 = $this->currPos;
4913    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, ">|", $this->currPos, 2, false) === 0) {
4914      $r3 = ">|";
4915      $this->currPos += 2;
4916    } else {
4917      if (!$silence) {$this->fail(48);}
4918      $r3 = self::$FAILED;
4919      $r2 = self::$FAILED;
4920      goto seq_1;
4921    }
4922    $r4 = $this->discardOWS($silence);
4923    if ($r4===self::$FAILED) {
4924      $this->currPos = $p1;
4925      $r2 = self::$FAILED;
4926      goto seq_1;
4927    }
4928    $r2 = true;
4929    seq_1:
4930    // free $r2,$p1
4931    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
4932
4933    $this->cache[$key] = $cached;
4934    return $r2;
4935  }
4936  private function discardGREAT($silence) {
4937    $key = json_encode([353, $this->currPos]);
4938    $cached = $this->cache[$key] ?? null;
4939      if ($cached) {
4940        $this->currPos = $cached['nextPos'];
4941
4942        return $cached['result'];
4943      }
4944
4945    // start seq_1
4946    $p1 = $this->currPos;
4947    $p3 = $this->currPos;
4948    $r4 = $this->discardDGREAT(true);
4949    if ($r4 === self::$FAILED) {
4950      $r4 = false;
4951    } else {
4952      $r4 = self::$FAILED;
4953      $this->currPos = $p3;
4954      $r2 = self::$FAILED;
4955      goto seq_1;
4956    }
4957    // free $p3
4958    $p3 = $this->currPos;
4959    $r5 = $this->discardGREATAND(true);
4960    if ($r5 === self::$FAILED) {
4961      $r5 = false;
4962    } else {
4963      $r5 = self::$FAILED;
4964      $this->currPos = $p3;
4965      $this->currPos = $p1;
4966      $r2 = self::$FAILED;
4967      goto seq_1;
4968    }
4969    // free $p3
4970    $p3 = $this->currPos;
4971    $r6 = $this->discardCLOBBER(true);
4972    if ($r6 === self::$FAILED) {
4973      $r6 = false;
4974    } else {
4975      $r6 = self::$FAILED;
4976      $this->currPos = $p3;
4977      $this->currPos = $p1;
4978      $r2 = self::$FAILED;
4979      goto seq_1;
4980    }
4981    // free $p3
4982    if (($this->input[$this->currPos] ?? null) === ">") {
4983      $this->currPos++;
4984      $r7 = ">";
4985    } else {
4986      if (!$silence) {$this->fail(49);}
4987      $r7 = self::$FAILED;
4988      $this->currPos = $p1;
4989      $r2 = self::$FAILED;
4990      goto seq_1;
4991    }
4992    $r8 = $this->discardOWS($silence);
4993    if ($r8===self::$FAILED) {
4994      $this->currPos = $p1;
4995      $r2 = self::$FAILED;
4996      goto seq_1;
4997    }
4998    $r2 = true;
4999    seq_1:
5000    // free $r2,$p1
5001    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
5002
5003    $this->cache[$key] = $cached;
5004    return $r2;
5005  }
5006  private function discardDLESSDASH($silence) {
5007    $key = json_encode([309, $this->currPos]);
5008    $cached = $this->cache[$key] ?? null;
5009      if ($cached) {
5010        $this->currPos = $cached['nextPos'];
5011
5012        return $cached['result'];
5013      }
5014
5015    // start seq_1
5016    $p1 = $this->currPos;
5017    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "<<-", $this->currPos, 3, false) === 0) {
5018      $r3 = "<<-";
5019      $this->currPos += 3;
5020    } else {
5021      if (!$silence) {$this->fail(50);}
5022      $r3 = self::$FAILED;
5023      $r2 = self::$FAILED;
5024      goto seq_1;
5025    }
5026    $r4 = $this->discardOWS($silence);
5027    if ($r4===self::$FAILED) {
5028      $this->currPos = $p1;
5029      $r2 = self::$FAILED;
5030      goto seq_1;
5031    }
5032    $r2 = true;
5033    seq_1:
5034    // free $r2,$p1
5035    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
5036
5037    $this->cache[$key] = $cached;
5038    return $r2;
5039  }
5040  private function discardDLESS($silence) {
5041    $key = json_encode([299, $this->currPos]);
5042    $cached = $this->cache[$key] ?? null;
5043      if ($cached) {
5044        $this->currPos = $cached['nextPos'];
5045
5046        return $cached['result'];
5047      }
5048
5049    // start seq_1
5050    $p1 = $this->currPos;
5051    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "<<", $this->currPos, 2, false) === 0) {
5052      $r3 = "<<";
5053      $this->currPos += 2;
5054    } else {
5055      if (!$silence) {$this->fail(51);}
5056      $r3 = self::$FAILED;
5057      $r2 = self::$FAILED;
5058      goto seq_1;
5059    }
5060    $r4 = $this->discardOWS($silence);
5061    if ($r4===self::$FAILED) {
5062      $this->currPos = $p1;
5063      $r2 = self::$FAILED;
5064      goto seq_1;
5065    }
5066    $r2 = true;
5067    seq_1:
5068    // free $r2,$p1
5069    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
5070
5071    $this->cache[$key] = $cached;
5072    return $r2;
5073  }
5074  private function parsehere_end($silence, $boolParams) {
5075    $key = json_encode([280, $this->currPos, $boolParams & 0x1]);
5076    $cached = $this->cache[$key] ?? null;
5077      if ($cached) {
5078        $this->currPos = $cached['nextPos'];
5079
5080        return $cached['result'];
5081      }
5082
5083    $p1 = $this->currPos;
5084    $r2 = $this->discardWORD($silence, $boolParams);
5085    if ($r2!==self::$FAILED) {
5086      $r2 = substr($this->input, $p1, $this->currPos - $p1);
5087    } else {
5088      $r2 = self::$FAILED;
5089    }
5090    // free $p1
5091    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
5092
5093    $this->cache[$key] = $cached;
5094    return $r2;
5095  }
5096  private function parsedquoted_escape($silence) {
5097    $key = json_encode([372, $this->currPos]);
5098    $cached = $this->cache[$key] ?? null;
5099      if ($cached) {
5100        $this->currPos = $cached['nextPos'];
5101
5102        return $cached['result'];
5103      }
5104
5105    $p2 = $this->currPos;
5106    // start seq_1
5107    $p3 = $this->currPos;
5108    if (($this->input[$this->currPos] ?? null) === "\\") {
5109      $this->currPos++;
5110      $r4 = "\\";
5111    } else {
5112      if (!$silence) {$this->fail(31);}
5113      $r4 = self::$FAILED;
5114      $r1 = self::$FAILED;
5115      goto seq_1;
5116    }
5117    // contents <- $r5
5118    if (strspn($this->input, "\$`\"\\\x0a", $this->currPos, 1) !== 0) {
5119      $r5 = $this->input[$this->currPos++];
5120    } else {
5121      $r5 = self::$FAILED;
5122      if (!$silence) {$this->fail(52);}
5123      $this->currPos = $p3;
5124      $r1 = self::$FAILED;
5125      goto seq_1;
5126    }
5127    $r1 = true;
5128    seq_1:
5129    if ($r1!==self::$FAILED) {
5130      $this->savedPos = $p2;
5131      $r1 = $this->a59($r5);
5132    }
5133    // free $p3
5134    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5135
5136    $this->cache[$key] = $cached;
5137    return $r1;
5138  }
5139  private function parsebackquoted_escape($silence) {
5140    $key = json_encode([378, $this->currPos]);
5141    $cached = $this->cache[$key] ?? null;
5142      if ($cached) {
5143        $this->currPos = $cached['nextPos'];
5144
5145        return $cached['result'];
5146      }
5147
5148    $p2 = $this->currPos;
5149    // start seq_1
5150    $p3 = $this->currPos;
5151    if (($this->input[$this->currPos] ?? null) === "\\") {
5152      $this->currPos++;
5153      $r4 = "\\";
5154    } else {
5155      if (!$silence) {$this->fail(31);}
5156      $r4 = self::$FAILED;
5157      $r1 = self::$FAILED;
5158      goto seq_1;
5159    }
5160    $r5 = $this->input[$this->currPos] ?? '';
5161    // contents <- $r5
5162    if ($r5 === "\$" || $r5 === "\\") {
5163      $this->currPos++;
5164    } else {
5165      $r5 = self::$FAILED;
5166      if (!$silence) {$this->fail(53);}
5167      $this->currPos = $p3;
5168      $r1 = self::$FAILED;
5169      goto seq_1;
5170    }
5171    $r1 = true;
5172    seq_1:
5173    if ($r1!==self::$FAILED) {
5174      $this->savedPos = $p2;
5175      $r1 = $this->a60($r5);
5176    }
5177    // free $p3
5178    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5179
5180    $this->cache[$key] = $cached;
5181    return $r1;
5182  }
5183  private function parsedouble_backquote_expansion($silence) {
5184    $key = json_encode([380, $this->currPos]);
5185    $cached = $this->cache[$key] ?? null;
5186      if ($cached) {
5187        $this->currPos = $cached['nextPos'];
5188
5189        return $cached['result'];
5190      }
5191
5192    $p2 = $this->currPos;
5193    // start seq_1
5194    $p3 = $this->currPos;
5195    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "\\`", $this->currPos, 2, false) === 0) {
5196      $r4 = "\\`";
5197      $this->currPos += 2;
5198    } else {
5199      if (!$silence) {$this->fail(54);}
5200      $r4 = self::$FAILED;
5201      $r1 = self::$FAILED;
5202      goto seq_1;
5203    }
5204    // start choice_1
5205    $r5 = $this->parsebackquoted_escape($silence);
5206    if ($r5!==self::$FAILED) {
5207      goto choice_1;
5208    }
5209    $r5 = $this->parsedollar_expansion($silence);
5210    if ($r5!==self::$FAILED) {
5211      goto choice_1;
5212    }
5213    if (($this->input[$this->currPos] ?? null) === "\$") {
5214      $this->currPos++;
5215      $r5 = "\$";
5216      goto choice_1;
5217    } else {
5218      if (!$silence) {$this->fail(34);}
5219      $r5 = self::$FAILED;
5220    }
5221    // start seq_2
5222    $p6 = $this->currPos;
5223    if (($this->input[$this->currPos] ?? null) === "\\") {
5224      $this->currPos++;
5225      $r7 = "\\";
5226    } else {
5227      if (!$silence) {$this->fail(31);}
5228      $r7 = self::$FAILED;
5229      $r5 = self::$FAILED;
5230      goto seq_2;
5231    }
5232    $p8 = $this->currPos;
5233    if (($this->input[$this->currPos] ?? null) === "`") {
5234      $this->currPos++;
5235      $r9 = "`";
5236    } else {
5237      $r9 = self::$FAILED;
5238    }
5239    if ($r9 === self::$FAILED) {
5240      $r9 = false;
5241    } else {
5242      $r9 = self::$FAILED;
5243      $this->currPos = $p8;
5244      $this->currPos = $p6;
5245      $r5 = self::$FAILED;
5246      goto seq_2;
5247    }
5248    // free $p8
5249    $r5 = [$r7,$r9];
5250    seq_2:
5251    if ($r5!==self::$FAILED) {
5252      goto choice_1;
5253    }
5254    // free $p6
5255    $p6 = $this->currPos;
5256    $r5 = self::$FAILED;
5257    for (;;) {
5258      if (strcspn($this->input, "`\$\\", $this->currPos, 1) !== 0) {
5259        $r10 = self::consumeChar($this->input, $this->currPos);
5260        $r5 = true;
5261      } else {
5262        $r10 = self::$FAILED;
5263        if (!$silence) {$this->fail(35);}
5264        break;
5265      }
5266    }
5267    if ($r5!==self::$FAILED) {
5268      $r5 = substr($this->input, $p6, $this->currPos - $p6);
5269    } else {
5270      $r5 = self::$FAILED;
5271    }
5272    // free $r10
5273    // free $p6
5274    choice_1:
5275    // parts <- $r5
5276    if ($r5===self::$FAILED) {
5277      $this->currPos = $p3;
5278      $r1 = self::$FAILED;
5279      goto seq_1;
5280    }
5281    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "\\`", $this->currPos, 2, false) === 0) {
5282      $r10 = "\\`";
5283      $this->currPos += 2;
5284    } else {
5285      if (!$silence) {$this->fail(54);}
5286      $r10 = self::$FAILED;
5287      $this->currPos = $p3;
5288      $r1 = self::$FAILED;
5289      goto seq_1;
5290    }
5291    $r1 = true;
5292    seq_1:
5293    if ($r1!==self::$FAILED) {
5294      $this->savedPos = $p2;
5295      $r1 = $this->a61($r5);
5296    }
5297    // free $p3
5298    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5299
5300    $this->cache[$key] = $cached;
5301    return $r1;
5302  }
5303  private function parsespecial_parameter($silence) {
5304    $key = json_encode([384, $this->currPos]);
5305    $cached = $this->cache[$key] ?? null;
5306      if ($cached) {
5307        $this->currPos = $cached['nextPos'];
5308
5309        return $cached['result'];
5310      }
5311
5312    $p2 = $this->currPos;
5313    // contents <- $r3
5314    if (strspn($this->input, "@*#?-\$!0", $this->currPos, 1) !== 0) {
5315      $r3 = $this->input[$this->currPos++];
5316    } else {
5317      $r3 = self::$FAILED;
5318      if (!$silence) {$this->fail(55);}
5319    }
5320    $r1 = $r3;
5321    if ($r1!==self::$FAILED) {
5322      $this->savedPos = $p2;
5323      $r1 = $this->a62($r3);
5324    }
5325    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5326
5327    $this->cache[$key] = $cached;
5328    return $r1;
5329  }
5330  private function parseshort_positional_parameter($silence) {
5331    $key = json_encode([386, $this->currPos]);
5332    $cached = $this->cache[$key] ?? null;
5333      if ($cached) {
5334        $this->currPos = $cached['nextPos'];
5335
5336        return $cached['result'];
5337      }
5338
5339    $p2 = $this->currPos;
5340    $r3 = $this->input[$this->currPos] ?? '';
5341    // contents <- $r3
5342    if (preg_match("/^[1-9]/", $r3)) {
5343      $this->currPos++;
5344    } else {
5345      $r3 = self::$FAILED;
5346      if (!$silence) {$this->fail(56);}
5347    }
5348    $r1 = $r3;
5349    if ($r1!==self::$FAILED) {
5350      $this->savedPos = $p2;
5351      $r1 = $this->a63($r3);
5352    }
5353    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5354
5355    $this->cache[$key] = $cached;
5356    return $r1;
5357  }
5358  private function parsebrace_expansion($silence) {
5359    $key = json_encode([388, $this->currPos]);
5360    $cached = $this->cache[$key] ?? null;
5361      if ($cached) {
5362        $this->currPos = $cached['nextPos'];
5363
5364        return $cached['result'];
5365      }
5366
5367    $p2 = $this->currPos;
5368    // start seq_1
5369    $p3 = $this->currPos;
5370    if (($this->input[$this->currPos] ?? null) === "{") {
5371      $this->currPos++;
5372      $r4 = "{";
5373    } else {
5374      if (!$silence) {$this->fail(17);}
5375      $r4 = self::$FAILED;
5376      $r1 = self::$FAILED;
5377      goto seq_1;
5378    }
5379    // start choice_1
5380    $r5 = $this->parsebinary_expansion($silence);
5381    if ($r5!==self::$FAILED) {
5382      goto choice_1;
5383    }
5384    $r5 = $this->parsestring_length($silence);
5385    if ($r5!==self::$FAILED) {
5386      goto choice_1;
5387    }
5388    $r5 = $this->parsebraced_parameter_expansion($silence);
5389    choice_1:
5390    // contents <- $r5
5391    if ($r5===self::$FAILED) {
5392      $this->currPos = $p3;
5393      $r1 = self::$FAILED;
5394      goto seq_1;
5395    }
5396    if (($this->input[$this->currPos] ?? null) === "}") {
5397      $this->currPos++;
5398      $r6 = "}";
5399    } else {
5400      if (!$silence) {$this->fail(18);}
5401      $r6 = self::$FAILED;
5402      $this->currPos = $p3;
5403      $r1 = self::$FAILED;
5404      goto seq_1;
5405    }
5406    $r1 = true;
5407    seq_1:
5408    if ($r1!==self::$FAILED) {
5409      $this->savedPos = $p2;
5410      $r1 = $this->a54($r5);
5411    }
5412    // free $p3
5413    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5414
5415    $this->cache[$key] = $cached;
5416    return $r1;
5417  }
5418  private function parsearithmetic_expansion($silence) {
5419    $key = json_encode([394, $this->currPos]);
5420    $cached = $this->cache[$key] ?? null;
5421      if ($cached) {
5422        $this->currPos = $cached['nextPos'];
5423
5424        return $cached['result'];
5425      }
5426
5427    $p2 = $this->currPos;
5428    // start seq_1
5429    $p3 = $this->currPos;
5430    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "((", $this->currPos, 2, false) === 0) {
5431      $r4 = "((";
5432      $this->currPos += 2;
5433    } else {
5434      if (!$silence) {$this->fail(57);}
5435      $r4 = self::$FAILED;
5436      $r1 = self::$FAILED;
5437      goto seq_1;
5438    }
5439    $r5 = $this->discardOWS($silence);
5440    if ($r5===self::$FAILED) {
5441      $this->currPos = $p3;
5442      $r1 = self::$FAILED;
5443      goto seq_1;
5444    }
5445    $r6 = [];
5446    for (;;) {
5447      $r7 = $this->parseWORD($silence, 0x0);
5448      if ($r7!==self::$FAILED) {
5449        $r6[] = $r7;
5450      } else {
5451        break;
5452      }
5453    }
5454    if (count($r6) === 0) {
5455      $r6 = self::$FAILED;
5456    }
5457    // words <- $r6
5458    if ($r6===self::$FAILED) {
5459      $this->currPos = $p3;
5460      $r1 = self::$FAILED;
5461      goto seq_1;
5462    }
5463    // free $r7
5464    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "))", $this->currPos, 2, false) === 0) {
5465      $r7 = "))";
5466      $this->currPos += 2;
5467    } else {
5468      if (!$silence) {$this->fail(58);}
5469      $r7 = self::$FAILED;
5470      $this->currPos = $p3;
5471      $r1 = self::$FAILED;
5472      goto seq_1;
5473    }
5474    $r1 = true;
5475    seq_1:
5476    if ($r1!==self::$FAILED) {
5477      $this->savedPos = $p2;
5478      $r1 = $this->a64($r6);
5479    }
5480    // free $p3
5481    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5482
5483    $this->cache[$key] = $cached;
5484    return $r1;
5485  }
5486  private function parsecommand_expansion($silence) {
5487    $key = json_encode([396, $this->currPos]);
5488    $cached = $this->cache[$key] ?? null;
5489      if ($cached) {
5490        $this->currPos = $cached['nextPos'];
5491
5492        return $cached['result'];
5493      }
5494
5495    $p2 = $this->currPos;
5496    // start seq_1
5497    $p3 = $this->currPos;
5498    if (($this->input[$this->currPos] ?? null) === "(") {
5499      $this->currPos++;
5500      $r4 = "(";
5501    } else {
5502      if (!$silence) {$this->fail(14);}
5503      $r4 = self::$FAILED;
5504      $r1 = self::$FAILED;
5505      goto seq_1;
5506    }
5507    $r5 = $this->parsecomplete_command($silence, 0x0);
5508    // command <- $r5
5509    if ($r5===self::$FAILED) {
5510      $this->currPos = $p3;
5511      $r1 = self::$FAILED;
5512      goto seq_1;
5513    }
5514    if (($this->input[$this->currPos] ?? null) === ")") {
5515      $this->currPos++;
5516      $r6 = ")";
5517    } else {
5518      if (!$silence) {$this->fail(15);}
5519      $r6 = self::$FAILED;
5520      $this->currPos = $p3;
5521      $r1 = self::$FAILED;
5522      goto seq_1;
5523    }
5524    $r1 = true;
5525    seq_1:
5526    if ($r1!==self::$FAILED) {
5527      $this->savedPos = $p2;
5528      $r1 = $this->a65($r5);
5529    }
5530    // free $p3
5531    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5532
5533    $this->cache[$key] = $cached;
5534    return $r1;
5535  }
5536  private function parsenamed_parameter($silence) {
5537    $key = json_encode([404, $this->currPos]);
5538    $cached = $this->cache[$key] ?? null;
5539      if ($cached) {
5540        $this->currPos = $cached['nextPos'];
5541
5542        return $cached['result'];
5543      }
5544
5545    $p2 = $this->currPos;
5546    $r3 = $this->parseNAME($silence);
5547    // name <- $r3
5548    $r1 = $r3;
5549    if ($r1!==self::$FAILED) {
5550      $this->savedPos = $p2;
5551      $r1 = $this->a66($r3);
5552    }
5553    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5554
5555    $this->cache[$key] = $cached;
5556    return $r1;
5557  }
5558  private function parsepattern($silence, $boolParams) {
5559    $key = json_encode([246, $this->currPos, $boolParams & 0x1]);
5560    $cached = $this->cache[$key] ?? null;
5561      if ($cached) {
5562        $this->currPos = $cached['nextPos'];
5563
5564        return $cached['result'];
5565      }
5566
5567    $p2 = $this->currPos;
5568    // start seq_1
5569    $p3 = $this->currPos;
5570    $r4 = $this->parseWORD($silence, $boolParams);
5571    // first <- $r4
5572    if ($r4===self::$FAILED) {
5573      $r1 = self::$FAILED;
5574      goto seq_1;
5575    }
5576    $r5 = [];
5577    for (;;) {
5578      // start seq_2
5579      $p7 = $this->currPos;
5580      $r8 = $this->parsePIPE($silence);
5581      if ($r8===self::$FAILED) {
5582        $r6 = self::$FAILED;
5583        goto seq_2;
5584      }
5585      $r9 = $this->parseWORD($silence, $boolParams);
5586      if ($r9===self::$FAILED) {
5587        $this->currPos = $p7;
5588        $r6 = self::$FAILED;
5589        goto seq_2;
5590      }
5591      $r6 = [$r8,$r9];
5592      seq_2:
5593      if ($r6!==self::$FAILED) {
5594        $r5[] = $r6;
5595      } else {
5596        break;
5597      }
5598      // free $p7
5599    }
5600    // rest <- $r5
5601    // free $r6
5602    $r1 = true;
5603    seq_1:
5604    if ($r1!==self::$FAILED) {
5605      $this->savedPos = $p2;
5606      $r1 = $this->a67($r4, $r5);
5607    }
5608    // free $p3
5609    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5610
5611    $this->cache[$key] = $cached;
5612    return $r1;
5613  }
5614  private function discardWORD($silence, $boolParams) {
5615    $key = json_encode([365, $this->currPos, $boolParams & 0x1]);
5616    $cached = $this->cache[$key] ?? null;
5617      if ($cached) {
5618        $this->currPos = $cached['nextPos'];
5619
5620        return $cached['result'];
5621      }
5622
5623    $p2 = $this->currPos;
5624    // start seq_1
5625    $p3 = $this->currPos;
5626    $r4 = [];
5627    for (;;) {
5628      $r5 = $this->parseword_part($silence, $boolParams);
5629      if ($r5!==self::$FAILED) {
5630        $r4[] = $r5;
5631      } else {
5632        break;
5633      }
5634    }
5635    if (count($r4) === 0) {
5636      $r4 = self::$FAILED;
5637    }
5638    // parts <- $r4
5639    if ($r4===self::$FAILED) {
5640      $r1 = self::$FAILED;
5641      goto seq_1;
5642    }
5643    // free $r5
5644    $r5 = $this->discardOWS($silence);
5645    if ($r5===self::$FAILED) {
5646      $this->currPos = $p3;
5647      $r1 = self::$FAILED;
5648      goto seq_1;
5649    }
5650    $r1 = true;
5651    seq_1:
5652    if ($r1!==self::$FAILED) {
5653      $this->savedPos = $p2;
5654      $r1 = $this->a19($r4);
5655    }
5656    // free $p3
5657    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5658
5659    $this->cache[$key] = $cached;
5660    return $r1;
5661  }
5662  private function parsebinary_expansion($silence) {
5663    $key = json_encode([390, $this->currPos]);
5664    $cached = $this->cache[$key] ?? null;
5665      if ($cached) {
5666        $this->currPos = $cached['nextPos'];
5667
5668        return $cached['result'];
5669      }
5670
5671    $p2 = $this->currPos;
5672    // start seq_1
5673    $p3 = $this->currPos;
5674    $r4 = $this->parseparameter($silence);
5675    // parameter <- $r4
5676    if ($r4===self::$FAILED) {
5677      $r1 = self::$FAILED;
5678      goto seq_1;
5679    }
5680    // start choice_1
5681    $p6 = $this->currPos;
5682    // start seq_2
5683    $p7 = $this->currPos;
5684    if (($this->input[$this->currPos] ?? null) === ":") {
5685      $this->currPos++;
5686      $r8 = ":";
5687    } else {
5688      if (!$silence) {$this->fail(59);}
5689      $r8 = self::$FAILED;
5690      $r5 = self::$FAILED;
5691      goto seq_2;
5692    }
5693    if (strspn($this->input, "-=?+", $this->currPos, 1) !== 0) {
5694      $r9 = $this->input[$this->currPos++];
5695    } else {
5696      $r9 = self::$FAILED;
5697      if (!$silence) {$this->fail(60);}
5698      $this->currPos = $p7;
5699      $r5 = self::$FAILED;
5700      goto seq_2;
5701    }
5702    $r5 = true;
5703    seq_2:
5704    if ($r5!==self::$FAILED) {
5705      $r5 = substr($this->input, $p6, $this->currPos - $p6);
5706      goto choice_1;
5707    } else {
5708      $r5 = self::$FAILED;
5709    }
5710    // free $p7
5711    // free $p6
5712    $p6 = $this->currPos;
5713    // start choice_2
5714    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "%%", $this->currPos, 2, false) === 0) {
5715      $r5 = "%%";
5716      $this->currPos += 2;
5717      goto choice_2;
5718    } else {
5719      if (!$silence) {$this->fail(61);}
5720      $r5 = self::$FAILED;
5721    }
5722    if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "##", $this->currPos, 2, false) === 0) {
5723      $r5 = "##";
5724      $this->currPos += 2;
5725      goto choice_2;
5726    } else {
5727      if (!$silence) {$this->fail(62);}
5728      $r5 = self::$FAILED;
5729    }
5730    if (strspn($this->input, "%#-=?+", $this->currPos, 1) !== 0) {
5731      $r5 = $this->input[$this->currPos++];
5732    } else {
5733      $r5 = self::$FAILED;
5734      if (!$silence) {$this->fail(63);}
5735    }
5736    choice_2:
5737    if ($r5!==self::$FAILED) {
5738      $r5 = substr($this->input, $p6, $this->currPos - $p6);
5739    } else {
5740      $r5 = self::$FAILED;
5741    }
5742    // free $p6
5743    choice_1:
5744    // operator <- $r5
5745    if ($r5===self::$FAILED) {
5746      $this->currPos = $p3;
5747      $r1 = self::$FAILED;
5748      goto seq_1;
5749    }
5750    $r10 = $this->discardOWS($silence);
5751    if ($r10===self::$FAILED) {
5752      $this->currPos = $p3;
5753      $r1 = self::$FAILED;
5754      goto seq_1;
5755    }
5756    $r11 = $this->parseWORD($silence, 0x1);
5757    if ($r11===self::$FAILED) {
5758      $r11 = null;
5759    }
5760    // word <- $r11
5761    $r1 = true;
5762    seq_1:
5763    if ($r1!==self::$FAILED) {
5764      $this->savedPos = $p2;
5765      $r1 = $this->a68($r4, $r5, $r11);
5766    }
5767    // free $p3
5768    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5769
5770    $this->cache[$key] = $cached;
5771    return $r1;
5772  }
5773  private function parsestring_length($silence) {
5774    $key = json_encode([392, $this->currPos]);
5775    $cached = $this->cache[$key] ?? null;
5776      if ($cached) {
5777        $this->currPos = $cached['nextPos'];
5778
5779        return $cached['result'];
5780      }
5781
5782    $p2 = $this->currPos;
5783    // start seq_1
5784    $p3 = $this->currPos;
5785    if (($this->input[$this->currPos] ?? null) === "#") {
5786      $this->currPos++;
5787      $r4 = "#";
5788    } else {
5789      if (!$silence) {$this->fail(3);}
5790      $r4 = self::$FAILED;
5791      $r1 = self::$FAILED;
5792      goto seq_1;
5793    }
5794    $r5 = $this->parseparameter($silence);
5795    // parameter <- $r5
5796    if ($r5===self::$FAILED) {
5797      $this->currPos = $p3;
5798      $r1 = self::$FAILED;
5799      goto seq_1;
5800    }
5801    $r1 = true;
5802    seq_1:
5803    if ($r1!==self::$FAILED) {
5804      $this->savedPos = $p2;
5805      $r1 = $this->a69($r5);
5806    }
5807    // free $p3
5808    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5809
5810    $this->cache[$key] = $cached;
5811    return $r1;
5812  }
5813  private function parsebraced_parameter_expansion($silence) {
5814    $key = json_encode([398, $this->currPos]);
5815    $cached = $this->cache[$key] ?? null;
5816      if ($cached) {
5817        $this->currPos = $cached['nextPos'];
5818
5819        return $cached['result'];
5820      }
5821
5822    $p2 = $this->currPos;
5823    $r3 = $this->parseparameter($silence);
5824    // parameter <- $r3
5825    $r1 = $r3;
5826    if ($r1!==self::$FAILED) {
5827      $this->savedPos = $p2;
5828      $r1 = $this->a70($r3);
5829    }
5830    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5831
5832    $this->cache[$key] = $cached;
5833    return $r1;
5834  }
5835  private function parsePIPE($silence) {
5836    $key = json_encode([354, $this->currPos]);
5837    $cached = $this->cache[$key] ?? null;
5838      if ($cached) {
5839        $this->currPos = $cached['nextPos'];
5840
5841        return $cached['result'];
5842      }
5843
5844    // start seq_1
5845    $p1 = $this->currPos;
5846    $p3 = $this->currPos;
5847    $r4 = $this->discardOR_IF(true);
5848    if ($r4 === self::$FAILED) {
5849      $r4 = false;
5850    } else {
5851      $r4 = self::$FAILED;
5852      $this->currPos = $p3;
5853      $r2 = self::$FAILED;
5854      goto seq_1;
5855    }
5856    // free $p3
5857    if (($this->input[$this->currPos] ?? null) === "|") {
5858      $this->currPos++;
5859      $r5 = "|";
5860    } else {
5861      if (!$silence) {$this->fail(11);}
5862      $r5 = self::$FAILED;
5863      $this->currPos = $p1;
5864      $r2 = self::$FAILED;
5865      goto seq_1;
5866    }
5867    $r6 = $this->parseOWS($silence);
5868    if ($r6===self::$FAILED) {
5869      $this->currPos = $p1;
5870      $r2 = self::$FAILED;
5871      goto seq_1;
5872    }
5873    $r2 = [$r4,$r5,$r6];
5874    seq_1:
5875    // free $r2,$p1
5876    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
5877
5878    $this->cache[$key] = $cached;
5879    return $r2;
5880  }
5881  private function parseparameter($silence) {
5882    $key = json_encode([400, $this->currPos]);
5883    $cached = $this->cache[$key] ?? null;
5884      if ($cached) {
5885        $this->currPos = $cached['nextPos'];
5886
5887        return $cached['result'];
5888      }
5889
5890    // start choice_1
5891    $r1 = $this->parsespecial_parameter($silence);
5892    if ($r1!==self::$FAILED) {
5893      goto choice_1;
5894    }
5895    $r1 = $this->parselong_positional_parameter($silence);
5896    if ($r1!==self::$FAILED) {
5897      goto choice_1;
5898    }
5899    $r1 = $this->parsenamed_parameter($silence);
5900    choice_1:
5901    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
5902
5903    $this->cache[$key] = $cached;
5904    return $r1;
5905  }
5906  private function parseOWS($silence) {
5907    $key = json_encode([360, $this->currPos]);
5908    $cached = $this->cache[$key] ?? null;
5909      if ($cached) {
5910        $this->currPos = $cached['nextPos'];
5911
5912        return $cached['result'];
5913      }
5914
5915    // start seq_1
5916    $p1 = $this->currPos;
5917    $r3 = [];
5918    for (;;) {
5919      if (strspn($this->input, " \x09\x0b\x0d\x0c", $this->currPos, 1) !== 0) {
5920        $r4 = $this->input[$this->currPos++];
5921        $r3[] = $r4;
5922      } else {
5923        $r4 = self::$FAILED;
5924        if (!$silence) {$this->fail(2);}
5925        break;
5926      }
5927    }
5928    // free $r4
5929    // start seq_2
5930    $p5 = $this->currPos;
5931    if (($this->input[$this->currPos] ?? null) === "#") {
5932      $this->currPos++;
5933      $r6 = "#";
5934    } else {
5935      if (!$silence) {$this->fail(3);}
5936      $r6 = self::$FAILED;
5937      $r4 = self::$FAILED;
5938      goto seq_2;
5939    }
5940    $r7 = [];
5941    for (;;) {
5942      $r8 = self::charAt($this->input, $this->currPos);
5943      if ($r8 !== '' && !($r8 === "\x0a")) {
5944        $this->currPos += strlen($r8);
5945        $r7[] = $r8;
5946      } else {
5947        $r8 = self::$FAILED;
5948        if (!$silence) {$this->fail(4);}
5949        break;
5950      }
5951    }
5952    // free $r8
5953    $r4 = [$r6,$r7];
5954    seq_2:
5955    if ($r4===self::$FAILED) {
5956      $r4 = null;
5957    }
5958    // free $p5
5959    $r2 = [$r3,$r4];
5960    seq_1:
5961    // free $r2,$p1
5962    $cached = ['nextPos' => $this->currPos, 'result' => $r2];
5963
5964    $this->cache[$key] = $cached;
5965    return $r2;
5966  }
5967  private function parselong_positional_parameter($silence) {
5968    $key = json_encode([402, $this->currPos]);
5969    $cached = $this->cache[$key] ?? null;
5970      if ($cached) {
5971        $this->currPos = $cached['nextPos'];
5972
5973        return $cached['result'];
5974      }
5975
5976    $p2 = $this->currPos;
5977    $p4 = $this->currPos;
5978    $r3 = self::$FAILED;
5979    for (;;) {
5980      $r5 = $this->input[$this->currPos] ?? '';
5981      if (preg_match("/^[0-9]/", $r5)) {
5982        $this->currPos++;
5983        $r3 = true;
5984      } else {
5985        $r5 = self::$FAILED;
5986        if (!$silence) {$this->fail(27);}
5987        break;
5988      }
5989    }
5990    // parameter <- $r3
5991    if ($r3!==self::$FAILED) {
5992      $r3 = substr($this->input, $p4, $this->currPos - $p4);
5993    } else {
5994      $r3 = self::$FAILED;
5995    }
5996    // free $r5
5997    // free $p4
5998    $r1 = $r3;
5999    if ($r1!==self::$FAILED) {
6000      $this->savedPos = $p2;
6001      $r1 = $this->a71($r3);
6002    }
6003    $cached = ['nextPos' => $this->currPos, 'result' => $r1];
6004
6005    $this->cache[$key] = $cached;
6006    return $r1;
6007  }
6008
6009  public function parse($input, $options = []) {
6010    $this->initInternal($input, $options);
6011    $startRule = $options['startRule'] ?? '(DEFAULT)';
6012    $result = null;
6013
6014    if (!empty($options['stream'])) {
6015      switch ($startRule) {
6016
6017        default:
6018          throw new \WikiPEG\InternalError("Can't stream rule $startRule.");
6019      }
6020    } else {
6021      switch ($startRule) {
6022        case '(DEFAULT)':
6023        case "program":
6024          $result = $this->parseprogram(false);
6025          break;
6026        default:
6027          throw new \WikiPEG\InternalError("Can't start parsing from rule $startRule.");
6028      }
6029    }
6030
6031    if ($result !== self::$FAILED && $this->currPos === $this->inputLength) {
6032      return $result;
6033    } else {
6034      if ($result !== self::$FAILED && $this->currPos < $this->inputLength) {
6035        $this->fail(0);
6036      }
6037      throw $this->buildParseException();
6038    }
6039  }
6040}
6041
6042