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