1<?php
2/*
3 * Generated by WikiPEG
4 */
5
6
7
8
9
10/* File-scope initializer */
11namespace Wikimedia\Parsoid\ParserTests;
12
13use Wikimedia\Parsoid\Utils\PHPUtils;
14
15
16class Grammar extends \Wikimedia\WikiPEG\PEGParserBase {
17	// initializer
18
19	/** @var string */
20	private $filename = '';
21	/** @var int */
22	private $lineNum = 1;
23
24	/**
25	 * @param string $filename
26	 * @return array
27	 */
28	public static function load( string $filename ) {
29		$g = new Grammar();
30		$g->filename = $filename;
31		$contents = file_get_contents( $filename ) ?: '';
32		if ( substr( $contents, -1 ) !== "\n" ) {
33			# ensure that the file is terminated with a newline
34			# to match `end_section` rule (and other uses of `eol`)
35			$contents .= "\n";
36		}
37		return $g->parse( $contents );
38	}
39
40
41	// cache init
42
43
44	// expectations
45	protected $expectations = [
46		0 => ["type" => "end", "description" => "end of input"],
471 => ["type" => "literal", "value" => "!!", "description" => "\"!!\""],
482 => ["type" => "class", "value" => "[0-9]", "description" => "[0-9]"],
493 => ["type" => "class", "value" => "[ \\t]", "description" => "[ \\t]"],
504 => ["type" => "class", "value" => "[vV]", "description" => "[vV]"],
515 => ["type" => "class", "value" => "[eE]", "description" => "[eE]"],
526 => ["type" => "class", "value" => "[rR]", "description" => "[rR]"],
537 => ["type" => "class", "value" => "[sS]", "description" => "[sS]"],
548 => ["type" => "class", "value" => "[iI]", "description" => "[iI]"],
559 => ["type" => "class", "value" => "[oO]", "description" => "[oO]"],
5610 => ["type" => "class", "value" => "[nN]", "description" => "[nN]"],
5711 => ["type" => "class", "value" => "[^\\n]", "description" => "[^\\n]"],
5812 => ["type" => "literal", "value" => "options", "description" => "\"options\""],
5913 => ["type" => "literal", "value" => "end", "description" => "\"end\""],
6014 => ["type" => "literal", "value" => "\x0a", "description" => "\"\\n\""],
6115 => ["type" => "literal", "value" => "#", "description" => "\"#\""],
6216 => ["type" => "literal", "value" => "article", "description" => "\"article\""],
6317 => ["type" => "literal", "value" => "text", "description" => "\"text\""],
6418 => ["type" => "literal", "value" => "endarticle", "description" => "\"endarticle\""],
6519 => ["type" => "literal", "value" => "test", "description" => "\"test\""],
6620 => ["type" => "class", "value" => "[^ \\t\\r\\n]", "description" => "[^ \\t\\r\\n]"],
6721 => ["type" => "literal", "value" => "hooks", "description" => "\"hooks\""],
6822 => ["type" => "literal", "value" => ":", "description" => "\":\""],
6923 => ["type" => "literal", "value" => "endhooks", "description" => "\"endhooks\""],
7024 => ["type" => "literal", "value" => "functionhooks", "description" => "\"functionhooks\""],
7125 => ["type" => "literal", "value" => "endfunctionhooks", "description" => "\"endfunctionhooks\""],
7226 => ["type" => "class", "value" => "[^ \\t\\n=!]", "description" => "[^ \\t\\n=!]"],
7327 => ["type" => "literal", "value" => "=", "description" => "\"=\""],
7428 => ["type" => "literal", "value" => ",", "description" => "\",\""],
7529 => ["type" => "literal", "value" => "[[", "description" => "\"[[\""],
7630 => ["type" => "class", "value" => "[^\\]\\n]", "description" => "[^\\]\\n]"],
7731 => ["type" => "literal", "value" => "]]", "description" => "\"]]\""],
7832 => ["type" => "class", "value" => "[\\\"]", "description" => "[\\\"]"],
7933 => ["type" => "class", "value" => "[^\\\\\\\"\\n]", "description" => "[^\\\\\\\"\\n]"],
8034 => ["type" => "literal", "value" => "\\", "description" => "\"\\\\\""],
8135 => ["type" => "class", "value" => "[^ \\t\\n\\\"\\'\\[\\]=,!\\{]", "description" => "[^ \\t\\n\\\"\\'\\[\\]=,!\\{]"],
8236 => ["type" => "literal", "value" => "{", "description" => "\"{\""],
8337 => ["type" => "class", "value" => "[^\\\"\\{\\}\\n]", "description" => "[^\\\"\\{\\}\\n]"],
8438 => ["type" => "literal", "value" => "}", "description" => "\"}\""],
85	];
86
87	// actions
88	private function a0($v) {
89
90		return [ 'type' => 'version', 'text' => $v ];
91
92}
93private function a1($sec) {
94
95	return $sec['text'];
96
97}
98private function a2() {
99 return $this->lineNum;
100}
101private function a3($l, $c) {
102
103	$c['filename'] = $this->filename;
104	$c['lineNumStart'] = $l;
105	$c['lineNumEnd'] = $this->lineNum;
106	return $c;
107
108}
109private function a4($c) {
110
111	return implode($c);
112
113}
114private function a5($opts) {
115
116	$o = [];
117	if ( $opts && count($opts) > 0 ) {
118		foreach ( $opts as $opt ) {
119			$o[$opt['k']] = $opt['v'];
120		}
121	}
122
123	return [ 'name' => 'options', 'text' => $o ];
124
125}
126private function a6($l) {
127 return [ 'type' => 'line', 'text' => $l ];
128}
129private function a7($nl) {
130 $this->lineNum++; return $nl;
131}
132private function a8($o, $rest) {
133
134	$result = [ $o ];
135	if ( $rest && count( $rest ) > 0 ) {
136		$result = array_merge( $result, $rest );
137	}
138	return $result;
139
140}
141private function a9($text) {
142 return [ 'type' => 'comment', 'text' => $text ];
143}
144private function a10($title, $text) {
145
146	return [
147		'type' => 'article',
148		'title' => $title,
149		'text' => $text
150	];
151
152}
153private function a11($testName, $sections) {
154
155	$test = [
156		'type' => 'test',
157		'testName' => $testName
158	];
159
160	foreach ( $sections as $section ) {
161		$test[$section['name']] = $section['text'];
162	}
163	// pegjs parser handles item options as follows:
164	//   item option             value of item.options.parsoid
165	//    <none>                          undefined
166	//    parsoid                             ""
167	//    parsoid=wt2html                  "wt2html"
168	//    parsoid=wt2html,wt2wt        ["wt2html","wt2wt"]
169	//    parsoid={"modes":["wt2wt"]}    {modes:['wt2wt']}
170
171	// treat 'parsoid=xxx,yyy' in options section as shorthand for
172	// 'parsoid={modes:["xxx","yyy"]}'
173	if ( isset($test['options']['parsoid'] ) ) {
174		if ($test['options']['parsoid'] === '') {
175			$test['options']['parsoid'] = [];
176		}
177		if ( is_string( $test['options']['parsoid'] ) ) {
178			$test['options']['parsoid'] = [ $test['options']['parsoid'] ];
179		}
180		if ( is_array( $test['options']['parsoid'] ) &&
181			isset( $test['options']['parsoid'][0] ) &&
182			!isset( $test['options']['parsoid']['modes'] )
183		) {
184			$test['options']['parsoid'] = [ 'modes' => $test['options']['parsoid'] ];
185		}
186	}
187	return $test;
188
189}
190private function a12($line) {
191
192	return $line;
193
194}
195private function a13($text) {
196
197	return [ 'type' => 'hooks', 'text' => $text ];
198
199}
200private function a14($text) {
201
202	return [ 'type' => 'functionhooks', 'text' => $text ];
203
204}
205private function a15($k, $v) {
206
207	return [ 'k' => strtolower( $k ), 'v' => $v ?? '' ];
208
209}
210private function a16($lines) {
211
212	return implode("\n", $lines);
213
214}
215private function a17($c) {
216 return implode( $c );
217}
218private function a18($name, $text) {
219
220	return [ 'name' => $name, 'text' => $text ];
221
222}
223private function a19($ovl) {
224
225	return count( $ovl ) === 1 ? $ovl[0] : $ovl;
226
227}
228private function a20($v, $ovl) {
229 return $ovl;
230}
231private function a21($v, $rest) {
232
233	$result = [ $v ];
234	if ( $rest && count( $rest ) > 0 ) {
235		$result = array_merge( $result, $rest );
236	}
237	return $result;
238
239}
240private function a22($v) {
241
242	if ( $v[0] === '"' || $v[0] === '{' ) { // } is needed to make pegjs happy
243		return PHPUtils::jsonDecode( $v );
244	}
245	return $v;
246
247}
248private function a23($v) {
249
250	// Perhaps we should canonicalize the title?
251	// Protect with JSON.stringify just in case the link target starts with
252	// double-quote or open-brace.
253	return PHPUtils::jsonEncode( implode( $v ) );
254
255}
256private function a24($c) {
257 return "\\" . $c;
258}
259private function a25($v) {
260
261	return '"' . implode( $v ) . '"';
262
263}
264private function a26($v) {
265
266	return implode( $v );
267
268}
269private function a27($v) {
270
271	return "{" . implode( $v ) . "}";
272
273}
274
275	// generated
276	private function parsetestfile($silence) {
277  // start seq_1
278  $p1 = $this->currPos;
279  $r3 = $this->parseformat($silence);
280  if ($r3===self::$FAILED) {
281    $r3 = null;
282  }
283  $r4 = $this->parsetestfile_options($silence);
284  if ($r4===self::$FAILED) {
285    $r4 = null;
286  }
287  $r5 = [];
288  for (;;) {
289    $r6 = $this->parselined_chunk($silence);
290    if ($r6!==self::$FAILED) {
291      $r5[] = $r6;
292    } else {
293      break;
294    }
295  }
296  if (count($r5) === 0) {
297    $r5 = self::$FAILED;
298  }
299  if ($r5===self::$FAILED) {
300    $this->currPos = $p1;
301    $r2 = self::$FAILED;
302    goto seq_1;
303  }
304  // free $r6
305  $r2 = [$r3,$r4,$r5];
306  seq_1:
307  // free $r2,$p1
308  return $r2;
309}
310private function parseformat($silence) {
311  $p2 = $this->currPos;
312  // start seq_1
313  $p3 = $this->currPos;
314  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
315    $r4 = "!!";
316    $this->currPos += 2;
317  } else {
318    if (!$silence) {$this->fail(1);}
319    $r4 = self::$FAILED;
320    $r1 = self::$FAILED;
321    goto seq_1;
322  }
323  $r5 = $this->discardwhitespace($silence);
324  if ($r5===self::$FAILED) {
325    $r5 = null;
326  }
327  $r6 = $this->discardversion_keyword($silence);
328  if ($r6===self::$FAILED) {
329    $this->currPos = $p3;
330    $r1 = self::$FAILED;
331    goto seq_1;
332  }
333  $r7 = self::$FAILED;
334  for (;;) {
335    $r8 = $this->discardwhitespace($silence);
336    if ($r8!==self::$FAILED) {
337      $r7 = true;
338    } else {
339      break;
340    }
341  }
342  if ($r7===self::$FAILED) {
343    $this->currPos = $p3;
344    $r1 = self::$FAILED;
345    goto seq_1;
346  }
347  // free $r8
348  $p9 = $this->currPos;
349  $r8 = self::$FAILED;
350  for (;;) {
351    $r10 = $this->input[$this->currPos] ?? '';
352    if (preg_match("/^[0-9]/", $r10)) {
353      $this->currPos++;
354      $r8 = true;
355    } else {
356      $r10 = self::$FAILED;
357      if (!$silence) {$this->fail(2);}
358      break;
359    }
360  }
361  // v <- $r8
362  if ($r8!==self::$FAILED) {
363    $r8 = substr($this->input, $p9, $this->currPos - $p9);
364  } else {
365    $r8 = self::$FAILED;
366    $this->currPos = $p3;
367    $r1 = self::$FAILED;
368    goto seq_1;
369  }
370  // free $r10
371  // free $p9
372  $r10 = $this->discardrest_of_line($silence);
373  if ($r10===self::$FAILED) {
374    $this->currPos = $p3;
375    $r1 = self::$FAILED;
376    goto seq_1;
377  }
378  $r1 = true;
379  seq_1:
380  if ($r1!==self::$FAILED) {
381    $this->savedPos = $p2;
382    $r1 = $this->a0($r8);
383  }
384  // free $p3
385  return $r1;
386}
387private function parsetestfile_options($silence) {
388  $p2 = $this->currPos;
389  // start seq_1
390  $p3 = $this->currPos;
391  $r4 = $this->parseoption_section($silence);
392  // sec <- $r4
393  if ($r4===self::$FAILED) {
394    $r1 = self::$FAILED;
395    goto seq_1;
396  }
397  $r5 = $this->discardend_section($silence);
398  if ($r5===self::$FAILED) {
399    $this->currPos = $p3;
400    $r1 = self::$FAILED;
401    goto seq_1;
402  }
403  $r1 = true;
404  seq_1:
405  if ($r1!==self::$FAILED) {
406    $this->savedPos = $p2;
407    $r1 = $this->a1($r4);
408  }
409  // free $p3
410  return $r1;
411}
412private function parselined_chunk($silence) {
413  $p2 = $this->currPos;
414  // start seq_1
415  $p3 = $this->currPos;
416  $p5 = $this->currPos;
417  $r4 = '';
418  // l <- $r4
419  if ($r4!==self::$FAILED) {
420    $this->savedPos = $p5;
421    $r4 = $this->a2();
422  } else {
423    $r1 = self::$FAILED;
424    goto seq_1;
425  }
426  $r6 = $this->parsechunk($silence);
427  // c <- $r6
428  if ($r6===self::$FAILED) {
429    $this->currPos = $p3;
430    $r1 = self::$FAILED;
431    goto seq_1;
432  }
433  $r1 = true;
434  seq_1:
435  if ($r1!==self::$FAILED) {
436    $this->savedPos = $p2;
437    $r1 = $this->a3($r4, $r6);
438  }
439  // free $p3
440  return $r1;
441}
442private function discardwhitespace($silence) {
443  $r1 = self::$FAILED;
444  for (;;) {
445    $r2 = $this->input[$this->currPos] ?? '';
446    if ($r2 === " " || $r2 === "\x09") {
447      $this->currPos++;
448      $r1 = true;
449    } else {
450      $r2 = self::$FAILED;
451      if (!$silence) {$this->fail(3);}
452      break;
453    }
454  }
455  // free $r2
456  return $r1;
457}
458private function discardversion_keyword($silence) {
459  // start seq_1
460  $p1 = $this->currPos;
461  $r3 = $this->input[$this->currPos] ?? '';
462  if ($r3 === "v" || $r3 === "V") {
463    $this->currPos++;
464  } else {
465    $r3 = self::$FAILED;
466    if (!$silence) {$this->fail(4);}
467    $r2 = self::$FAILED;
468    goto seq_1;
469  }
470  $r4 = $this->input[$this->currPos] ?? '';
471  if ($r4 === "e" || $r4 === "E") {
472    $this->currPos++;
473  } else {
474    $r4 = self::$FAILED;
475    if (!$silence) {$this->fail(5);}
476    $this->currPos = $p1;
477    $r2 = self::$FAILED;
478    goto seq_1;
479  }
480  $r5 = $this->input[$this->currPos] ?? '';
481  if ($r5 === "r" || $r5 === "R") {
482    $this->currPos++;
483  } else {
484    $r5 = self::$FAILED;
485    if (!$silence) {$this->fail(6);}
486    $this->currPos = $p1;
487    $r2 = self::$FAILED;
488    goto seq_1;
489  }
490  $r6 = $this->input[$this->currPos] ?? '';
491  if ($r6 === "s" || $r6 === "S") {
492    $this->currPos++;
493  } else {
494    $r6 = self::$FAILED;
495    if (!$silence) {$this->fail(7);}
496    $this->currPos = $p1;
497    $r2 = self::$FAILED;
498    goto seq_1;
499  }
500  $r7 = $this->input[$this->currPos] ?? '';
501  if ($r7 === "i" || $r7 === "I") {
502    $this->currPos++;
503  } else {
504    $r7 = self::$FAILED;
505    if (!$silence) {$this->fail(8);}
506    $this->currPos = $p1;
507    $r2 = self::$FAILED;
508    goto seq_1;
509  }
510  $r8 = $this->input[$this->currPos] ?? '';
511  if ($r8 === "o" || $r8 === "O") {
512    $this->currPos++;
513  } else {
514    $r8 = self::$FAILED;
515    if (!$silence) {$this->fail(9);}
516    $this->currPos = $p1;
517    $r2 = self::$FAILED;
518    goto seq_1;
519  }
520  $r9 = $this->input[$this->currPos] ?? '';
521  if ($r9 === "n" || $r9 === "N") {
522    $this->currPos++;
523  } else {
524    $r9 = self::$FAILED;
525    if (!$silence) {$this->fail(10);}
526    $this->currPos = $p1;
527    $r2 = self::$FAILED;
528    goto seq_1;
529  }
530  $r2 = true;
531  seq_1:
532  // free $r2,$p1
533  return $r2;
534}
535private function discardrest_of_line($silence) {
536  $p2 = $this->currPos;
537  // start seq_1
538  $p3 = $this->currPos;
539  $r4 = [];
540  for (;;) {
541    $r5 = self::charAt($this->input, $this->currPos);
542    if ($r5 !== '' && !($r5 === "\x0a")) {
543      $this->currPos += strlen($r5);
544      $r4[] = $r5;
545    } else {
546      $r5 = self::$FAILED;
547      if (!$silence) {$this->fail(11);}
548      break;
549    }
550  }
551  // c <- $r4
552  // free $r5
553  $r5 = $this->discardeol($silence);
554  if ($r5===self::$FAILED) {
555    $this->currPos = $p3;
556    $r1 = self::$FAILED;
557    goto seq_1;
558  }
559  $r1 = true;
560  seq_1:
561  if ($r1!==self::$FAILED) {
562    $this->savedPos = $p2;
563    $r1 = $this->a4($r4);
564  }
565  // free $p3
566  return $r1;
567}
568private function parseoption_section($silence) {
569  $p2 = $this->currPos;
570  // start seq_1
571  $p3 = $this->currPos;
572  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
573    $r4 = "!!";
574    $this->currPos += 2;
575  } else {
576    if (!$silence) {$this->fail(1);}
577    $r4 = self::$FAILED;
578    $r1 = self::$FAILED;
579    goto seq_1;
580  }
581  $r5 = $this->discardwhitespace($silence);
582  if ($r5===self::$FAILED) {
583    $r5 = null;
584  }
585  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "options", $this->currPos, 7, false) === 0) {
586    $r6 = "options";
587    $this->currPos += 7;
588  } else {
589    if (!$silence) {$this->fail(12);}
590    $r6 = self::$FAILED;
591    $this->currPos = $p3;
592    $r1 = self::$FAILED;
593    goto seq_1;
594  }
595  $r7 = $this->discardwhitespace($silence);
596  if ($r7===self::$FAILED) {
597    $r7 = null;
598  }
599  $r8 = $this->discardeol($silence);
600  if ($r8===self::$FAILED) {
601    $this->currPos = $p3;
602    $r1 = self::$FAILED;
603    goto seq_1;
604  }
605  $r9 = $this->parseoption_list($silence);
606  if ($r9===self::$FAILED) {
607    $r9 = null;
608  }
609  // opts <- $r9
610  $r1 = true;
611  seq_1:
612  if ($r1!==self::$FAILED) {
613    $this->savedPos = $p2;
614    $r1 = $this->a5($r9);
615  }
616  // free $p3
617  return $r1;
618}
619private function discardend_section($silence) {
620  // start seq_1
621  $p1 = $this->currPos;
622  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
623    $r3 = "!!";
624    $this->currPos += 2;
625  } else {
626    if (!$silence) {$this->fail(1);}
627    $r3 = self::$FAILED;
628    $r2 = self::$FAILED;
629    goto seq_1;
630  }
631  $r4 = $this->discardwhitespace($silence);
632  if ($r4===self::$FAILED) {
633    $r4 = null;
634  }
635  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "end", $this->currPos, 3, false) === 0) {
636    $r5 = "end";
637    $this->currPos += 3;
638  } else {
639    if (!$silence) {$this->fail(13);}
640    $r5 = self::$FAILED;
641    $this->currPos = $p1;
642    $r2 = self::$FAILED;
643    goto seq_1;
644  }
645  $r6 = $this->discardwhitespace($silence);
646  if ($r6===self::$FAILED) {
647    $r6 = null;
648  }
649  $r7 = $this->discardeol($silence);
650  if ($r7===self::$FAILED) {
651    $this->currPos = $p1;
652    $r2 = self::$FAILED;
653    goto seq_1;
654  }
655  $r2 = true;
656  seq_1:
657  // free $r2,$p1
658  return $r2;
659}
660private function parsechunk($silence) {
661  // start choice_1
662  $r1 = $this->parsecomment($silence);
663  if ($r1!==self::$FAILED) {
664    goto choice_1;
665  }
666  $r1 = $this->parsearticle($silence);
667  if ($r1!==self::$FAILED) {
668    goto choice_1;
669  }
670  $r1 = $this->parsetest($silence);
671  if ($r1!==self::$FAILED) {
672    goto choice_1;
673  }
674  $p2 = $this->currPos;
675  $r3 = $this->parseline($silence);
676  // l <- $r3
677  $r1 = $r3;
678  if ($r1!==self::$FAILED) {
679    $this->savedPos = $p2;
680    $r1 = $this->a6($r3);
681    goto choice_1;
682  }
683  $r1 = $this->parsehooks($silence);
684  if ($r1!==self::$FAILED) {
685    goto choice_1;
686  }
687  $r1 = $this->parsefunctionhooks($silence);
688  choice_1:
689  return $r1;
690}
691private function discardeol($silence) {
692  $p2 = $this->currPos;
693  // nl <- $r3
694  if (($this->input[$this->currPos] ?? null) === "\x0a") {
695    $this->currPos++;
696    $r3 = "\x0a";
697  } else {
698    if (!$silence) {$this->fail(14);}
699    $r3 = self::$FAILED;
700  }
701  $r1 = $r3;
702  if ($r1!==self::$FAILED) {
703    $this->savedPos = $p2;
704    $r1 = $this->a7($r3);
705  }
706  return $r1;
707}
708private function parseoption_list($silence) {
709  $p2 = $this->currPos;
710  // start seq_1
711  $p3 = $this->currPos;
712  $r4 = $this->parsean_option($silence);
713  // o <- $r4
714  if ($r4===self::$FAILED) {
715    $r1 = self::$FAILED;
716    goto seq_1;
717  }
718  $r5 = self::$FAILED;
719  for (;;) {
720    // start choice_1
721    $r6 = $this->input[$this->currPos] ?? '';
722    if ($r6 === " " || $r6 === "\x09") {
723      $this->currPos++;
724      goto choice_1;
725    } else {
726      $r6 = self::$FAILED;
727      if (!$silence) {$this->fail(3);}
728    }
729    $r6 = $this->discardeol($silence);
730    choice_1:
731    if ($r6!==self::$FAILED) {
732      $r5 = true;
733    } else {
734      break;
735    }
736  }
737  if ($r5===self::$FAILED) {
738    $this->currPos = $p3;
739    $r1 = self::$FAILED;
740    goto seq_1;
741  }
742  // free $r6
743  $r6 = $this->parseoption_list($silence);
744  if ($r6===self::$FAILED) {
745    $r6 = null;
746  }
747  // rest <- $r6
748  $r1 = true;
749  seq_1:
750  if ($r1!==self::$FAILED) {
751    $this->savedPos = $p2;
752    $r1 = $this->a8($r4, $r6);
753  }
754  // free $p3
755  return $r1;
756}
757private function parsecomment($silence) {
758  $p2 = $this->currPos;
759  // start seq_1
760  $p3 = $this->currPos;
761  if (($this->input[$this->currPos] ?? null) === "#") {
762    $this->currPos++;
763    $r4 = "#";
764  } else {
765    if (!$silence) {$this->fail(15);}
766    $r4 = self::$FAILED;
767    $r1 = self::$FAILED;
768    goto seq_1;
769  }
770  $r5 = $this->parserest_of_line($silence);
771  // text <- $r5
772  if ($r5===self::$FAILED) {
773    $this->currPos = $p3;
774    $r1 = self::$FAILED;
775    goto seq_1;
776  }
777  $r1 = true;
778  seq_1:
779  if ($r1!==self::$FAILED) {
780    $this->savedPos = $p2;
781    $r1 = $this->a9($r5);
782  }
783  // free $p3
784  return $r1;
785}
786private function parsearticle($silence) {
787  $p2 = $this->currPos;
788  // start seq_1
789  $p3 = $this->currPos;
790  $r4 = $this->discardstart_article($silence);
791  if ($r4===self::$FAILED) {
792    $r1 = self::$FAILED;
793    goto seq_1;
794  }
795  $r5 = $this->parseline($silence);
796  // title <- $r5
797  if ($r5===self::$FAILED) {
798    $this->currPos = $p3;
799    $r1 = self::$FAILED;
800    goto seq_1;
801  }
802  $r6 = $this->discardstart_text($silence);
803  if ($r6===self::$FAILED) {
804    $this->currPos = $p3;
805    $r1 = self::$FAILED;
806    goto seq_1;
807  }
808  $r7 = $this->parsetext($silence);
809  // text <- $r7
810  if ($r7===self::$FAILED) {
811    $this->currPos = $p3;
812    $r1 = self::$FAILED;
813    goto seq_1;
814  }
815  // start choice_1
816  $r8 = $this->discardend_article($silence);
817  if ($r8!==self::$FAILED) {
818    goto choice_1;
819  }
820  $r8 = $this->discardend_section($silence);
821  choice_1:
822  if ($r8===self::$FAILED) {
823    $this->currPos = $p3;
824    $r1 = self::$FAILED;
825    goto seq_1;
826  }
827  $r1 = true;
828  seq_1:
829  if ($r1!==self::$FAILED) {
830    $this->savedPos = $p2;
831    $r1 = $this->a10($r5, $r7);
832  }
833  // free $p3
834  return $r1;
835}
836private function parsetest($silence) {
837  $p2 = $this->currPos;
838  // start seq_1
839  $p3 = $this->currPos;
840  $r4 = $this->discardstart_test($silence);
841  if ($r4===self::$FAILED) {
842    $r1 = self::$FAILED;
843    goto seq_1;
844  }
845  $r5 = $this->parsetext($silence);
846  // testName <- $r5
847  if ($r5===self::$FAILED) {
848    $this->currPos = $p3;
849    $r1 = self::$FAILED;
850    goto seq_1;
851  }
852  $r6 = [];
853  for (;;) {
854    // start choice_1
855    $r7 = $this->parsesection($silence);
856    if ($r7!==self::$FAILED) {
857      goto choice_1;
858    }
859    $r7 = $this->parseoption_section($silence);
860    choice_1:
861    if ($r7!==self::$FAILED) {
862      $r6[] = $r7;
863    } else {
864      break;
865    }
866  }
867  // sections <- $r6
868  // free $r7
869  $r7 = $this->discardend_section($silence);
870  if ($r7===self::$FAILED) {
871    $this->currPos = $p3;
872    $r1 = self::$FAILED;
873    goto seq_1;
874  }
875  $r1 = true;
876  seq_1:
877  if ($r1!==self::$FAILED) {
878    $this->savedPos = $p2;
879    $r1 = $this->a11($r5, $r6);
880  }
881  // free $p3
882  return $r1;
883}
884private function parseline($silence) {
885  $p2 = $this->currPos;
886  // start seq_1
887  $p3 = $this->currPos;
888  $p4 = $this->currPos;
889  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
890    $r5 = "!!";
891    $this->currPos += 2;
892  } else {
893    $r5 = self::$FAILED;
894  }
895  if ($r5 === self::$FAILED) {
896    $r5 = false;
897  } else {
898    $r5 = self::$FAILED;
899    $this->currPos = $p4;
900    $r1 = self::$FAILED;
901    goto seq_1;
902  }
903  // free $p4
904  $r6 = $this->parserest_of_line($silence);
905  // line <- $r6
906  if ($r6===self::$FAILED) {
907    $this->currPos = $p3;
908    $r1 = self::$FAILED;
909    goto seq_1;
910  }
911  $r1 = true;
912  seq_1:
913  if ($r1!==self::$FAILED) {
914    $this->savedPos = $p2;
915    $r1 = $this->a12($r6);
916  }
917  // free $p3
918  return $r1;
919}
920private function parsehooks($silence) {
921  $p2 = $this->currPos;
922  // start seq_1
923  $p3 = $this->currPos;
924  $r4 = $this->discardstart_hooks($silence);
925  if ($r4===self::$FAILED) {
926    $r1 = self::$FAILED;
927    goto seq_1;
928  }
929  $r5 = $this->parsetext($silence);
930  // text <- $r5
931  if ($r5===self::$FAILED) {
932    $this->currPos = $p3;
933    $r1 = self::$FAILED;
934    goto seq_1;
935  }
936  // start choice_1
937  $r6 = $this->discardend_hooks($silence);
938  if ($r6!==self::$FAILED) {
939    goto choice_1;
940  }
941  $r6 = $this->discardend_section($silence);
942  choice_1:
943  if ($r6===self::$FAILED) {
944    $this->currPos = $p3;
945    $r1 = self::$FAILED;
946    goto seq_1;
947  }
948  $r1 = true;
949  seq_1:
950  if ($r1!==self::$FAILED) {
951    $this->savedPos = $p2;
952    $r1 = $this->a13($r5);
953  }
954  // free $p3
955  return $r1;
956}
957private function parsefunctionhooks($silence) {
958  $p2 = $this->currPos;
959  // start seq_1
960  $p3 = $this->currPos;
961  $r4 = $this->discardstart_functionhooks($silence);
962  if ($r4===self::$FAILED) {
963    $r1 = self::$FAILED;
964    goto seq_1;
965  }
966  $r5 = $this->parsetext($silence);
967  // text <- $r5
968  if ($r5===self::$FAILED) {
969    $this->currPos = $p3;
970    $r1 = self::$FAILED;
971    goto seq_1;
972  }
973  // start choice_1
974  $r6 = $this->discardend_functionhooks($silence);
975  if ($r6!==self::$FAILED) {
976    goto choice_1;
977  }
978  $r6 = $this->discardend_section($silence);
979  choice_1:
980  if ($r6===self::$FAILED) {
981    $this->currPos = $p3;
982    $r1 = self::$FAILED;
983    goto seq_1;
984  }
985  $r1 = true;
986  seq_1:
987  if ($r1!==self::$FAILED) {
988    $this->savedPos = $p2;
989    $r1 = $this->a14($r5);
990  }
991  // free $p3
992  return $r1;
993}
994private function parsean_option($silence) {
995  $p2 = $this->currPos;
996  // start seq_1
997  $p3 = $this->currPos;
998  $r4 = $this->parseoption_name($silence);
999  // k <- $r4
1000  if ($r4===self::$FAILED) {
1001    $r1 = self::$FAILED;
1002    goto seq_1;
1003  }
1004  $r5 = $this->parseoption_value($silence);
1005  if ($r5===self::$FAILED) {
1006    $r5 = null;
1007  }
1008  // v <- $r5
1009  $r1 = true;
1010  seq_1:
1011  if ($r1!==self::$FAILED) {
1012    $this->savedPos = $p2;
1013    $r1 = $this->a15($r4, $r5);
1014  }
1015  // free $p3
1016  return $r1;
1017}
1018private function parserest_of_line($silence) {
1019  $p2 = $this->currPos;
1020  // start seq_1
1021  $p3 = $this->currPos;
1022  $r4 = [];
1023  for (;;) {
1024    $r5 = self::charAt($this->input, $this->currPos);
1025    if ($r5 !== '' && !($r5 === "\x0a")) {
1026      $this->currPos += strlen($r5);
1027      $r4[] = $r5;
1028    } else {
1029      $r5 = self::$FAILED;
1030      if (!$silence) {$this->fail(11);}
1031      break;
1032    }
1033  }
1034  // c <- $r4
1035  // free $r5
1036  $r5 = $this->discardeol($silence);
1037  if ($r5===self::$FAILED) {
1038    $this->currPos = $p3;
1039    $r1 = self::$FAILED;
1040    goto seq_1;
1041  }
1042  $r1 = true;
1043  seq_1:
1044  if ($r1!==self::$FAILED) {
1045    $this->savedPos = $p2;
1046    $r1 = $this->a4($r4);
1047  }
1048  // free $p3
1049  return $r1;
1050}
1051private function discardstart_article($silence) {
1052  // start seq_1
1053  $p1 = $this->currPos;
1054  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1055    $r3 = "!!";
1056    $this->currPos += 2;
1057  } else {
1058    if (!$silence) {$this->fail(1);}
1059    $r3 = self::$FAILED;
1060    $r2 = self::$FAILED;
1061    goto seq_1;
1062  }
1063  $r4 = $this->discardwhitespace($silence);
1064  if ($r4===self::$FAILED) {
1065    $r4 = null;
1066  }
1067  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "article", $this->currPos, 7, false) === 0) {
1068    $r5 = "article";
1069    $this->currPos += 7;
1070  } else {
1071    if (!$silence) {$this->fail(16);}
1072    $r5 = self::$FAILED;
1073    $this->currPos = $p1;
1074    $r2 = self::$FAILED;
1075    goto seq_1;
1076  }
1077  $r6 = $this->discardwhitespace($silence);
1078  if ($r6===self::$FAILED) {
1079    $r6 = null;
1080  }
1081  $r7 = $this->discardeol($silence);
1082  if ($r7===self::$FAILED) {
1083    $this->currPos = $p1;
1084    $r2 = self::$FAILED;
1085    goto seq_1;
1086  }
1087  $r2 = true;
1088  seq_1:
1089  // free $r2,$p1
1090  return $r2;
1091}
1092private function discardstart_text($silence) {
1093  // start seq_1
1094  $p1 = $this->currPos;
1095  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1096    $r3 = "!!";
1097    $this->currPos += 2;
1098  } else {
1099    if (!$silence) {$this->fail(1);}
1100    $r3 = self::$FAILED;
1101    $r2 = self::$FAILED;
1102    goto seq_1;
1103  }
1104  $r4 = $this->discardwhitespace($silence);
1105  if ($r4===self::$FAILED) {
1106    $r4 = null;
1107  }
1108  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "text", $this->currPos, 4, false) === 0) {
1109    $r5 = "text";
1110    $this->currPos += 4;
1111  } else {
1112    if (!$silence) {$this->fail(17);}
1113    $r5 = self::$FAILED;
1114    $this->currPos = $p1;
1115    $r2 = self::$FAILED;
1116    goto seq_1;
1117  }
1118  $r6 = $this->discardwhitespace($silence);
1119  if ($r6===self::$FAILED) {
1120    $r6 = null;
1121  }
1122  $r7 = $this->discardeol($silence);
1123  if ($r7===self::$FAILED) {
1124    $this->currPos = $p1;
1125    $r2 = self::$FAILED;
1126    goto seq_1;
1127  }
1128  $r2 = true;
1129  seq_1:
1130  // free $r2,$p1
1131  return $r2;
1132}
1133private function parsetext($silence) {
1134  $p2 = $this->currPos;
1135  $r3 = [];
1136  for (;;) {
1137    $r4 = $this->parseline($silence);
1138    if ($r4!==self::$FAILED) {
1139      $r3[] = $r4;
1140    } else {
1141      break;
1142    }
1143  }
1144  // lines <- $r3
1145  // free $r4
1146  $r1 = $r3;
1147  if ($r1!==self::$FAILED) {
1148    $this->savedPos = $p2;
1149    $r1 = $this->a16($r3);
1150  }
1151  return $r1;
1152}
1153private function discardend_article($silence) {
1154  // start seq_1
1155  $p1 = $this->currPos;
1156  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1157    $r3 = "!!";
1158    $this->currPos += 2;
1159  } else {
1160    if (!$silence) {$this->fail(1);}
1161    $r3 = self::$FAILED;
1162    $r2 = self::$FAILED;
1163    goto seq_1;
1164  }
1165  $r4 = $this->discardwhitespace($silence);
1166  if ($r4===self::$FAILED) {
1167    $r4 = null;
1168  }
1169  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "endarticle", $this->currPos, 10, false) === 0) {
1170    $r5 = "endarticle";
1171    $this->currPos += 10;
1172  } else {
1173    if (!$silence) {$this->fail(18);}
1174    $r5 = self::$FAILED;
1175    $this->currPos = $p1;
1176    $r2 = self::$FAILED;
1177    goto seq_1;
1178  }
1179  $r6 = $this->discardwhitespace($silence);
1180  if ($r6===self::$FAILED) {
1181    $r6 = null;
1182  }
1183  $r7 = $this->discardeol($silence);
1184  if ($r7===self::$FAILED) {
1185    $this->currPos = $p1;
1186    $r2 = self::$FAILED;
1187    goto seq_1;
1188  }
1189  $r2 = true;
1190  seq_1:
1191  // free $r2,$p1
1192  return $r2;
1193}
1194private function discardstart_test($silence) {
1195  // start seq_1
1196  $p1 = $this->currPos;
1197  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1198    $r3 = "!!";
1199    $this->currPos += 2;
1200  } else {
1201    if (!$silence) {$this->fail(1);}
1202    $r3 = self::$FAILED;
1203    $r2 = self::$FAILED;
1204    goto seq_1;
1205  }
1206  $r4 = $this->discardwhitespace($silence);
1207  if ($r4===self::$FAILED) {
1208    $r4 = null;
1209  }
1210  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "test", $this->currPos, 4, false) === 0) {
1211    $r5 = "test";
1212    $this->currPos += 4;
1213  } else {
1214    if (!$silence) {$this->fail(19);}
1215    $r5 = self::$FAILED;
1216    $this->currPos = $p1;
1217    $r2 = self::$FAILED;
1218    goto seq_1;
1219  }
1220  $r6 = $this->discardwhitespace($silence);
1221  if ($r6===self::$FAILED) {
1222    $r6 = null;
1223  }
1224  $r7 = $this->discardeol($silence);
1225  if ($r7===self::$FAILED) {
1226    $this->currPos = $p1;
1227    $r2 = self::$FAILED;
1228    goto seq_1;
1229  }
1230  $r2 = true;
1231  seq_1:
1232  // free $r2,$p1
1233  return $r2;
1234}
1235private function parsesection($silence) {
1236  $p2 = $this->currPos;
1237  // start seq_1
1238  $p3 = $this->currPos;
1239  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1240    $r4 = "!!";
1241    $this->currPos += 2;
1242  } else {
1243    if (!$silence) {$this->fail(1);}
1244    $r4 = self::$FAILED;
1245    $r1 = self::$FAILED;
1246    goto seq_1;
1247  }
1248  $r5 = $this->discardwhitespace($silence);
1249  if ($r5===self::$FAILED) {
1250    $r5 = null;
1251  }
1252  $p6 = $this->currPos;
1253  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "end", $this->currPos, 3, false) === 0) {
1254    $r7 = "end";
1255    $this->currPos += 3;
1256  } else {
1257    $r7 = self::$FAILED;
1258  }
1259  if ($r7 === self::$FAILED) {
1260    $r7 = false;
1261  } else {
1262    $r7 = self::$FAILED;
1263    $this->currPos = $p6;
1264    $this->currPos = $p3;
1265    $r1 = self::$FAILED;
1266    goto seq_1;
1267  }
1268  // free $p6
1269  $p6 = $this->currPos;
1270  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "options", $this->currPos, 7, false) === 0) {
1271    $r8 = "options";
1272    $this->currPos += 7;
1273  } else {
1274    $r8 = self::$FAILED;
1275  }
1276  if ($r8 === self::$FAILED) {
1277    $r8 = false;
1278  } else {
1279    $r8 = self::$FAILED;
1280    $this->currPos = $p6;
1281    $this->currPos = $p3;
1282    $r1 = self::$FAILED;
1283    goto seq_1;
1284  }
1285  // free $p6
1286  $p6 = $this->currPos;
1287  $r10 = [];
1288  for (;;) {
1289    if (strcspn($this->input, " \x09\x0d\x0a", $this->currPos, 1) !== 0) {
1290      $r11 = self::consumeChar($this->input, $this->currPos);
1291      $r10[] = $r11;
1292    } else {
1293      $r11 = self::$FAILED;
1294      if (!$silence) {$this->fail(20);}
1295      break;
1296    }
1297  }
1298  if (count($r10) === 0) {
1299    $r10 = self::$FAILED;
1300  }
1301  // c <- $r10
1302  // free $r11
1303  $r9 = $r10;
1304  // name <- $r9
1305  if ($r9!==self::$FAILED) {
1306    $this->savedPos = $p6;
1307    $r9 = $this->a17($r10);
1308  } else {
1309    $this->currPos = $p3;
1310    $r1 = self::$FAILED;
1311    goto seq_1;
1312  }
1313  $r11 = $this->discardrest_of_line($silence);
1314  if ($r11===self::$FAILED) {
1315    $this->currPos = $p3;
1316    $r1 = self::$FAILED;
1317    goto seq_1;
1318  }
1319  $r12 = $this->parsetext($silence);
1320  // text <- $r12
1321  if ($r12===self::$FAILED) {
1322    $this->currPos = $p3;
1323    $r1 = self::$FAILED;
1324    goto seq_1;
1325  }
1326  $r1 = true;
1327  seq_1:
1328  if ($r1!==self::$FAILED) {
1329    $this->savedPos = $p2;
1330    $r1 = $this->a18($r9, $r12);
1331  }
1332  // free $p3
1333  return $r1;
1334}
1335private function discardstart_hooks($silence) {
1336  // start seq_1
1337  $p1 = $this->currPos;
1338  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1339    $r3 = "!!";
1340    $this->currPos += 2;
1341  } else {
1342    if (!$silence) {$this->fail(1);}
1343    $r3 = self::$FAILED;
1344    $r2 = self::$FAILED;
1345    goto seq_1;
1346  }
1347  $r4 = $this->discardwhitespace($silence);
1348  if ($r4===self::$FAILED) {
1349    $r4 = null;
1350  }
1351  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "hooks", $this->currPos, 5, false) === 0) {
1352    $r5 = "hooks";
1353    $this->currPos += 5;
1354  } else {
1355    if (!$silence) {$this->fail(21);}
1356    $r5 = self::$FAILED;
1357    $this->currPos = $p1;
1358    $r2 = self::$FAILED;
1359    goto seq_1;
1360  }
1361  if (($this->input[$this->currPos] ?? null) === ":") {
1362    $this->currPos++;
1363    $r6 = ":";
1364  } else {
1365    if (!$silence) {$this->fail(22);}
1366    $r6 = self::$FAILED;
1367    $r6 = null;
1368  }
1369  $r7 = $this->discardwhitespace($silence);
1370  if ($r7===self::$FAILED) {
1371    $r7 = null;
1372  }
1373  $r8 = $this->discardeol($silence);
1374  if ($r8===self::$FAILED) {
1375    $this->currPos = $p1;
1376    $r2 = self::$FAILED;
1377    goto seq_1;
1378  }
1379  $r2 = true;
1380  seq_1:
1381  // free $r2,$p1
1382  return $r2;
1383}
1384private function discardend_hooks($silence) {
1385  // start seq_1
1386  $p1 = $this->currPos;
1387  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1388    $r3 = "!!";
1389    $this->currPos += 2;
1390  } else {
1391    if (!$silence) {$this->fail(1);}
1392    $r3 = self::$FAILED;
1393    $r2 = self::$FAILED;
1394    goto seq_1;
1395  }
1396  $r4 = $this->discardwhitespace($silence);
1397  if ($r4===self::$FAILED) {
1398    $r4 = null;
1399  }
1400  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "endhooks", $this->currPos, 8, false) === 0) {
1401    $r5 = "endhooks";
1402    $this->currPos += 8;
1403  } else {
1404    if (!$silence) {$this->fail(23);}
1405    $r5 = self::$FAILED;
1406    $this->currPos = $p1;
1407    $r2 = self::$FAILED;
1408    goto seq_1;
1409  }
1410  $r6 = $this->discardwhitespace($silence);
1411  if ($r6===self::$FAILED) {
1412    $r6 = null;
1413  }
1414  $r7 = $this->discardeol($silence);
1415  if ($r7===self::$FAILED) {
1416    $this->currPos = $p1;
1417    $r2 = self::$FAILED;
1418    goto seq_1;
1419  }
1420  $r2 = true;
1421  seq_1:
1422  // free $r2,$p1
1423  return $r2;
1424}
1425private function discardstart_functionhooks($silence) {
1426  // start seq_1
1427  $p1 = $this->currPos;
1428  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1429    $r3 = "!!";
1430    $this->currPos += 2;
1431  } else {
1432    if (!$silence) {$this->fail(1);}
1433    $r3 = self::$FAILED;
1434    $r2 = self::$FAILED;
1435    goto seq_1;
1436  }
1437  $r4 = $this->discardwhitespace($silence);
1438  if ($r4===self::$FAILED) {
1439    $r4 = null;
1440  }
1441  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "functionhooks", $this->currPos, 13, false) === 0) {
1442    $r5 = "functionhooks";
1443    $this->currPos += 13;
1444  } else {
1445    if (!$silence) {$this->fail(24);}
1446    $r5 = self::$FAILED;
1447    $this->currPos = $p1;
1448    $r2 = self::$FAILED;
1449    goto seq_1;
1450  }
1451  if (($this->input[$this->currPos] ?? null) === ":") {
1452    $this->currPos++;
1453    $r6 = ":";
1454  } else {
1455    if (!$silence) {$this->fail(22);}
1456    $r6 = self::$FAILED;
1457    $r6 = null;
1458  }
1459  $r7 = $this->discardwhitespace($silence);
1460  if ($r7===self::$FAILED) {
1461    $r7 = null;
1462  }
1463  $r8 = $this->discardeol($silence);
1464  if ($r8===self::$FAILED) {
1465    $this->currPos = $p1;
1466    $r2 = self::$FAILED;
1467    goto seq_1;
1468  }
1469  $r2 = true;
1470  seq_1:
1471  // free $r2,$p1
1472  return $r2;
1473}
1474private function discardend_functionhooks($silence) {
1475  // start seq_1
1476  $p1 = $this->currPos;
1477  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1478    $r3 = "!!";
1479    $this->currPos += 2;
1480  } else {
1481    if (!$silence) {$this->fail(1);}
1482    $r3 = self::$FAILED;
1483    $r2 = self::$FAILED;
1484    goto seq_1;
1485  }
1486  $r4 = $this->discardwhitespace($silence);
1487  if ($r4===self::$FAILED) {
1488    $r4 = null;
1489  }
1490  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "endfunctionhooks", $this->currPos, 16, false) === 0) {
1491    $r5 = "endfunctionhooks";
1492    $this->currPos += 16;
1493  } else {
1494    if (!$silence) {$this->fail(25);}
1495    $r5 = self::$FAILED;
1496    $this->currPos = $p1;
1497    $r2 = self::$FAILED;
1498    goto seq_1;
1499  }
1500  if (($this->input[$this->currPos] ?? null) === ":") {
1501    $this->currPos++;
1502    $r6 = ":";
1503  } else {
1504    if (!$silence) {$this->fail(22);}
1505    $r6 = self::$FAILED;
1506    $r6 = null;
1507  }
1508  $r7 = $this->discardwhitespace($silence);
1509  if ($r7===self::$FAILED) {
1510    $r7 = null;
1511  }
1512  $r8 = $this->discardeol($silence);
1513  if ($r8===self::$FAILED) {
1514    $this->currPos = $p1;
1515    $r2 = self::$FAILED;
1516    goto seq_1;
1517  }
1518  $r2 = true;
1519  seq_1:
1520  // free $r2,$p1
1521  return $r2;
1522}
1523private function parseoption_name($silence) {
1524  $p2 = $this->currPos;
1525  $r3 = [];
1526  for (;;) {
1527    if (strcspn($this->input, " \x09\x0a=!", $this->currPos, 1) !== 0) {
1528      $r4 = self::consumeChar($this->input, $this->currPos);
1529      $r3[] = $r4;
1530    } else {
1531      $r4 = self::$FAILED;
1532      if (!$silence) {$this->fail(26);}
1533      break;
1534    }
1535  }
1536  if (count($r3) === 0) {
1537    $r3 = self::$FAILED;
1538  }
1539  // c <- $r3
1540  // free $r4
1541  $r1 = $r3;
1542  if ($r1!==self::$FAILED) {
1543    $this->savedPos = $p2;
1544    $r1 = $this->a4($r3);
1545  }
1546  return $r1;
1547}
1548private function parseoption_value($silence) {
1549  $p2 = $this->currPos;
1550  // start seq_1
1551  $p3 = $this->currPos;
1552  $r4 = $this->discardwhitespace($silence);
1553  if ($r4===self::$FAILED) {
1554    $r4 = null;
1555  }
1556  if (($this->input[$this->currPos] ?? null) === "=") {
1557    $this->currPos++;
1558    $r5 = "=";
1559  } else {
1560    if (!$silence) {$this->fail(27);}
1561    $r5 = self::$FAILED;
1562    $this->currPos = $p3;
1563    $r1 = self::$FAILED;
1564    goto seq_1;
1565  }
1566  $r6 = $this->discardwhitespace($silence);
1567  if ($r6===self::$FAILED) {
1568    $r6 = null;
1569  }
1570  $r7 = $this->parseoption_value_list($silence);
1571  // ovl <- $r7
1572  if ($r7===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->a19($r7);
1582  }
1583  // free $p3
1584  return $r1;
1585}
1586private function parseoption_value_list($silence) {
1587  $p2 = $this->currPos;
1588  // start seq_1
1589  $p3 = $this->currPos;
1590  $r4 = $this->parsean_option_value($silence);
1591  // v <- $r4
1592  if ($r4===self::$FAILED) {
1593    $r1 = self::$FAILED;
1594    goto seq_1;
1595  }
1596  $p6 = $this->currPos;
1597  // start seq_2
1598  $p7 = $this->currPos;
1599  $r8 = $this->discardwhitespace($silence);
1600  if ($r8===self::$FAILED) {
1601    $r8 = null;
1602  }
1603  if (($this->input[$this->currPos] ?? null) === ",") {
1604    $this->currPos++;
1605    $r9 = ",";
1606  } else {
1607    if (!$silence) {$this->fail(28);}
1608    $r9 = self::$FAILED;
1609    $this->currPos = $p7;
1610    $r5 = self::$FAILED;
1611    goto seq_2;
1612  }
1613  $r10 = $this->discardwhitespace($silence);
1614  if ($r10===self::$FAILED) {
1615    $r10 = null;
1616  }
1617  $r11 = $this->parseoption_value_list($silence);
1618  // ovl <- $r11
1619  if ($r11===self::$FAILED) {
1620    $this->currPos = $p7;
1621    $r5 = self::$FAILED;
1622    goto seq_2;
1623  }
1624  $r5 = true;
1625  seq_2:
1626  if ($r5!==self::$FAILED) {
1627    $this->savedPos = $p6;
1628    $r5 = $this->a20($r4, $r11);
1629  } else {
1630    $r5 = null;
1631  }
1632  // free $p7
1633  // rest <- $r5
1634  $r1 = true;
1635  seq_1:
1636  if ($r1!==self::$FAILED) {
1637    $this->savedPos = $p2;
1638    $r1 = $this->a21($r4, $r5);
1639  }
1640  // free $p3
1641  return $r1;
1642}
1643private function parsean_option_value($silence) {
1644  $p2 = $this->currPos;
1645  // start choice_1
1646  $r3 = $this->parselink_target_value($silence);
1647  if ($r3!==self::$FAILED) {
1648    goto choice_1;
1649  }
1650  $r3 = $this->parsequoted_value($silence);
1651  if ($r3!==self::$FAILED) {
1652    goto choice_1;
1653  }
1654  $r3 = $this->parseplain_value($silence);
1655  if ($r3!==self::$FAILED) {
1656    goto choice_1;
1657  }
1658  $r3 = $this->parsejson_value($silence);
1659  choice_1:
1660  // v <- $r3
1661  $r1 = $r3;
1662  if ($r1!==self::$FAILED) {
1663    $this->savedPos = $p2;
1664    $r1 = $this->a22($r3);
1665  }
1666  return $r1;
1667}
1668private function parselink_target_value($silence) {
1669  $p2 = $this->currPos;
1670  // start seq_1
1671  $p3 = $this->currPos;
1672  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "[[", $this->currPos, 2, false) === 0) {
1673    $r4 = "[[";
1674    $this->currPos += 2;
1675  } else {
1676    if (!$silence) {$this->fail(29);}
1677    $r4 = self::$FAILED;
1678    $r1 = self::$FAILED;
1679    goto seq_1;
1680  }
1681  $r5 = [];
1682  for (;;) {
1683    $r6 = self::charAt($this->input, $this->currPos);
1684    if ($r6 !== '' && !($r6 === "]" || $r6 === "\x0a")) {
1685      $this->currPos += strlen($r6);
1686      $r5[] = $r6;
1687    } else {
1688      $r6 = self::$FAILED;
1689      if (!$silence) {$this->fail(30);}
1690      break;
1691    }
1692  }
1693  // v <- $r5
1694  // free $r6
1695  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "]]", $this->currPos, 2, false) === 0) {
1696    $r6 = "]]";
1697    $this->currPos += 2;
1698  } else {
1699    if (!$silence) {$this->fail(31);}
1700    $r6 = self::$FAILED;
1701    $this->currPos = $p3;
1702    $r1 = self::$FAILED;
1703    goto seq_1;
1704  }
1705  $r1 = true;
1706  seq_1:
1707  if ($r1!==self::$FAILED) {
1708    $this->savedPos = $p2;
1709    $r1 = $this->a23($r5);
1710  }
1711  // free $p3
1712  return $r1;
1713}
1714private function parsequoted_value($silence) {
1715  $p2 = $this->currPos;
1716  // start seq_1
1717  $p3 = $this->currPos;
1718  $r4 = $this->input[$this->currPos] ?? '';
1719  if ($r4 === "\"") {
1720    $this->currPos++;
1721  } else {
1722    $r4 = self::$FAILED;
1723    if (!$silence) {$this->fail(32);}
1724    $r1 = self::$FAILED;
1725    goto seq_1;
1726  }
1727  $r5 = [];
1728  for (;;) {
1729    // start choice_1
1730    if (strcspn($this->input, "\\\"\x0a", $this->currPos, 1) !== 0) {
1731      $r6 = self::consumeChar($this->input, $this->currPos);
1732      goto choice_1;
1733    } else {
1734      $r6 = self::$FAILED;
1735      if (!$silence) {$this->fail(33);}
1736    }
1737    $p7 = $this->currPos;
1738    // start seq_2
1739    $p8 = $this->currPos;
1740    if (($this->input[$this->currPos] ?? null) === "\\") {
1741      $this->currPos++;
1742      $r9 = "\\";
1743    } else {
1744      if (!$silence) {$this->fail(34);}
1745      $r9 = self::$FAILED;
1746      $r6 = self::$FAILED;
1747      goto seq_2;
1748    }
1749    $r10 = self::charAt($this->input, $this->currPos);
1750    // c <- $r10
1751    if ($r10 !== '' && !($r10 === "\x0a")) {
1752      $this->currPos += strlen($r10);
1753    } else {
1754      $r10 = self::$FAILED;
1755      if (!$silence) {$this->fail(11);}
1756      $this->currPos = $p8;
1757      $r6 = self::$FAILED;
1758      goto seq_2;
1759    }
1760    $r6 = true;
1761    seq_2:
1762    if ($r6!==self::$FAILED) {
1763      $this->savedPos = $p7;
1764      $r6 = $this->a24($r10);
1765    }
1766    // free $p8
1767    choice_1:
1768    if ($r6!==self::$FAILED) {
1769      $r5[] = $r6;
1770    } else {
1771      break;
1772    }
1773  }
1774  // v <- $r5
1775  // free $r6
1776  $r6 = $this->input[$this->currPos] ?? '';
1777  if ($r6 === "\"") {
1778    $this->currPos++;
1779  } else {
1780    $r6 = self::$FAILED;
1781    if (!$silence) {$this->fail(32);}
1782    $this->currPos = $p3;
1783    $r1 = self::$FAILED;
1784    goto seq_1;
1785  }
1786  $r1 = true;
1787  seq_1:
1788  if ($r1!==self::$FAILED) {
1789    $this->savedPos = $p2;
1790    $r1 = $this->a25($r5);
1791  }
1792  // free $p3
1793  return $r1;
1794}
1795private function parseplain_value($silence) {
1796  $p2 = $this->currPos;
1797  $r3 = [];
1798  for (;;) {
1799    if (strcspn($this->input, " \x09\x0a\"'[]=,!{", $this->currPos, 1) !== 0) {
1800      $r4 = self::consumeChar($this->input, $this->currPos);
1801      $r3[] = $r4;
1802    } else {
1803      $r4 = self::$FAILED;
1804      if (!$silence) {$this->fail(35);}
1805      break;
1806    }
1807  }
1808  if (count($r3) === 0) {
1809    $r3 = self::$FAILED;
1810  }
1811  // v <- $r3
1812  // free $r4
1813  $r1 = $r3;
1814  if ($r1!==self::$FAILED) {
1815    $this->savedPos = $p2;
1816    $r1 = $this->a26($r3);
1817  }
1818  return $r1;
1819}
1820private function parsejson_value($silence) {
1821  $p2 = $this->currPos;
1822  // start seq_1
1823  $p3 = $this->currPos;
1824  if (($this->input[$this->currPos] ?? null) === "{") {
1825    $this->currPos++;
1826    $r4 = "{";
1827  } else {
1828    if (!$silence) {$this->fail(36);}
1829    $r4 = self::$FAILED;
1830    $r1 = self::$FAILED;
1831    goto seq_1;
1832  }
1833  $r5 = [];
1834  for (;;) {
1835    // start choice_1
1836    if (strcspn($this->input, "\"{}\x0a", $this->currPos, 1) !== 0) {
1837      $r6 = self::consumeChar($this->input, $this->currPos);
1838      goto choice_1;
1839    } else {
1840      $r6 = self::$FAILED;
1841      if (!$silence) {$this->fail(37);}
1842    }
1843    $r6 = $this->parsequoted_value($silence);
1844    if ($r6!==self::$FAILED) {
1845      goto choice_1;
1846    }
1847    $r6 = $this->parsejson_value($silence);
1848    if ($r6!==self::$FAILED) {
1849      goto choice_1;
1850    }
1851    $r6 = $this->parseeol($silence);
1852    choice_1:
1853    if ($r6!==self::$FAILED) {
1854      $r5[] = $r6;
1855    } else {
1856      break;
1857    }
1858  }
1859  // v <- $r5
1860  // free $r6
1861  if (($this->input[$this->currPos] ?? null) === "}") {
1862    $this->currPos++;
1863    $r6 = "}";
1864  } else {
1865    if (!$silence) {$this->fail(38);}
1866    $r6 = self::$FAILED;
1867    $this->currPos = $p3;
1868    $r1 = self::$FAILED;
1869    goto seq_1;
1870  }
1871  $r1 = true;
1872  seq_1:
1873  if ($r1!==self::$FAILED) {
1874    $this->savedPos = $p2;
1875    $r1 = $this->a27($r5);
1876  }
1877  // free $p3
1878  return $r1;
1879}
1880private function parseeol($silence) {
1881  $p2 = $this->currPos;
1882  // nl <- $r3
1883  if (($this->input[$this->currPos] ?? null) === "\x0a") {
1884    $this->currPos++;
1885    $r3 = "\x0a";
1886  } else {
1887    if (!$silence) {$this->fail(14);}
1888    $r3 = self::$FAILED;
1889  }
1890  $r1 = $r3;
1891  if ($r1!==self::$FAILED) {
1892    $this->savedPos = $p2;
1893    $r1 = $this->a7($r3);
1894  }
1895  return $r1;
1896}
1897
1898	public function parse( $input, $options = [] ) {
1899		$this->initInternal( $input, $options );
1900		$startRule = $options['startRule'] ?? '(DEFAULT)';
1901		$result = null;
1902
1903		if ( !empty( $options['stream'] ) ) {
1904			switch ( $startRule ) {
1905
1906			default:
1907				throw new \Wikimedia\WikiPEG\InternalError( "Can't stream rule $startRule." );
1908			}
1909		} else {
1910			switch ( $startRule ) {
1911				case '(DEFAULT)':
1912case "testfile":
1913  $result = $this->parsetestfile(false);
1914  break;
1915			default:
1916				throw new \Wikimedia\WikiPEG\InternalError( "Can't start parsing from rule $startRule." );
1917			}
1918		}
1919
1920		if ( $result !== self::$FAILED && $this->currPos === $this->inputLength ) {
1921			return $result;
1922		} else {
1923			if ( $result !== self::$FAILED && $this->currPos < $this->inputLength ) {
1924				$this->fail( 0 );
1925			}
1926			throw $this->buildParseException();
1927		}
1928	}
1929}
1930
1931