Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 1508
0.00% covered (danger)
0.00%
0 / 89
CRAP
0.00% covered (danger)
0.00%
0 / 1
Grammar
0.00% covered (danger)
0.00%
0 / 1508
0.00% covered (danger)
0.00%
0 / 89
261632
0.00% covered (danger)
0.00%
0 / 1
 load
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 addLines
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 a0
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a2
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a3
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a4
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a5
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a6
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a7
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a8
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 a9
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a10
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 a11
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 a12
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
72
 a13
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a14
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a15
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a16
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a17
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a18
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a19
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a20
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 a21
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 a22
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 a23
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a24
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 a25
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a26
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 a27
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a28
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a29
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a30
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a31
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a32
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a33
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 a34
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 a35
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 parsetestfile
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
132
 parsecomment_or_blank_line
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
30
 parseformat
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 1
272
 parsetestfile_options
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
30
 parselined_chunk
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
20
 parsecomment
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
30
 discardwhitespace
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 parseeol
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
 discardversion_keyword
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 discardrest_of_line
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
56
 parseoption_section
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
156
 discardend_section
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 parsechunk
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
56
 parserest_of_line
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
56
 discardeol
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
 parseoption_list
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 parsearticle
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
72
 parsetest
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
90
 parsehooks
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
42
 parsefunctionhooks
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
42
 parseline
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
42
 parsean_option
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
 discardstart_article
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 discardstart_text
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 parsetext
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
 discardend_article
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 discardstart_test
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 parsesection
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 1
650
 parseconfig_section
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
156
 discardstart_hooks
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
156
 discardend_hooks
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 discardstart_functionhooks
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
156
 discardend_functionhooks
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
156
 parseoption_name
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
42
 parseoption_value
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
56
 parseconfig_list
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
56
 parseoption_value_list
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
90
 parsea_config_line
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
20
 parsean_option_value
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 parseconfig_value
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
56
 parselink_target_value
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
182
 parsequoted_value
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 1
272
 parseplain_value
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
42
 parsejson_value
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
156
 parsevalid_json_value
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
56
 discardquoted_value
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 1
272
 discardplain_value
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
42
 discardarray_value
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
156
 discardjson_value
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
156
 parsearray_value
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 1
156
 parse
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
110
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
16
17
18class Grammar extends \Wikimedia\WikiPEG\PEGParserBase {
19    // initializer
20    
21    /** @var string */
22    private $filename = '';
23    /** @var int */
24    private $lineNum = 1;
25
26    /**
27     * @param string $filename
28     * @return array
29     */
30    public static function load( string $filename ) {
31        $g = new Grammar();
32        $g->filename = $filename;
33        $contents = file_get_contents( $filename ) ?: '';
34        if ( substr( $contents, -1 ) !== "\n" ) {
35            # ensure that the file is terminated with a newline
36            # to match `end_section` rule (and other uses of `eol`)
37            $contents .= "\n";
38        }
39        return $g->parse( $contents );
40    }
41
42    private function addLines( int $lineStart, array $item ) {
43        $item['filename'] = $this->filename;
44        $item['lineNumStart'] = $lineStart;
45        $item['lineNumEnd'] = $this->lineNum;
46        return $item;
47    }
48
49
50    // cache init
51    
52
53    // expectations
54    protected $expectations = [
55        0 => ["type" => "end", "description" => "end of input"],
561 => ["type" => "literal", "value" => "!!", "description" => "\"!!\""],
572 => ["type" => "class", "value" => "[0-9]", "description" => "[0-9]"],
583 => ["type" => "literal", "value" => "#", "description" => "\"#\""],
594 => ["type" => "class", "value" => "[ \\t]", "description" => "[ \\t]"],
605 => ["type" => "literal", "value" => "\x0a", "description" => "\"\\n\""],
616 => ["type" => "literal", "value" => "version", "description" => "\"version\""],
627 => ["type" => "class", "value" => "[^\\n]", "description" => "[^\\n]"],
638 => ["type" => "literal", "value" => "options", "description" => "\"options\""],
649 => ["type" => "literal", "value" => "end", "description" => "\"end\""],
6510 => ["type" => "literal", "value" => "article", "description" => "\"article\""],
6611 => ["type" => "literal", "value" => "text", "description" => "\"text\""],
6712 => ["type" => "literal", "value" => "endarticle", "description" => "\"endarticle\""],
6813 => ["type" => "literal", "value" => "test", "description" => "\"test\""],
6914 => ["type" => "class", "value" => "[^ \\t\\r\\n]", "description" => "[^ \\t\\r\\n]"],
7015 => ["type" => "literal", "value" => "config", "description" => "\"config\""],
7116 => ["type" => "literal", "value" => "hooks", "description" => "\"hooks\""],
7217 => ["type" => "literal", "value" => ":", "description" => "\":\""],
7318 => ["type" => "literal", "value" => "endhooks", "description" => "\"endhooks\""],
7419 => ["type" => "literal", "value" => "functionhooks", "description" => "\"functionhooks\""],
7520 => ["type" => "literal", "value" => "endfunctionhooks", "description" => "\"endfunctionhooks\""],
7621 => ["type" => "class", "value" => "[^ \\t\\n=!]", "description" => "[^ \\t\\n=!]"],
7722 => ["type" => "literal", "value" => "=", "description" => "\"=\""],
7823 => ["type" => "literal", "value" => ",", "description" => "\",\""],
7924 => ["type" => "literal", "value" => "[[", "description" => "\"[[\""],
8025 => ["type" => "class", "value" => "[^\\]\\n]", "description" => "[^\\]\\n]"],
8126 => ["type" => "literal", "value" => "]]", "description" => "\"]]\""],
8227 => ["type" => "class", "value" => "[\\\"]", "description" => "[\\\"]"],
8328 => ["type" => "class", "value" => "[^\\\\\\\"\\n]", "description" => "[^\\\\\\\"\\n]"],
8429 => ["type" => "literal", "value" => "\\", "description" => "\"\\\\\""],
8530 => ["type" => "class", "value" => "[^ \\t\\n\\\"\\'\\[\\]=,!\\{]", "description" => "[^ \\t\\n\\\"\\'\\[\\]=,!\\{]"],
8631 => ["type" => "literal", "value" => "{", "description" => "\"{\""],
8732 => ["type" => "class", "value" => "[^\\\"\\{\\}\\n]", "description" => "[^\\\"\\{\\}\\n]"],
8833 => ["type" => "literal", "value" => "}", "description" => "\"}\""],
8934 => ["type" => "literal", "value" => "[", "description" => "\"[\""],
9035 => ["type" => "class", "value" => "[^\\\"\\[\\]\\n]", "description" => "[^\\\"\\[\\]\\n]"],
9136 => ["type" => "literal", "value" => "]", "description" => "\"]\""],
92    ];
93
94    // actions
95    private function a0($nl) {
96 return [ 'type' => 'line', 'text' => $nl ]; 
97}
98private function a1() {
99 return $this->lineNum; 
100}
101private function a2($l, $v) {
102
103        return $this->addLines( $l, [ 'type' => 'version', 'text' => $v ] );
104    
105}
106private function a3($l, $sec) {
107
108    return $this->addLines( $l, $sec );
109
110}
111private function a4($l, $c) {
112
113    return $this->addLines($l, $c);
114
115}
116private function a5($text) {
117 return [ 'type' => 'comment', 'text' => $text ]; 
118}
119private function a6($nl) {
120 $this->lineNum++; return $nl; 
121}
122private function a7($c) {
123
124    return implode($c);
125
126}
127private function a8($opts) {
128
129    $o = [];
130    if ( $opts && count($opts) > 0 ) {
131        foreach ( $opts as $opt ) {
132            $o[$opt['k']] = $opt['v'];
133        }
134    }
135
136    return [ 'type' => 'section', 'name' => 'options', 'text' => $o ];
137
138}
139private function a9($l) {
140 return [ 'type' => 'line', 'text' => $l ]; 
141}
142private function a10($o, $rest) {
143
144    $result = [ $o ];
145    if ( $rest && count( $rest ) > 0 ) {
146        $result = array_merge( $result, $rest );
147    }
148    return $result;
149
150}
151private function a11($title, $text) {
152
153    return [
154        'type' => 'article',
155        'title' => $title,
156        'text' => $text
157    ];
158
159}
160private function a12($testName, $sections) {
161
162    $test = [
163        'type' => 'test',
164        'testName' => $testName
165    ];
166
167    foreach ( $sections as $section ) {
168        $test[$section['name']] = $section['text'];
169    }
170    // pegjs parser handles item options as follows:
171    //   item option             value of item.options.parsoid
172    //    <none>                          undefined
173    //    parsoid                             ""
174    //    parsoid=wt2html                  "wt2html"
175    //    parsoid=wt2html,wt2wt        ["wt2html","wt2wt"]
176    //    parsoid={"modes":["wt2wt"]}    {modes:['wt2wt']}
177
178    // treat 'parsoid=xxx,yyy' in options section as shorthand for
179    // 'parsoid={modes:["xxx","yyy"]}'
180    if ( isset($test['options']['parsoid'] ) ) {
181        if ($test['options']['parsoid'] === '') {
182            $test['options']['parsoid'] = [];
183        }
184        if ( is_string( $test['options']['parsoid'] ) ) {
185            $test['options']['parsoid'] = [ $test['options']['parsoid'] ];
186        }
187        if ( is_array( $test['options']['parsoid'] ) &&
188            isset( $test['options']['parsoid'][0] ) &&
189            !isset( $test['options']['parsoid']['modes'] )
190        ) {
191            $test['options']['parsoid'] = [ 'modes' => $test['options']['parsoid'] ];
192        }
193    }
194    return $test;
195
196}
197private function a13($text) {
198
199    return [ 'type' => 'hooks', 'text' => $text ];
200
201}
202private function a14($text) {
203
204    return [ 'type' => 'functionhooks', 'text' => $text ];
205
206}
207private function a15($line) {
208
209    return $line;
210
211}
212private function a16($k, $v) {
213
214    return [ 'k' => strtolower( $k ), 'v' => $v ?? '' ];
215
216}
217private function a17($lines) {
218
219    return implode("\n", $lines);
220
221}
222private function a18($c) {
223 return implode( $c ); 
224}
225private function a19($name, $text) {
226
227    return [ 'name' => $name, 'text' => $text ];
228
229}
230private function a20($items) {
231
232    $c = [];
233    if ( $items && count($items) > 0 ) {
234        foreach ( $items as $item ) {
235            $c[$item['k']] = $item['v'];
236        }
237    }
238
239    return [ 'type' => 'section', 'name' => 'config', 'text' => $c ];
240
241}
242private function a21($ovl) {
243
244    return count( $ovl ) === 1 ? $ovl[0] : $ovl;
245
246}
247private function a22($c, $rest) {
248
249    $result = [ $c ];
250    if ( $rest && count( $rest ) > 0 ) {
251        $result = array_merge( $result, $rest );
252    }
253    return $result;
254
255}
256private function a23($v, $ovl) {
257 return $ovl; 
258}
259private function a24($v, $rest) {
260
261    $result = [ $v ];
262    if ( $rest && count( $rest ) > 0 ) {
263        $result = array_merge( $result, $rest );
264    }
265    return $result;
266
267}
268private function a25($k, $v) {
269
270    return [ 'k' => $k, 'v' => $v ];
271
272}
273private function a26($v) {
274
275    if ( $v[0] === '"' || $v[0] === '{' ) { // } is needed to make pegjs happy
276        return PHPUtils::jsonDecode( $v );
277    }
278    return $v;
279
280}
281private function a27($v) {
282 return $v; 
283}
284private function a28($v) {
285
286    // Perhaps we should canonicalize the title?
287    // Protect with JSON.stringify just in case the link target starts with
288    // double-quote or open-brace.
289    return PHPUtils::jsonEncode( implode( $v ) );
290
291}
292private function a29($c) {
293 return "\\" . $c; 
294}
295private function a30($v) {
296
297    return '"' . implode( $v ) . '"';
298
299}
300private function a31($v) {
301
302    return implode( $v );
303
304}
305private function a32($v) {
306
307    return "{" . implode( $v ) . "}";
308
309}
310private function a33($v) {
311
312  // validate this as acceptable JSON
313  // (this ensures that wikipeg throws a syntax error if
314  // the JSON is invalid; note that PHP 7.3 would allow us
315  // to use JSON_THROW_ON_ERROR instead of json_last_error()...)
316  $ignore = json_decode($v, true, 100);
317  return (json_last_error() === JSON_ERROR_NONE);
318
319}
320private function a34($v) {
321
322  // The value is valid JSON; return the decoded value.
323  return json_decode($v, true);
324
325}
326private function a35($v) {
327
328    return "[" . implode( $v ) . "]";
329
330}
331
332    // generated
333    private function parsetestfile($silence) {
334  // start seq_1
335  $p1 = $this->currPos;
336  $r3 = [];
337  for (;;) {
338    $r4 = $this->parsecomment_or_blank_line($silence);
339    if ($r4!==self::$FAILED) {
340      $r3[] = $r4;
341    } else {
342      break;
343    }
344  }
345  // free $r4
346  $r4 = $this->parseformat($silence);
347  if ($r4===self::$FAILED) {
348    $r4 = null;
349  }
350  $r5 = [];
351  for (;;) {
352    $r6 = $this->parsecomment_or_blank_line($silence);
353    if ($r6!==self::$FAILED) {
354      $r5[] = $r6;
355    } else {
356      break;
357    }
358  }
359  // free $r6
360  $r6 = $this->parsetestfile_options($silence);
361  if ($r6===self::$FAILED) {
362    $r6 = null;
363  }
364  $r7 = [];
365  for (;;) {
366    $r8 = $this->parselined_chunk($silence);
367    if ($r8!==self::$FAILED) {
368      $r7[] = $r8;
369    } else {
370      break;
371    }
372  }
373  if (count($r7) === 0) {
374    $r7 = self::$FAILED;
375  }
376  if ($r7===self::$FAILED) {
377    $this->currPos = $p1;
378    $r2 = self::$FAILED;
379    goto seq_1;
380  }
381  // free $r8
382  $r2 = [$r3,$r4,$r5,$r6,$r7];
383  seq_1:
384  // free $r2,$p1
385  return $r2;
386}
387private function parsecomment_or_blank_line($silence) {
388  // start choice_1
389  $r1 = $this->parsecomment($silence);
390  if ($r1!==self::$FAILED) {
391    goto choice_1;
392  }
393  $p2 = $this->currPos;
394  // start seq_1
395  $p3 = $this->currPos;
396  $r4 = $this->discardwhitespace($silence);
397  if ($r4===self::$FAILED) {
398    $r4 = null;
399  }
400  $r5 = $this->parseeol($silence);
401  // nl <- $r5
402  if ($r5===self::$FAILED) {
403    $this->currPos = $p3;
404    $r1 = self::$FAILED;
405    goto seq_1;
406  }
407  $r1 = true;
408  seq_1:
409  if ($r1!==self::$FAILED) {
410    $this->savedPos = $p2;
411    $r1 = $this->a0($r5);
412  }
413  // free $p3
414  choice_1:
415  return $r1;
416}
417private function parseformat($silence) {
418  $p2 = $this->currPos;
419  // start seq_1
420  $p3 = $this->currPos;
421  $p5 = $this->currPos;
422  $r4 = '';
423  // l <- $r4
424  if ($r4!==self::$FAILED) {
425    $this->savedPos = $p5;
426    $r4 = $this->a1();
427  } else {
428    $r1 = self::$FAILED;
429    goto seq_1;
430  }
431  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
432    $r6 = "!!";
433    $this->currPos += 2;
434  } else {
435    if (!$silence) {$this->fail(1);}
436    $r6 = self::$FAILED;
437    $this->currPos = $p3;
438    $r1 = self::$FAILED;
439    goto seq_1;
440  }
441  $r7 = $this->discardwhitespace($silence);
442  if ($r7===self::$FAILED) {
443    $r7 = null;
444  }
445  $r8 = $this->discardversion_keyword($silence);
446  if ($r8===self::$FAILED) {
447    $this->currPos = $p3;
448    $r1 = self::$FAILED;
449    goto seq_1;
450  }
451  $r9 = self::$FAILED;
452  for (;;) {
453    $r10 = $this->discardwhitespace($silence);
454    if ($r10!==self::$FAILED) {
455      $r9 = true;
456    } else {
457      break;
458    }
459  }
460  if ($r9===self::$FAILED) {
461    $this->currPos = $p3;
462    $r1 = self::$FAILED;
463    goto seq_1;
464  }
465  // free $r10
466  $p11 = $this->currPos;
467  $r10 = self::$FAILED;
468  for (;;) {
469    $r12 = $this->input[$this->currPos] ?? '';
470    if (preg_match("/^[0-9]/", $r12)) {
471      $this->currPos++;
472      $r10 = true;
473    } else {
474      $r12 = self::$FAILED;
475      if (!$silence) {$this->fail(2);}
476      break;
477    }
478  }
479  // v <- $r10
480  if ($r10!==self::$FAILED) {
481    $r10 = substr($this->input, $p11, $this->currPos - $p11);
482  } else {
483    $r10 = self::$FAILED;
484    $this->currPos = $p3;
485    $r1 = self::$FAILED;
486    goto seq_1;
487  }
488  // free $r12
489  // free $p11
490  $r12 = $this->discardrest_of_line($silence);
491  if ($r12===self::$FAILED) {
492    $this->currPos = $p3;
493    $r1 = self::$FAILED;
494    goto seq_1;
495  }
496  $r1 = true;
497  seq_1:
498  if ($r1!==self::$FAILED) {
499    $this->savedPos = $p2;
500    $r1 = $this->a2($r4, $r10);
501  }
502  // free $p3
503  return $r1;
504}
505private function parsetestfile_options($silence) {
506  $p2 = $this->currPos;
507  // start seq_1
508  $p3 = $this->currPos;
509  $p5 = $this->currPos;
510  $r4 = '';
511  // l <- $r4
512  if ($r4!==self::$FAILED) {
513    $this->savedPos = $p5;
514    $r4 = $this->a1();
515  } else {
516    $r1 = self::$FAILED;
517    goto seq_1;
518  }
519  $r6 = $this->parseoption_section($silence);
520  // sec <- $r6
521  if ($r6===self::$FAILED) {
522    $this->currPos = $p3;
523    $r1 = self::$FAILED;
524    goto seq_1;
525  }
526  $r7 = $this->discardend_section($silence);
527  if ($r7===self::$FAILED) {
528    $this->currPos = $p3;
529    $r1 = self::$FAILED;
530    goto seq_1;
531  }
532  $r1 = true;
533  seq_1:
534  if ($r1!==self::$FAILED) {
535    $this->savedPos = $p2;
536    $r1 = $this->a3($r4, $r6);
537  }
538  // free $p3
539  return $r1;
540}
541private function parselined_chunk($silence) {
542  $p2 = $this->currPos;
543  // start seq_1
544  $p3 = $this->currPos;
545  $p5 = $this->currPos;
546  $r4 = '';
547  // l <- $r4
548  if ($r4!==self::$FAILED) {
549    $this->savedPos = $p5;
550    $r4 = $this->a1();
551  } else {
552    $r1 = self::$FAILED;
553    goto seq_1;
554  }
555  $r6 = $this->parsechunk($silence);
556  // c <- $r6
557  if ($r6===self::$FAILED) {
558    $this->currPos = $p3;
559    $r1 = self::$FAILED;
560    goto seq_1;
561  }
562  $r1 = true;
563  seq_1:
564  if ($r1!==self::$FAILED) {
565    $this->savedPos = $p2;
566    $r1 = $this->a4($r4, $r6);
567  }
568  // free $p3
569  return $r1;
570}
571private function parsecomment($silence) {
572  $p2 = $this->currPos;
573  // start seq_1
574  $p3 = $this->currPos;
575  if (($this->input[$this->currPos] ?? null) === "#") {
576    $this->currPos++;
577    $r4 = "#";
578  } else {
579    if (!$silence) {$this->fail(3);}
580    $r4 = self::$FAILED;
581    $r1 = self::$FAILED;
582    goto seq_1;
583  }
584  $r5 = $this->parserest_of_line($silence);
585  // text <- $r5
586  if ($r5===self::$FAILED) {
587    $this->currPos = $p3;
588    $r1 = self::$FAILED;
589    goto seq_1;
590  }
591  $r1 = true;
592  seq_1:
593  if ($r1!==self::$FAILED) {
594    $this->savedPos = $p2;
595    $r1 = $this->a5($r5);
596  }
597  // free $p3
598  return $r1;
599}
600private function discardwhitespace($silence) {
601  $r1 = self::$FAILED;
602  for (;;) {
603    $r2 = $this->input[$this->currPos] ?? '';
604    if ($r2 === " " || $r2 === "\x09") {
605      $this->currPos++;
606      $r1 = true;
607    } else {
608      $r2 = self::$FAILED;
609      if (!$silence) {$this->fail(4);}
610      break;
611    }
612  }
613  // free $r2
614  return $r1;
615}
616private function parseeol($silence) {
617  $p2 = $this->currPos;
618  // nl <- $r3
619  if (($this->input[$this->currPos] ?? null) === "\x0a") {
620    $this->currPos++;
621    $r3 = "\x0a";
622  } else {
623    if (!$silence) {$this->fail(5);}
624    $r3 = self::$FAILED;
625  }
626  $r1 = $r3;
627  if ($r1!==self::$FAILED) {
628    $this->savedPos = $p2;
629    $r1 = $this->a6($r3);
630  }
631  return $r1;
632}
633private function discardversion_keyword($silence) {
634  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "version", $this->currPos, 7, true) === 0) {
635    $r1 = substr($this->input, $this->currPos, 7);
636    $this->currPos += 7;
637  } else {
638    if (!$silence) {$this->fail(6);}
639    $r1 = self::$FAILED;
640  }
641  return $r1;
642}
643private function discardrest_of_line($silence) {
644  $p2 = $this->currPos;
645  // start seq_1
646  $p3 = $this->currPos;
647  $r4 = [];
648  for (;;) {
649    $r5 = self::charAt($this->input, $this->currPos);
650    if ($r5 !== '' && !($r5 === "\x0a")) {
651      $this->currPos += strlen($r5);
652      $r4[] = $r5;
653    } else {
654      $r5 = self::$FAILED;
655      if (!$silence) {$this->fail(7);}
656      break;
657    }
658  }
659  // c <- $r4
660  // free $r5
661  $r5 = $this->discardeol($silence);
662  if ($r5===self::$FAILED) {
663    $this->currPos = $p3;
664    $r1 = self::$FAILED;
665    goto seq_1;
666  }
667  $r1 = true;
668  seq_1:
669  if ($r1!==self::$FAILED) {
670    $this->savedPos = $p2;
671    $r1 = $this->a7($r4);
672  }
673  // free $p3
674  return $r1;
675}
676private function parseoption_section($silence) {
677  $p2 = $this->currPos;
678  // start seq_1
679  $p3 = $this->currPos;
680  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
681    $r4 = "!!";
682    $this->currPos += 2;
683  } else {
684    if (!$silence) {$this->fail(1);}
685    $r4 = self::$FAILED;
686    $r1 = self::$FAILED;
687    goto seq_1;
688  }
689  $r5 = $this->discardwhitespace($silence);
690  if ($r5===self::$FAILED) {
691    $r5 = null;
692  }
693  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "options", $this->currPos, 7, false) === 0) {
694    $r6 = "options";
695    $this->currPos += 7;
696  } else {
697    if (!$silence) {$this->fail(8);}
698    $r6 = self::$FAILED;
699    $this->currPos = $p3;
700    $r1 = self::$FAILED;
701    goto seq_1;
702  }
703  $r7 = $this->discardwhitespace($silence);
704  if ($r7===self::$FAILED) {
705    $r7 = null;
706  }
707  $r8 = $this->discardeol($silence);
708  if ($r8===self::$FAILED) {
709    $this->currPos = $p3;
710    $r1 = self::$FAILED;
711    goto seq_1;
712  }
713  $r9 = $this->parseoption_list($silence);
714  if ($r9===self::$FAILED) {
715    $r9 = null;
716  }
717  // opts <- $r9
718  $r1 = true;
719  seq_1:
720  if ($r1!==self::$FAILED) {
721    $this->savedPos = $p2;
722    $r1 = $this->a8($r9);
723  }
724  // free $p3
725  return $r1;
726}
727private function discardend_section($silence) {
728  // start seq_1
729  $p1 = $this->currPos;
730  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
731    $r3 = "!!";
732    $this->currPos += 2;
733  } else {
734    if (!$silence) {$this->fail(1);}
735    $r3 = self::$FAILED;
736    $r2 = self::$FAILED;
737    goto seq_1;
738  }
739  $r4 = $this->discardwhitespace($silence);
740  if ($r4===self::$FAILED) {
741    $r4 = null;
742  }
743  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "end", $this->currPos, 3, false) === 0) {
744    $r5 = "end";
745    $this->currPos += 3;
746  } else {
747    if (!$silence) {$this->fail(9);}
748    $r5 = self::$FAILED;
749    $this->currPos = $p1;
750    $r2 = self::$FAILED;
751    goto seq_1;
752  }
753  $r6 = $this->discardwhitespace($silence);
754  if ($r6===self::$FAILED) {
755    $r6 = null;
756  }
757  $r7 = $this->discardeol($silence);
758  if ($r7===self::$FAILED) {
759    $this->currPos = $p1;
760    $r2 = self::$FAILED;
761    goto seq_1;
762  }
763  $r2 = true;
764  seq_1:
765  // free $r2,$p1
766  return $r2;
767}
768private function parsechunk($silence) {
769  // start choice_1
770  $r1 = $this->parsecomment_or_blank_line($silence);
771  if ($r1!==self::$FAILED) {
772    goto choice_1;
773  }
774  $r1 = $this->parsearticle($silence);
775  if ($r1!==self::$FAILED) {
776    goto choice_1;
777  }
778  $r1 = $this->parsetest($silence);
779  if ($r1!==self::$FAILED) {
780    goto choice_1;
781  }
782  $r1 = $this->parsehooks($silence);
783  if ($r1!==self::$FAILED) {
784    goto choice_1;
785  }
786  $r1 = $this->parsefunctionhooks($silence);
787  if ($r1!==self::$FAILED) {
788    goto choice_1;
789  }
790  $p2 = $this->currPos;
791  $r3 = $this->parseline($silence);
792  // l <- $r3
793  $r1 = $r3;
794  if ($r1!==self::$FAILED) {
795    $this->savedPos = $p2;
796    $r1 = $this->a9($r3);
797  }
798  choice_1:
799  return $r1;
800}
801private function parserest_of_line($silence) {
802  $p2 = $this->currPos;
803  // start seq_1
804  $p3 = $this->currPos;
805  $r4 = [];
806  for (;;) {
807    $r5 = self::charAt($this->input, $this->currPos);
808    if ($r5 !== '' && !($r5 === "\x0a")) {
809      $this->currPos += strlen($r5);
810      $r4[] = $r5;
811    } else {
812      $r5 = self::$FAILED;
813      if (!$silence) {$this->fail(7);}
814      break;
815    }
816  }
817  // c <- $r4
818  // free $r5
819  $r5 = $this->discardeol($silence);
820  if ($r5===self::$FAILED) {
821    $this->currPos = $p3;
822    $r1 = self::$FAILED;
823    goto seq_1;
824  }
825  $r1 = true;
826  seq_1:
827  if ($r1!==self::$FAILED) {
828    $this->savedPos = $p2;
829    $r1 = $this->a7($r4);
830  }
831  // free $p3
832  return $r1;
833}
834private function discardeol($silence) {
835  $p2 = $this->currPos;
836  // nl <- $r3
837  if (($this->input[$this->currPos] ?? null) === "\x0a") {
838    $this->currPos++;
839    $r3 = "\x0a";
840  } else {
841    if (!$silence) {$this->fail(5);}
842    $r3 = self::$FAILED;
843  }
844  $r1 = $r3;
845  if ($r1!==self::$FAILED) {
846    $this->savedPos = $p2;
847    $r1 = $this->a6($r3);
848  }
849  return $r1;
850}
851private function parseoption_list($silence) {
852  $p2 = $this->currPos;
853  // start seq_1
854  $p3 = $this->currPos;
855  $r4 = $this->parsean_option($silence);
856  // o <- $r4
857  if ($r4===self::$FAILED) {
858    $r1 = self::$FAILED;
859    goto seq_1;
860  }
861  $r5 = self::$FAILED;
862  for (;;) {
863    // start choice_1
864    $r6 = $this->input[$this->currPos] ?? '';
865    if ($r6 === " " || $r6 === "\x09") {
866      $this->currPos++;
867      goto choice_1;
868    } else {
869      $r6 = self::$FAILED;
870      if (!$silence) {$this->fail(4);}
871    }
872    $r6 = $this->discardeol($silence);
873    choice_1:
874    if ($r6!==self::$FAILED) {
875      $r5 = true;
876    } else {
877      break;
878    }
879  }
880  if ($r5===self::$FAILED) {
881    $this->currPos = $p3;
882    $r1 = self::$FAILED;
883    goto seq_1;
884  }
885  // free $r6
886  $r6 = $this->parseoption_list($silence);
887  if ($r6===self::$FAILED) {
888    $r6 = null;
889  }
890  // rest <- $r6
891  $r1 = true;
892  seq_1:
893  if ($r1!==self::$FAILED) {
894    $this->savedPos = $p2;
895    $r1 = $this->a10($r4, $r6);
896  }
897  // free $p3
898  return $r1;
899}
900private function parsearticle($silence) {
901  $p2 = $this->currPos;
902  // start seq_1
903  $p3 = $this->currPos;
904  $r4 = $this->discardstart_article($silence);
905  if ($r4===self::$FAILED) {
906    $r1 = self::$FAILED;
907    goto seq_1;
908  }
909  $r5 = $this->parseline($silence);
910  // title <- $r5
911  if ($r5===self::$FAILED) {
912    $this->currPos = $p3;
913    $r1 = self::$FAILED;
914    goto seq_1;
915  }
916  $r6 = $this->discardstart_text($silence);
917  if ($r6===self::$FAILED) {
918    $this->currPos = $p3;
919    $r1 = self::$FAILED;
920    goto seq_1;
921  }
922  $r7 = $this->parsetext($silence);
923  // text <- $r7
924  if ($r7===self::$FAILED) {
925    $this->currPos = $p3;
926    $r1 = self::$FAILED;
927    goto seq_1;
928  }
929  // start choice_1
930  $r8 = $this->discardend_article($silence);
931  if ($r8!==self::$FAILED) {
932    goto choice_1;
933  }
934  $r8 = $this->discardend_section($silence);
935  choice_1:
936  if ($r8===self::$FAILED) {
937    $this->currPos = $p3;
938    $r1 = self::$FAILED;
939    goto seq_1;
940  }
941  $r1 = true;
942  seq_1:
943  if ($r1!==self::$FAILED) {
944    $this->savedPos = $p2;
945    $r1 = $this->a11($r5, $r7);
946  }
947  // free $p3
948  return $r1;
949}
950private function parsetest($silence) {
951  $p2 = $this->currPos;
952  // start seq_1
953  $p3 = $this->currPos;
954  $r4 = $this->discardstart_test($silence);
955  if ($r4===self::$FAILED) {
956    $r1 = self::$FAILED;
957    goto seq_1;
958  }
959  $r5 = $this->parsetext($silence);
960  // testName <- $r5
961  if ($r5===self::$FAILED) {
962    $this->currPos = $p3;
963    $r1 = self::$FAILED;
964    goto seq_1;
965  }
966  $r6 = [];
967  for (;;) {
968    // start choice_1
969    $r7 = $this->parsesection($silence);
970    if ($r7!==self::$FAILED) {
971      goto choice_1;
972    }
973    $r7 = $this->parseconfig_section($silence);
974    if ($r7!==self::$FAILED) {
975      goto choice_1;
976    }
977    $r7 = $this->parseoption_section($silence);
978    choice_1:
979    if ($r7!==self::$FAILED) {
980      $r6[] = $r7;
981    } else {
982      break;
983    }
984  }
985  // sections <- $r6
986  // free $r7
987  $r7 = $this->discardend_section($silence);
988  if ($r7===self::$FAILED) {
989    $this->currPos = $p3;
990    $r1 = self::$FAILED;
991    goto seq_1;
992  }
993  $r1 = true;
994  seq_1:
995  if ($r1!==self::$FAILED) {
996    $this->savedPos = $p2;
997    $r1 = $this->a12($r5, $r6);
998  }
999  // free $p3
1000  return $r1;
1001}
1002private function parsehooks($silence) {
1003  $p2 = $this->currPos;
1004  // start seq_1
1005  $p3 = $this->currPos;
1006  $r4 = $this->discardstart_hooks($silence);
1007  if ($r4===self::$FAILED) {
1008    $r1 = self::$FAILED;
1009    goto seq_1;
1010  }
1011  $r5 = $this->parsetext($silence);
1012  // text <- $r5
1013  if ($r5===self::$FAILED) {
1014    $this->currPos = $p3;
1015    $r1 = self::$FAILED;
1016    goto seq_1;
1017  }
1018  // start choice_1
1019  $r6 = $this->discardend_hooks($silence);
1020  if ($r6!==self::$FAILED) {
1021    goto choice_1;
1022  }
1023  $r6 = $this->discardend_section($silence);
1024  choice_1:
1025  if ($r6===self::$FAILED) {
1026    $this->currPos = $p3;
1027    $r1 = self::$FAILED;
1028    goto seq_1;
1029  }
1030  $r1 = true;
1031  seq_1:
1032  if ($r1!==self::$FAILED) {
1033    $this->savedPos = $p2;
1034    $r1 = $this->a13($r5);
1035  }
1036  // free $p3
1037  return $r1;
1038}
1039private function parsefunctionhooks($silence) {
1040  $p2 = $this->currPos;
1041  // start seq_1
1042  $p3 = $this->currPos;
1043  $r4 = $this->discardstart_functionhooks($silence);
1044  if ($r4===self::$FAILED) {
1045    $r1 = self::$FAILED;
1046    goto seq_1;
1047  }
1048  $r5 = $this->parsetext($silence);
1049  // text <- $r5
1050  if ($r5===self::$FAILED) {
1051    $this->currPos = $p3;
1052    $r1 = self::$FAILED;
1053    goto seq_1;
1054  }
1055  // start choice_1
1056  $r6 = $this->discardend_functionhooks($silence);
1057  if ($r6!==self::$FAILED) {
1058    goto choice_1;
1059  }
1060  $r6 = $this->discardend_section($silence);
1061  choice_1:
1062  if ($r6===self::$FAILED) {
1063    $this->currPos = $p3;
1064    $r1 = self::$FAILED;
1065    goto seq_1;
1066  }
1067  $r1 = true;
1068  seq_1:
1069  if ($r1!==self::$FAILED) {
1070    $this->savedPos = $p2;
1071    $r1 = $this->a14($r5);
1072  }
1073  // free $p3
1074  return $r1;
1075}
1076private function parseline($silence) {
1077  $p2 = $this->currPos;
1078  // start seq_1
1079  $p3 = $this->currPos;
1080  $p4 = $this->currPos;
1081  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1082    $r5 = "!!";
1083    $this->currPos += 2;
1084  } else {
1085    $r5 = self::$FAILED;
1086  }
1087  if ($r5 === self::$FAILED) {
1088    $r5 = false;
1089  } else {
1090    $r5 = self::$FAILED;
1091    $this->currPos = $p4;
1092    $r1 = self::$FAILED;
1093    goto seq_1;
1094  }
1095  // free $p4
1096  $r6 = $this->parserest_of_line($silence);
1097  // line <- $r6
1098  if ($r6===self::$FAILED) {
1099    $this->currPos = $p3;
1100    $r1 = self::$FAILED;
1101    goto seq_1;
1102  }
1103  $r1 = true;
1104  seq_1:
1105  if ($r1!==self::$FAILED) {
1106    $this->savedPos = $p2;
1107    $r1 = $this->a15($r6);
1108  }
1109  // free $p3
1110  return $r1;
1111}
1112private function parsean_option($silence) {
1113  $p2 = $this->currPos;
1114  // start seq_1
1115  $p3 = $this->currPos;
1116  $r4 = $this->parseoption_name($silence);
1117  // k <- $r4
1118  if ($r4===self::$FAILED) {
1119    $r1 = self::$FAILED;
1120    goto seq_1;
1121  }
1122  $r5 = $this->parseoption_value($silence);
1123  if ($r5===self::$FAILED) {
1124    $r5 = null;
1125  }
1126  // v <- $r5
1127  $r1 = true;
1128  seq_1:
1129  if ($r1!==self::$FAILED) {
1130    $this->savedPos = $p2;
1131    $r1 = $this->a16($r4, $r5);
1132  }
1133  // free $p3
1134  return $r1;
1135}
1136private function discardstart_article($silence) {
1137  // start seq_1
1138  $p1 = $this->currPos;
1139  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1140    $r3 = "!!";
1141    $this->currPos += 2;
1142  } else {
1143    if (!$silence) {$this->fail(1);}
1144    $r3 = self::$FAILED;
1145    $r2 = self::$FAILED;
1146    goto seq_1;
1147  }
1148  $r4 = $this->discardwhitespace($silence);
1149  if ($r4===self::$FAILED) {
1150    $r4 = null;
1151  }
1152  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "article", $this->currPos, 7, false) === 0) {
1153    $r5 = "article";
1154    $this->currPos += 7;
1155  } else {
1156    if (!$silence) {$this->fail(10);}
1157    $r5 = self::$FAILED;
1158    $this->currPos = $p1;
1159    $r2 = self::$FAILED;
1160    goto seq_1;
1161  }
1162  $r6 = $this->discardwhitespace($silence);
1163  if ($r6===self::$FAILED) {
1164    $r6 = null;
1165  }
1166  $r7 = $this->discardeol($silence);
1167  if ($r7===self::$FAILED) {
1168    $this->currPos = $p1;
1169    $r2 = self::$FAILED;
1170    goto seq_1;
1171  }
1172  $r2 = true;
1173  seq_1:
1174  // free $r2,$p1
1175  return $r2;
1176}
1177private function discardstart_text($silence) {
1178  // start seq_1
1179  $p1 = $this->currPos;
1180  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1181    $r3 = "!!";
1182    $this->currPos += 2;
1183  } else {
1184    if (!$silence) {$this->fail(1);}
1185    $r3 = self::$FAILED;
1186    $r2 = self::$FAILED;
1187    goto seq_1;
1188  }
1189  $r4 = $this->discardwhitespace($silence);
1190  if ($r4===self::$FAILED) {
1191    $r4 = null;
1192  }
1193  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "text", $this->currPos, 4, false) === 0) {
1194    $r5 = "text";
1195    $this->currPos += 4;
1196  } else {
1197    if (!$silence) {$this->fail(11);}
1198    $r5 = self::$FAILED;
1199    $this->currPos = $p1;
1200    $r2 = self::$FAILED;
1201    goto seq_1;
1202  }
1203  $r6 = $this->discardwhitespace($silence);
1204  if ($r6===self::$FAILED) {
1205    $r6 = null;
1206  }
1207  $r7 = $this->discardeol($silence);
1208  if ($r7===self::$FAILED) {
1209    $this->currPos = $p1;
1210    $r2 = self::$FAILED;
1211    goto seq_1;
1212  }
1213  $r2 = true;
1214  seq_1:
1215  // free $r2,$p1
1216  return $r2;
1217}
1218private function parsetext($silence) {
1219  $p2 = $this->currPos;
1220  $r3 = [];
1221  for (;;) {
1222    $r4 = $this->parseline($silence);
1223    if ($r4!==self::$FAILED) {
1224      $r3[] = $r4;
1225    } else {
1226      break;
1227    }
1228  }
1229  // lines <- $r3
1230  // free $r4
1231  $r1 = $r3;
1232  if ($r1!==self::$FAILED) {
1233    $this->savedPos = $p2;
1234    $r1 = $this->a17($r3);
1235  }
1236  return $r1;
1237}
1238private function discardend_article($silence) {
1239  // start seq_1
1240  $p1 = $this->currPos;
1241  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1242    $r3 = "!!";
1243    $this->currPos += 2;
1244  } else {
1245    if (!$silence) {$this->fail(1);}
1246    $r3 = self::$FAILED;
1247    $r2 = self::$FAILED;
1248    goto seq_1;
1249  }
1250  $r4 = $this->discardwhitespace($silence);
1251  if ($r4===self::$FAILED) {
1252    $r4 = null;
1253  }
1254  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "endarticle", $this->currPos, 10, false) === 0) {
1255    $r5 = "endarticle";
1256    $this->currPos += 10;
1257  } else {
1258    if (!$silence) {$this->fail(12);}
1259    $r5 = self::$FAILED;
1260    $this->currPos = $p1;
1261    $r2 = self::$FAILED;
1262    goto seq_1;
1263  }
1264  $r6 = $this->discardwhitespace($silence);
1265  if ($r6===self::$FAILED) {
1266    $r6 = null;
1267  }
1268  $r7 = $this->discardeol($silence);
1269  if ($r7===self::$FAILED) {
1270    $this->currPos = $p1;
1271    $r2 = self::$FAILED;
1272    goto seq_1;
1273  }
1274  $r2 = true;
1275  seq_1:
1276  // free $r2,$p1
1277  return $r2;
1278}
1279private function discardstart_test($silence) {
1280  // start seq_1
1281  $p1 = $this->currPos;
1282  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1283    $r3 = "!!";
1284    $this->currPos += 2;
1285  } else {
1286    if (!$silence) {$this->fail(1);}
1287    $r3 = self::$FAILED;
1288    $r2 = self::$FAILED;
1289    goto seq_1;
1290  }
1291  $r4 = $this->discardwhitespace($silence);
1292  if ($r4===self::$FAILED) {
1293    $r4 = null;
1294  }
1295  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "test", $this->currPos, 4, false) === 0) {
1296    $r5 = "test";
1297    $this->currPos += 4;
1298  } else {
1299    if (!$silence) {$this->fail(13);}
1300    $r5 = self::$FAILED;
1301    $this->currPos = $p1;
1302    $r2 = self::$FAILED;
1303    goto seq_1;
1304  }
1305  $r6 = $this->discardwhitespace($silence);
1306  if ($r6===self::$FAILED) {
1307    $r6 = null;
1308  }
1309  $r7 = $this->discardeol($silence);
1310  if ($r7===self::$FAILED) {
1311    $this->currPos = $p1;
1312    $r2 = self::$FAILED;
1313    goto seq_1;
1314  }
1315  $r2 = true;
1316  seq_1:
1317  // free $r2,$p1
1318  return $r2;
1319}
1320private function parsesection($silence) {
1321  $p2 = $this->currPos;
1322  // start seq_1
1323  $p3 = $this->currPos;
1324  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1325    $r4 = "!!";
1326    $this->currPos += 2;
1327  } else {
1328    if (!$silence) {$this->fail(1);}
1329    $r4 = self::$FAILED;
1330    $r1 = self::$FAILED;
1331    goto seq_1;
1332  }
1333  $r5 = $this->discardwhitespace($silence);
1334  if ($r5===self::$FAILED) {
1335    $r5 = null;
1336  }
1337  $p6 = $this->currPos;
1338  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "test", $this->currPos, 4, false) === 0) {
1339    $r7 = "test";
1340    $this->currPos += 4;
1341  } else {
1342    $r7 = self::$FAILED;
1343  }
1344  if ($r7 === self::$FAILED) {
1345    $r7 = false;
1346  } else {
1347    $r7 = self::$FAILED;
1348    $this->currPos = $p6;
1349    $this->currPos = $p3;
1350    $r1 = self::$FAILED;
1351    goto seq_1;
1352  }
1353  // free $p6
1354  $p6 = $this->currPos;
1355  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "end", $this->currPos, 3, false) === 0) {
1356    $r8 = "end";
1357    $this->currPos += 3;
1358  } else {
1359    $r8 = self::$FAILED;
1360  }
1361  if ($r8 === self::$FAILED) {
1362    $r8 = false;
1363  } else {
1364    $r8 = self::$FAILED;
1365    $this->currPos = $p6;
1366    $this->currPos = $p3;
1367    $r1 = self::$FAILED;
1368    goto seq_1;
1369  }
1370  // free $p6
1371  $p6 = $this->currPos;
1372  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "options", $this->currPos, 7, false) === 0) {
1373    $r9 = "options";
1374    $this->currPos += 7;
1375  } else {
1376    $r9 = self::$FAILED;
1377  }
1378  if ($r9 === self::$FAILED) {
1379    $r9 = false;
1380  } else {
1381    $r9 = self::$FAILED;
1382    $this->currPos = $p6;
1383    $this->currPos = $p3;
1384    $r1 = self::$FAILED;
1385    goto seq_1;
1386  }
1387  // free $p6
1388  $p6 = $this->currPos;
1389  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "config", $this->currPos, 6, false) === 0) {
1390    $r10 = "config";
1391    $this->currPos += 6;
1392  } else {
1393    $r10 = self::$FAILED;
1394  }
1395  if ($r10 === self::$FAILED) {
1396    $r10 = false;
1397  } else {
1398    $r10 = self::$FAILED;
1399    $this->currPos = $p6;
1400    $this->currPos = $p3;
1401    $r1 = self::$FAILED;
1402    goto seq_1;
1403  }
1404  // free $p6
1405  $p6 = $this->currPos;
1406  $r12 = [];
1407  for (;;) {
1408    if (strcspn($this->input, " \x09\x0d\x0a", $this->currPos, 1) !== 0) {
1409      $r13 = self::consumeChar($this->input, $this->currPos);
1410      $r12[] = $r13;
1411    } else {
1412      $r13 = self::$FAILED;
1413      if (!$silence) {$this->fail(14);}
1414      break;
1415    }
1416  }
1417  if (count($r12) === 0) {
1418    $r12 = self::$FAILED;
1419  }
1420  // c <- $r12
1421  // free $r13
1422  $r11 = $r12;
1423  // name <- $r11
1424  if ($r11!==self::$FAILED) {
1425    $this->savedPos = $p6;
1426    $r11 = $this->a18($r12);
1427  } else {
1428    $this->currPos = $p3;
1429    $r1 = self::$FAILED;
1430    goto seq_1;
1431  }
1432  $r13 = $this->discardrest_of_line($silence);
1433  if ($r13===self::$FAILED) {
1434    $this->currPos = $p3;
1435    $r1 = self::$FAILED;
1436    goto seq_1;
1437  }
1438  $r14 = $this->parsetext($silence);
1439  // text <- $r14
1440  if ($r14===self::$FAILED) {
1441    $this->currPos = $p3;
1442    $r1 = self::$FAILED;
1443    goto seq_1;
1444  }
1445  $r1 = true;
1446  seq_1:
1447  if ($r1!==self::$FAILED) {
1448    $this->savedPos = $p2;
1449    $r1 = $this->a19($r11, $r14);
1450  }
1451  // free $p3
1452  return $r1;
1453}
1454private function parseconfig_section($silence) {
1455  $p2 = $this->currPos;
1456  // start seq_1
1457  $p3 = $this->currPos;
1458  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1459    $r4 = "!!";
1460    $this->currPos += 2;
1461  } else {
1462    if (!$silence) {$this->fail(1);}
1463    $r4 = self::$FAILED;
1464    $r1 = self::$FAILED;
1465    goto seq_1;
1466  }
1467  $r5 = $this->discardwhitespace($silence);
1468  if ($r5===self::$FAILED) {
1469    $r5 = null;
1470  }
1471  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "config", $this->currPos, 6, false) === 0) {
1472    $r6 = "config";
1473    $this->currPos += 6;
1474  } else {
1475    if (!$silence) {$this->fail(15);}
1476    $r6 = self::$FAILED;
1477    $this->currPos = $p3;
1478    $r1 = self::$FAILED;
1479    goto seq_1;
1480  }
1481  $r7 = $this->discardwhitespace($silence);
1482  if ($r7===self::$FAILED) {
1483    $r7 = null;
1484  }
1485  $r8 = $this->discardeol($silence);
1486  if ($r8===self::$FAILED) {
1487    $this->currPos = $p3;
1488    $r1 = self::$FAILED;
1489    goto seq_1;
1490  }
1491  $r9 = $this->parseconfig_list($silence);
1492  if ($r9===self::$FAILED) {
1493    $r9 = null;
1494  }
1495  // items <- $r9
1496  $r1 = true;
1497  seq_1:
1498  if ($r1!==self::$FAILED) {
1499    $this->savedPos = $p2;
1500    $r1 = $this->a20($r9);
1501  }
1502  // free $p3
1503  return $r1;
1504}
1505private function discardstart_hooks($silence) {
1506  // start seq_1
1507  $p1 = $this->currPos;
1508  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1509    $r3 = "!!";
1510    $this->currPos += 2;
1511  } else {
1512    if (!$silence) {$this->fail(1);}
1513    $r3 = self::$FAILED;
1514    $r2 = self::$FAILED;
1515    goto seq_1;
1516  }
1517  $r4 = $this->discardwhitespace($silence);
1518  if ($r4===self::$FAILED) {
1519    $r4 = null;
1520  }
1521  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "hooks", $this->currPos, 5, false) === 0) {
1522    $r5 = "hooks";
1523    $this->currPos += 5;
1524  } else {
1525    if (!$silence) {$this->fail(16);}
1526    $r5 = self::$FAILED;
1527    $this->currPos = $p1;
1528    $r2 = self::$FAILED;
1529    goto seq_1;
1530  }
1531  if (($this->input[$this->currPos] ?? null) === ":") {
1532    $this->currPos++;
1533    $r6 = ":";
1534  } else {
1535    if (!$silence) {$this->fail(17);}
1536    $r6 = self::$FAILED;
1537    $r6 = null;
1538  }
1539  $r7 = $this->discardwhitespace($silence);
1540  if ($r7===self::$FAILED) {
1541    $r7 = null;
1542  }
1543  $r8 = $this->discardeol($silence);
1544  if ($r8===self::$FAILED) {
1545    $this->currPos = $p1;
1546    $r2 = self::$FAILED;
1547    goto seq_1;
1548  }
1549  $r2 = true;
1550  seq_1:
1551  // free $r2,$p1
1552  return $r2;
1553}
1554private function discardend_hooks($silence) {
1555  // start seq_1
1556  $p1 = $this->currPos;
1557  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1558    $r3 = "!!";
1559    $this->currPos += 2;
1560  } else {
1561    if (!$silence) {$this->fail(1);}
1562    $r3 = self::$FAILED;
1563    $r2 = self::$FAILED;
1564    goto seq_1;
1565  }
1566  $r4 = $this->discardwhitespace($silence);
1567  if ($r4===self::$FAILED) {
1568    $r4 = null;
1569  }
1570  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "endhooks", $this->currPos, 8, false) === 0) {
1571    $r5 = "endhooks";
1572    $this->currPos += 8;
1573  } else {
1574    if (!$silence) {$this->fail(18);}
1575    $r5 = self::$FAILED;
1576    $this->currPos = $p1;
1577    $r2 = self::$FAILED;
1578    goto seq_1;
1579  }
1580  $r6 = $this->discardwhitespace($silence);
1581  if ($r6===self::$FAILED) {
1582    $r6 = null;
1583  }
1584  $r7 = $this->discardeol($silence);
1585  if ($r7===self::$FAILED) {
1586    $this->currPos = $p1;
1587    $r2 = self::$FAILED;
1588    goto seq_1;
1589  }
1590  $r2 = true;
1591  seq_1:
1592  // free $r2,$p1
1593  return $r2;
1594}
1595private function discardstart_functionhooks($silence) {
1596  // start seq_1
1597  $p1 = $this->currPos;
1598  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1599    $r3 = "!!";
1600    $this->currPos += 2;
1601  } else {
1602    if (!$silence) {$this->fail(1);}
1603    $r3 = self::$FAILED;
1604    $r2 = self::$FAILED;
1605    goto seq_1;
1606  }
1607  $r4 = $this->discardwhitespace($silence);
1608  if ($r4===self::$FAILED) {
1609    $r4 = null;
1610  }
1611  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "functionhooks", $this->currPos, 13, false) === 0) {
1612    $r5 = "functionhooks";
1613    $this->currPos += 13;
1614  } else {
1615    if (!$silence) {$this->fail(19);}
1616    $r5 = self::$FAILED;
1617    $this->currPos = $p1;
1618    $r2 = self::$FAILED;
1619    goto seq_1;
1620  }
1621  if (($this->input[$this->currPos] ?? null) === ":") {
1622    $this->currPos++;
1623    $r6 = ":";
1624  } else {
1625    if (!$silence) {$this->fail(17);}
1626    $r6 = self::$FAILED;
1627    $r6 = null;
1628  }
1629  $r7 = $this->discardwhitespace($silence);
1630  if ($r7===self::$FAILED) {
1631    $r7 = null;
1632  }
1633  $r8 = $this->discardeol($silence);
1634  if ($r8===self::$FAILED) {
1635    $this->currPos = $p1;
1636    $r2 = self::$FAILED;
1637    goto seq_1;
1638  }
1639  $r2 = true;
1640  seq_1:
1641  // free $r2,$p1
1642  return $r2;
1643}
1644private function discardend_functionhooks($silence) {
1645  // start seq_1
1646  $p1 = $this->currPos;
1647  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "!!", $this->currPos, 2, false) === 0) {
1648    $r3 = "!!";
1649    $this->currPos += 2;
1650  } else {
1651    if (!$silence) {$this->fail(1);}
1652    $r3 = self::$FAILED;
1653    $r2 = self::$FAILED;
1654    goto seq_1;
1655  }
1656  $r4 = $this->discardwhitespace($silence);
1657  if ($r4===self::$FAILED) {
1658    $r4 = null;
1659  }
1660  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "endfunctionhooks", $this->currPos, 16, false) === 0) {
1661    $r5 = "endfunctionhooks";
1662    $this->currPos += 16;
1663  } else {
1664    if (!$silence) {$this->fail(20);}
1665    $r5 = self::$FAILED;
1666    $this->currPos = $p1;
1667    $r2 = self::$FAILED;
1668    goto seq_1;
1669  }
1670  if (($this->input[$this->currPos] ?? null) === ":") {
1671    $this->currPos++;
1672    $r6 = ":";
1673  } else {
1674    if (!$silence) {$this->fail(17);}
1675    $r6 = self::$FAILED;
1676    $r6 = null;
1677  }
1678  $r7 = $this->discardwhitespace($silence);
1679  if ($r7===self::$FAILED) {
1680    $r7 = null;
1681  }
1682  $r8 = $this->discardeol($silence);
1683  if ($r8===self::$FAILED) {
1684    $this->currPos = $p1;
1685    $r2 = self::$FAILED;
1686    goto seq_1;
1687  }
1688  $r2 = true;
1689  seq_1:
1690  // free $r2,$p1
1691  return $r2;
1692}
1693private function parseoption_name($silence) {
1694  $p2 = $this->currPos;
1695  $r3 = [];
1696  for (;;) {
1697    if (strcspn($this->input, " \x09\x0a=!", $this->currPos, 1) !== 0) {
1698      $r4 = self::consumeChar($this->input, $this->currPos);
1699      $r3[] = $r4;
1700    } else {
1701      $r4 = self::$FAILED;
1702      if (!$silence) {$this->fail(21);}
1703      break;
1704    }
1705  }
1706  if (count($r3) === 0) {
1707    $r3 = self::$FAILED;
1708  }
1709  // c <- $r3
1710  // free $r4
1711  $r1 = $r3;
1712  if ($r1!==self::$FAILED) {
1713    $this->savedPos = $p2;
1714    $r1 = $this->a7($r3);
1715  }
1716  return $r1;
1717}
1718private function parseoption_value($silence) {
1719  $p2 = $this->currPos;
1720  // start seq_1
1721  $p3 = $this->currPos;
1722  $r4 = $this->discardwhitespace($silence);
1723  if ($r4===self::$FAILED) {
1724    $r4 = null;
1725  }
1726  if (($this->input[$this->currPos] ?? null) === "=") {
1727    $this->currPos++;
1728    $r5 = "=";
1729  } else {
1730    if (!$silence) {$this->fail(22);}
1731    $r5 = self::$FAILED;
1732    $this->currPos = $p3;
1733    $r1 = self::$FAILED;
1734    goto seq_1;
1735  }
1736  $r6 = $this->discardwhitespace($silence);
1737  if ($r6===self::$FAILED) {
1738    $r6 = null;
1739  }
1740  $r7 = $this->parseoption_value_list($silence);
1741  // ovl <- $r7
1742  if ($r7===self::$FAILED) {
1743    $this->currPos = $p3;
1744    $r1 = self::$FAILED;
1745    goto seq_1;
1746  }
1747  $r1 = true;
1748  seq_1:
1749  if ($r1!==self::$FAILED) {
1750    $this->savedPos = $p2;
1751    $r1 = $this->a21($r7);
1752  }
1753  // free $p3
1754  return $r1;
1755}
1756private function parseconfig_list($silence) {
1757  $p2 = $this->currPos;
1758  // start seq_1
1759  $p3 = $this->currPos;
1760  $r4 = $this->parsea_config_line($silence);
1761  // c <- $r4
1762  if ($r4===self::$FAILED) {
1763    $r1 = self::$FAILED;
1764    goto seq_1;
1765  }
1766  $r5 = self::$FAILED;
1767  for (;;) {
1768    $r6 = $this->discardeol($silence);
1769    if ($r6!==self::$FAILED) {
1770      $r5 = true;
1771    } else {
1772      break;
1773    }
1774  }
1775  if ($r5===self::$FAILED) {
1776    $this->currPos = $p3;
1777    $r1 = self::$FAILED;
1778    goto seq_1;
1779  }
1780  // free $r6
1781  $r6 = $this->parseconfig_list($silence);
1782  if ($r6===self::$FAILED) {
1783    $r6 = null;
1784  }
1785  // rest <- $r6
1786  $r1 = true;
1787  seq_1:
1788  if ($r1!==self::$FAILED) {
1789    $this->savedPos = $p2;
1790    $r1 = $this->a22($r4, $r6);
1791  }
1792  // free $p3
1793  return $r1;
1794}
1795private function parseoption_value_list($silence) {
1796  $p2 = $this->currPos;
1797  // start seq_1
1798  $p3 = $this->currPos;
1799  $r4 = $this->parsean_option_value($silence);
1800  // v <- $r4
1801  if ($r4===self::$FAILED) {
1802    $r1 = self::$FAILED;
1803    goto seq_1;
1804  }
1805  $p6 = $this->currPos;
1806  // start seq_2
1807  $p7 = $this->currPos;
1808  $r8 = $this->discardwhitespace($silence);
1809  if ($r8===self::$FAILED) {
1810    $r8 = null;
1811  }
1812  if (($this->input[$this->currPos] ?? null) === ",") {
1813    $this->currPos++;
1814    $r9 = ",";
1815  } else {
1816    if (!$silence) {$this->fail(23);}
1817    $r9 = self::$FAILED;
1818    $this->currPos = $p7;
1819    $r5 = self::$FAILED;
1820    goto seq_2;
1821  }
1822  $r10 = $this->discardwhitespace($silence);
1823  if ($r10===self::$FAILED) {
1824    $r10 = null;
1825  }
1826  $r11 = $this->parseoption_value_list($silence);
1827  // ovl <- $r11
1828  if ($r11===self::$FAILED) {
1829    $this->currPos = $p7;
1830    $r5 = self::$FAILED;
1831    goto seq_2;
1832  }
1833  $r5 = true;
1834  seq_2:
1835  if ($r5!==self::$FAILED) {
1836    $this->savedPos = $p6;
1837    $r5 = $this->a23($r4, $r11);
1838  } else {
1839    $r5 = null;
1840  }
1841  // free $p7
1842  // rest <- $r5
1843  $r1 = true;
1844  seq_1:
1845  if ($r1!==self::$FAILED) {
1846    $this->savedPos = $p2;
1847    $r1 = $this->a24($r4, $r5);
1848  }
1849  // free $p3
1850  return $r1;
1851}
1852private function parsea_config_line($silence) {
1853  $p2 = $this->currPos;
1854  // start seq_1
1855  $p3 = $this->currPos;
1856  $r4 = $this->parseoption_name($silence);
1857  // k <- $r4
1858  if ($r4===self::$FAILED) {
1859    $r1 = self::$FAILED;
1860    goto seq_1;
1861  }
1862  $r5 = $this->parseconfig_value($silence);
1863  // v <- $r5
1864  if ($r5===self::$FAILED) {
1865    $this->currPos = $p3;
1866    $r1 = self::$FAILED;
1867    goto seq_1;
1868  }
1869  $r1 = true;
1870  seq_1:
1871  if ($r1!==self::$FAILED) {
1872    $this->savedPos = $p2;
1873    $r1 = $this->a25($r4, $r5);
1874  }
1875  // free $p3
1876  return $r1;
1877}
1878private function parsean_option_value($silence) {
1879  $p2 = $this->currPos;
1880  // start choice_1
1881  $r3 = $this->parselink_target_value($silence);
1882  if ($r3!==self::$FAILED) {
1883    goto choice_1;
1884  }
1885  $r3 = $this->parsequoted_value($silence);
1886  if ($r3!==self::$FAILED) {
1887    goto choice_1;
1888  }
1889  $r3 = $this->parseplain_value($silence);
1890  if ($r3!==self::$FAILED) {
1891    goto choice_1;
1892  }
1893  $r3 = $this->parsejson_value($silence);
1894  choice_1:
1895  // v <- $r3
1896  $r1 = $r3;
1897  if ($r1!==self::$FAILED) {
1898    $this->savedPos = $p2;
1899    $r1 = $this->a26($r3);
1900  }
1901  return $r1;
1902}
1903private function parseconfig_value($silence) {
1904  $p2 = $this->currPos;
1905  // start seq_1
1906  $p3 = $this->currPos;
1907  $r4 = $this->discardwhitespace($silence);
1908  if ($r4===self::$FAILED) {
1909    $r4 = null;
1910  }
1911  if (($this->input[$this->currPos] ?? null) === "=") {
1912    $this->currPos++;
1913    $r5 = "=";
1914  } else {
1915    if (!$silence) {$this->fail(22);}
1916    $r5 = self::$FAILED;
1917    $this->currPos = $p3;
1918    $r1 = self::$FAILED;
1919    goto seq_1;
1920  }
1921  $r6 = $this->discardwhitespace($silence);
1922  if ($r6===self::$FAILED) {
1923    $r6 = null;
1924  }
1925  $r7 = $this->parsevalid_json_value($silence);
1926  // v <- $r7
1927  if ($r7===self::$FAILED) {
1928    $this->currPos = $p3;
1929    $r1 = self::$FAILED;
1930    goto seq_1;
1931  }
1932  $r1 = true;
1933  seq_1:
1934  if ($r1!==self::$FAILED) {
1935    $this->savedPos = $p2;
1936    $r1 = $this->a27($r7);
1937  }
1938  // free $p3
1939  return $r1;
1940}
1941private function parselink_target_value($silence) {
1942  $p2 = $this->currPos;
1943  // start seq_1
1944  $p3 = $this->currPos;
1945  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "[[", $this->currPos, 2, false) === 0) {
1946    $r4 = "[[";
1947    $this->currPos += 2;
1948  } else {
1949    if (!$silence) {$this->fail(24);}
1950    $r4 = self::$FAILED;
1951    $r1 = self::$FAILED;
1952    goto seq_1;
1953  }
1954  $r5 = [];
1955  for (;;) {
1956    $r6 = self::charAt($this->input, $this->currPos);
1957    if ($r6 !== '' && !($r6 === "]" || $r6 === "\x0a")) {
1958      $this->currPos += strlen($r6);
1959      $r5[] = $r6;
1960    } else {
1961      $r6 = self::$FAILED;
1962      if (!$silence) {$this->fail(25);}
1963      break;
1964    }
1965  }
1966  // v <- $r5
1967  // free $r6
1968  if ($this->currPos >= $this->inputLength ? false : substr_compare($this->input, "]]", $this->currPos, 2, false) === 0) {
1969    $r6 = "]]";
1970    $this->currPos += 2;
1971  } else {
1972    if (!$silence) {$this->fail(26);}
1973    $r6 = self::$FAILED;
1974    $this->currPos = $p3;
1975    $r1 = self::$FAILED;
1976    goto seq_1;
1977  }
1978  $r1 = true;
1979  seq_1:
1980  if ($r1!==self::$FAILED) {
1981    $this->savedPos = $p2;
1982    $r1 = $this->a28($r5);
1983  }
1984  // free $p3
1985  return $r1;
1986}
1987private function parsequoted_value($silence) {
1988  $p2 = $this->currPos;
1989  // start seq_1
1990  $p3 = $this->currPos;
1991  $r4 = $this->input[$this->currPos] ?? '';
1992  if ($r4 === "\"") {
1993    $this->currPos++;
1994  } else {
1995    $r4 = self::$FAILED;
1996    if (!$silence) {$this->fail(27);}
1997    $r1 = self::$FAILED;
1998    goto seq_1;
1999  }
2000  $r5 = [];
2001  for (;;) {
2002    // start choice_1
2003    if (strcspn($this->input, "\\\"\x0a", $this->currPos, 1) !== 0) {
2004      $r6 = self::consumeChar($this->input, $this->currPos);
2005      goto choice_1;
2006    } else {
2007      $r6 = self::$FAILED;
2008      if (!$silence) {$this->fail(28);}
2009    }
2010    $p7 = $this->currPos;
2011    // start seq_2
2012    $p8 = $this->currPos;
2013    if (($this->input[$this->currPos] ?? null) === "\\") {
2014      $this->currPos++;
2015      $r9 = "\\";
2016    } else {
2017      if (!$silence) {$this->fail(29);}
2018      $r9 = self::$FAILED;
2019      $r6 = self::$FAILED;
2020      goto seq_2;
2021    }
2022    $r10 = self::charAt($this->input, $this->currPos);
2023    // c <- $r10
2024    if ($r10 !== '' && !($r10 === "\x0a")) {
2025      $this->currPos += strlen($r10);
2026    } else {
2027      $r10 = self::$FAILED;
2028      if (!$silence) {$this->fail(7);}
2029      $this->currPos = $p8;
2030      $r6 = self::$FAILED;
2031      goto seq_2;
2032    }
2033    $r6 = true;
2034    seq_2:
2035    if ($r6!==self::$FAILED) {
2036      $this->savedPos = $p7;
2037      $r6 = $this->a29($r10);
2038    }
2039    // free $p8
2040    choice_1:
2041    if ($r6!==self::$FAILED) {
2042      $r5[] = $r6;
2043    } else {
2044      break;
2045    }
2046  }
2047  // v <- $r5
2048  // free $r6
2049  $r6 = $this->input[$this->currPos] ?? '';
2050  if ($r6 === "\"") {
2051    $this->currPos++;
2052  } else {
2053    $r6 = self::$FAILED;
2054    if (!$silence) {$this->fail(27);}
2055    $this->currPos = $p3;
2056    $r1 = self::$FAILED;
2057    goto seq_1;
2058  }
2059  $r1 = true;
2060  seq_1:
2061  if ($r1!==self::$FAILED) {
2062    $this->savedPos = $p2;
2063    $r1 = $this->a30($r5);
2064  }
2065  // free $p3
2066  return $r1;
2067}
2068private function parseplain_value($silence) {
2069  $p2 = $this->currPos;
2070  $r3 = [];
2071  for (;;) {
2072    if (strcspn($this->input, " \x09\x0a\"'[]=,!{", $this->currPos, 1) !== 0) {
2073      $r4 = self::consumeChar($this->input, $this->currPos);
2074      $r3[] = $r4;
2075    } else {
2076      $r4 = self::$FAILED;
2077      if (!$silence) {$this->fail(30);}
2078      break;
2079    }
2080  }
2081  if (count($r3) === 0) {
2082    $r3 = self::$FAILED;
2083  }
2084  // v <- $r3
2085  // free $r4
2086  $r1 = $r3;
2087  if ($r1!==self::$FAILED) {
2088    $this->savedPos = $p2;
2089    $r1 = $this->a31($r3);
2090  }
2091  return $r1;
2092}
2093private function parsejson_value($silence) {
2094  $p2 = $this->currPos;
2095  // start seq_1
2096  $p3 = $this->currPos;
2097  if (($this->input[$this->currPos] ?? null) === "{") {
2098    $this->currPos++;
2099    $r4 = "{";
2100  } else {
2101    if (!$silence) {$this->fail(31);}
2102    $r4 = self::$FAILED;
2103    $r1 = self::$FAILED;
2104    goto seq_1;
2105  }
2106  $r5 = [];
2107  for (;;) {
2108    // start choice_1
2109    if (strcspn($this->input, "\"{}\x0a", $this->currPos, 1) !== 0) {
2110      $r6 = self::consumeChar($this->input, $this->currPos);
2111      goto choice_1;
2112    } else {
2113      $r6 = self::$FAILED;
2114      if (!$silence) {$this->fail(32);}
2115    }
2116    $r6 = $this->parsequoted_value($silence);
2117    if ($r6!==self::$FAILED) {
2118      goto choice_1;
2119    }
2120    $r6 = $this->parsejson_value($silence);
2121    if ($r6!==self::$FAILED) {
2122      goto choice_1;
2123    }
2124    $r6 = $this->parseeol($silence);
2125    choice_1:
2126    if ($r6!==self::$FAILED) {
2127      $r5[] = $r6;
2128    } else {
2129      break;
2130    }
2131  }
2132  // v <- $r5
2133  // free $r6
2134  if (($this->input[$this->currPos] ?? null) === "}") {
2135    $this->currPos++;
2136    $r6 = "}";
2137  } else {
2138    if (!$silence) {$this->fail(33);}
2139    $r6 = self::$FAILED;
2140    $this->currPos = $p3;
2141    $r1 = self::$FAILED;
2142    goto seq_1;
2143  }
2144  $r1 = true;
2145  seq_1:
2146  if ($r1!==self::$FAILED) {
2147    $this->savedPos = $p2;
2148    $r1 = $this->a32($r5);
2149  }
2150  // free $p3
2151  return $r1;
2152}
2153private function parsevalid_json_value($silence) {
2154  $p2 = $this->currPos;
2155  // start seq_1
2156  $p3 = $this->currPos;
2157  $p5 = $this->currPos;
2158  // start choice_1
2159  $r4 = $this->discardquoted_value($silence);
2160  if ($r4!==self::$FAILED) {
2161    goto choice_1;
2162  }
2163  $r4 = $this->discardplain_value($silence);
2164  if ($r4!==self::$FAILED) {
2165    goto choice_1;
2166  }
2167  $r4 = $this->discardarray_value($silence);
2168  if ($r4!==self::$FAILED) {
2169    goto choice_1;
2170  }
2171  $r4 = $this->discardjson_value($silence);
2172  choice_1:
2173  // v <- $r4
2174  if ($r4!==self::$FAILED) {
2175    $r4 = substr($this->input, $p5, $this->currPos - $p5);
2176  } else {
2177    $r4 = self::$FAILED;
2178    $r1 = self::$FAILED;
2179    goto seq_1;
2180  }
2181  // free $p5
2182  $this->savedPos = $this->currPos;
2183  $r6 = $this->a33($r4);
2184  if ($r6) {
2185    $r6 = false;
2186  } else {
2187    $r6 = self::$FAILED;
2188    $this->currPos = $p3;
2189    $r1 = self::$FAILED;
2190    goto seq_1;
2191  }
2192  $r1 = true;
2193  seq_1:
2194  if ($r1!==self::$FAILED) {
2195    $this->savedPos = $p2;
2196    $r1 = $this->a34($r4);
2197  }
2198  // free $p3
2199  return $r1;
2200}
2201private function discardquoted_value($silence) {
2202  $p2 = $this->currPos;
2203  // start seq_1
2204  $p3 = $this->currPos;
2205  $r4 = $this->input[$this->currPos] ?? '';
2206  if ($r4 === "\"") {
2207    $this->currPos++;
2208  } else {
2209    $r4 = self::$FAILED;
2210    if (!$silence) {$this->fail(27);}
2211    $r1 = self::$FAILED;
2212    goto seq_1;
2213  }
2214  $r5 = [];
2215  for (;;) {
2216    // start choice_1
2217    if (strcspn($this->input, "\\\"\x0a", $this->currPos, 1) !== 0) {
2218      $r6 = self::consumeChar($this->input, $this->currPos);
2219      goto choice_1;
2220    } else {
2221      $r6 = self::$FAILED;
2222      if (!$silence) {$this->fail(28);}
2223    }
2224    $p7 = $this->currPos;
2225    // start seq_2
2226    $p8 = $this->currPos;
2227    if (($this->input[$this->currPos] ?? null) === "\\") {
2228      $this->currPos++;
2229      $r9 = "\\";
2230    } else {
2231      if (!$silence) {$this->fail(29);}
2232      $r9 = self::$FAILED;
2233      $r6 = self::$FAILED;
2234      goto seq_2;
2235    }
2236    $r10 = self::charAt($this->input, $this->currPos);
2237    // c <- $r10
2238    if ($r10 !== '' && !($r10 === "\x0a")) {
2239      $this->currPos += strlen($r10);
2240    } else {
2241      $r10 = self::$FAILED;
2242      if (!$silence) {$this->fail(7);}
2243      $this->currPos = $p8;
2244      $r6 = self::$FAILED;
2245      goto seq_2;
2246    }
2247    $r6 = true;
2248    seq_2:
2249    if ($r6!==self::$FAILED) {
2250      $this->savedPos = $p7;
2251      $r6 = $this->a29($r10);
2252    }
2253    // free $p8
2254    choice_1:
2255    if ($r6!==self::$FAILED) {
2256      $r5[] = $r6;
2257    } else {
2258      break;
2259    }
2260  }
2261  // v <- $r5
2262  // free $r6
2263  $r6 = $this->input[$this->currPos] ?? '';
2264  if ($r6 === "\"") {
2265    $this->currPos++;
2266  } else {
2267    $r6 = self::$FAILED;
2268    if (!$silence) {$this->fail(27);}
2269    $this->currPos = $p3;
2270    $r1 = self::$FAILED;
2271    goto seq_1;
2272  }
2273  $r1 = true;
2274  seq_1:
2275  if ($r1!==self::$FAILED) {
2276    $this->savedPos = $p2;
2277    $r1 = $this->a30($r5);
2278  }
2279  // free $p3
2280  return $r1;
2281}
2282private function discardplain_value($silence) {
2283  $p2 = $this->currPos;
2284  $r3 = [];
2285  for (;;) {
2286    if (strcspn($this->input, " \x09\x0a\"'[]=,!{", $this->currPos, 1) !== 0) {
2287      $r4 = self::consumeChar($this->input, $this->currPos);
2288      $r3[] = $r4;
2289    } else {
2290      $r4 = self::$FAILED;
2291      if (!$silence) {$this->fail(30);}
2292      break;
2293    }
2294  }
2295  if (count($r3) === 0) {
2296    $r3 = self::$FAILED;
2297  }
2298  // v <- $r3
2299  // free $r4
2300  $r1 = $r3;
2301  if ($r1!==self::$FAILED) {
2302    $this->savedPos = $p2;
2303    $r1 = $this->a31($r3);
2304  }
2305  return $r1;
2306}
2307private function discardarray_value($silence) {
2308  $p2 = $this->currPos;
2309  // start seq_1
2310  $p3 = $this->currPos;
2311  if (($this->input[$this->currPos] ?? null) === "[") {
2312    $this->currPos++;
2313    $r4 = "[";
2314  } else {
2315    if (!$silence) {$this->fail(34);}
2316    $r4 = self::$FAILED;
2317    $r1 = self::$FAILED;
2318    goto seq_1;
2319  }
2320  $r5 = [];
2321  for (;;) {
2322    // start choice_1
2323    if (strcspn($this->input, "\"[]\x0a", $this->currPos, 1) !== 0) {
2324      $r6 = self::consumeChar($this->input, $this->currPos);
2325      goto choice_1;
2326    } else {
2327      $r6 = self::$FAILED;
2328      if (!$silence) {$this->fail(35);}
2329    }
2330    $r6 = $this->parsequoted_value($silence);
2331    if ($r6!==self::$FAILED) {
2332      goto choice_1;
2333    }
2334    $r6 = $this->parsearray_value($silence);
2335    if ($r6!==self::$FAILED) {
2336      goto choice_1;
2337    }
2338    $r6 = $this->parseeol($silence);
2339    choice_1:
2340    if ($r6!==self::$FAILED) {
2341      $r5[] = $r6;
2342    } else {
2343      break;
2344    }
2345  }
2346  // v <- $r5
2347  // free $r6
2348  if (($this->input[$this->currPos] ?? null) === "]") {
2349    $this->currPos++;
2350    $r6 = "]";
2351  } else {
2352    if (!$silence) {$this->fail(36);}
2353    $r6 = self::$FAILED;
2354    $this->currPos = $p3;
2355    $r1 = self::$FAILED;
2356    goto seq_1;
2357  }
2358  $r1 = true;
2359  seq_1:
2360  if ($r1!==self::$FAILED) {
2361    $this->savedPos = $p2;
2362    $r1 = $this->a35($r5);
2363  }
2364  // free $p3
2365  return $r1;
2366}
2367private function discardjson_value($silence) {
2368  $p2 = $this->currPos;
2369  // start seq_1
2370  $p3 = $this->currPos;
2371  if (($this->input[$this->currPos] ?? null) === "{") {
2372    $this->currPos++;
2373    $r4 = "{";
2374  } else {
2375    if (!$silence) {$this->fail(31);}
2376    $r4 = self::$FAILED;
2377    $r1 = self::$FAILED;
2378    goto seq_1;
2379  }
2380  $r5 = [];
2381  for (;;) {
2382    // start choice_1
2383    if (strcspn($this->input, "\"{}\x0a", $this->currPos, 1) !== 0) {
2384      $r6 = self::consumeChar($this->input, $this->currPos);
2385      goto choice_1;
2386    } else {
2387      $r6 = self::$FAILED;
2388      if (!$silence) {$this->fail(32);}
2389    }
2390    $r6 = $this->parsequoted_value($silence);
2391    if ($r6!==self::$FAILED) {
2392      goto choice_1;
2393    }
2394    $r6 = $this->parsejson_value($silence);
2395    if ($r6!==self::$FAILED) {
2396      goto choice_1;
2397    }
2398    $r6 = $this->parseeol($silence);
2399    choice_1:
2400    if ($r6!==self::$FAILED) {
2401      $r5[] = $r6;
2402    } else {
2403      break;
2404    }
2405  }
2406  // v <- $r5
2407  // free $r6
2408  if (($this->input[$this->currPos] ?? null) === "}") {
2409    $this->currPos++;
2410    $r6 = "}";
2411  } else {
2412    if (!$silence) {$this->fail(33);}
2413    $r6 = self::$FAILED;
2414    $this->currPos = $p3;
2415    $r1 = self::$FAILED;
2416    goto seq_1;
2417  }
2418  $r1 = true;
2419  seq_1:
2420  if ($r1!==self::$FAILED) {
2421    $this->savedPos = $p2;
2422    $r1 = $this->a32($r5);
2423  }
2424  // free $p3
2425  return $r1;
2426}
2427private function parsearray_value($silence) {
2428  $p2 = $this->currPos;
2429  // start seq_1
2430  $p3 = $this->currPos;
2431  if (($this->input[$this->currPos] ?? null) === "[") {
2432    $this->currPos++;
2433    $r4 = "[";
2434  } else {
2435    if (!$silence) {$this->fail(34);}
2436    $r4 = self::$FAILED;
2437    $r1 = self::$FAILED;
2438    goto seq_1;
2439  }
2440  $r5 = [];
2441  for (;;) {
2442    // start choice_1
2443    if (strcspn($this->input, "\"[]\x0a", $this->currPos, 1) !== 0) {
2444      $r6 = self::consumeChar($this->input, $this->currPos);
2445      goto choice_1;
2446    } else {
2447      $r6 = self::$FAILED;
2448      if (!$silence) {$this->fail(35);}
2449    }
2450    $r6 = $this->parsequoted_value($silence);
2451    if ($r6!==self::$FAILED) {
2452      goto choice_1;
2453    }
2454    $r6 = $this->parsearray_value($silence);
2455    if ($r6!==self::$FAILED) {
2456      goto choice_1;
2457    }
2458    $r6 = $this->parseeol($silence);
2459    choice_1:
2460    if ($r6!==self::$FAILED) {
2461      $r5[] = $r6;
2462    } else {
2463      break;
2464    }
2465  }
2466  // v <- $r5
2467  // free $r6
2468  if (($this->input[$this->currPos] ?? null) === "]") {
2469    $this->currPos++;
2470    $r6 = "]";
2471  } else {
2472    if (!$silence) {$this->fail(36);}
2473    $r6 = self::$FAILED;
2474    $this->currPos = $p3;
2475    $r1 = self::$FAILED;
2476    goto seq_1;
2477  }
2478  $r1 = true;
2479  seq_1:
2480  if ($r1!==self::$FAILED) {
2481    $this->savedPos = $p2;
2482    $r1 = $this->a35($r5);
2483  }
2484  // free $p3
2485  return $r1;
2486}
2487
2488    public function parse( $input, $options = [] ) {
2489        $this->initInternal( $input, $options );
2490        $startRule = $options['startRule'] ?? '(DEFAULT)';
2491        $result = null;
2492
2493        if ( !empty( $options['stream'] ) ) {
2494            switch ( $startRule ) {
2495                
2496            default:
2497                throw new \Wikimedia\WikiPEG\InternalError( "Can't stream rule $startRule." );
2498            }
2499        } else {
2500            switch ( $startRule ) {
2501                case '(DEFAULT)':
2502case "testfile":
2503  $result = $this->parsetestfile(false);
2504  break;
2505            default:
2506                throw new \Wikimedia\WikiPEG\InternalError( "Can't start parsing from rule $startRule." );
2507            }
2508        }
2509
2510        if ( $result !== self::$FAILED && $this->currPos === $this->inputLength ) {
2511            return $result;
2512        } else {
2513            if ( $result !== self::$FAILED && $this->currPos < $this->inputLength ) {
2514                $this->fail( 0 );
2515            }
2516            throw $this->buildParseException();
2517        }
2518    }
2519}
2520