1#################################################################### 2# 3# This file was generated using Parse::Yapp version 1.05. 4# 5# Don't edit this file, use source file instead. 6# 7# ANY CHANGE MADE HERE WILL BE LOST ! 8# 9#################################################################### 10package Parse::Yapp::Parse; 11use vars qw ( @ISA ); 12use strict; 13 14@ISA= qw ( Parse::Yapp::Driver ); 15use Parse::Yapp::Driver; 16 17#line 1 "YappParse.yp" 18# (c) Copyright Francois Desarmenien 1998-2001, all rights reserved. 19# (see COPYRIGHT in Parse::Yapp.pm pod section for use and distribution rights) 20# 21# Parse/Yapp/Parser.yp: Parse::Yapp::Parser.pm source file 22# 23# Use: yapp -m 'Parse::Yapp::Parse' -o Parse/Yapp/Parse.pm YappParse.yp 24# 25# to generate the Parser module. 26# 27#line 12 "YappParse.yp" 28 29require 5.004; 30 31use Carp; 32 33my($input,$lexlevel,@lineno,$nberr,$prec,$labelno); 34my($syms,$head,$tail,$token,$term,$nterm,$rules,$precterm,$start,$nullable); 35my($expect); 36 37 38 39sub new { 40 my($class)=shift; 41 ref($class) 42 and $class=ref($class); 43 44 my($self)=$class->SUPER::new( yyversion => '1.05', 45 yystates => 46[ 47 {#State 0 48 ACTIONS => { 49 "%%" => -6, 50 'HEADCODE' => 3, 51 'UNION' => 2, 52 'TOKEN' => 5, 53 'ASSOC' => 7, 54 'START' => 6, 55 'error' => 9, 56 'TYPE' => 10, 57 "\n" => 11, 58 'EXPECT' => 13 59 }, 60 GOTOS => { 61 'head' => 1, 62 'decls' => 12, 63 'yapp' => 4, 64 'decl' => 14, 65 'headsec' => 8 66 } 67 }, 68 {#State 1 69 ACTIONS => { 70 'error' => 19, 71 "%%" => 16, 72 'IDENT' => 18 73 }, 74 GOTOS => { 75 'rules' => 15, 76 'rulesec' => 20, 77 'body' => 17 78 } 79 }, 80 {#State 2 81 ACTIONS => { 82 'CODE' => 21 83 } 84 }, 85 {#State 3 86 ACTIONS => { 87 "\n" => 22 88 } 89 }, 90 {#State 4 91 ACTIONS => { 92 '' => 23 93 } 94 }, 95 {#State 5 96 ACTIONS => { 97 "<" => 25 98 }, 99 DEFAULT => -19, 100 GOTOS => { 101 'typedecl' => 24 102 } 103 }, 104 {#State 6 105 ACTIONS => { 106 'IDENT' => 26 107 }, 108 GOTOS => { 109 'ident' => 27 110 } 111 }, 112 {#State 7 113 ACTIONS => { 114 "<" => 25 115 }, 116 DEFAULT => -19, 117 GOTOS => { 118 'typedecl' => 28 119 } 120 }, 121 {#State 8 122 ACTIONS => { 123 "%%" => 29 124 } 125 }, 126 {#State 9 127 ACTIONS => { 128 "\n" => 30 129 } 130 }, 131 {#State 10 132 ACTIONS => { 133 "<" => 25 134 }, 135 DEFAULT => -19, 136 GOTOS => { 137 'typedecl' => 31 138 } 139 }, 140 {#State 11 141 DEFAULT => -10 142 }, 143 {#State 12 144 ACTIONS => { 145 "%%" => -7, 146 'HEADCODE' => 3, 147 'UNION' => 2, 148 'TOKEN' => 5, 149 'ASSOC' => 7, 150 'START' => 6, 151 'error' => 9, 152 'TYPE' => 10, 153 "\n" => 11, 154 'EXPECT' => 13 155 }, 156 GOTOS => { 157 'decl' => 32 158 } 159 }, 160 {#State 13 161 ACTIONS => { 162 'NUMBER' => 33 163 } 164 }, 165 {#State 14 166 DEFAULT => -9 167 }, 168 {#State 15 169 DEFAULT => -28 170 }, 171 {#State 16 172 DEFAULT => -26 173 }, 174 {#State 17 175 ACTIONS => { 176 'TAILCODE' => 34 177 }, 178 DEFAULT => -45, 179 GOTOS => { 180 'tail' => 35 181 } 182 }, 183 {#State 18 184 ACTIONS => { 185 ":" => 36 186 } 187 }, 188 {#State 19 189 ACTIONS => { 190 ";" => 37 191 } 192 }, 193 {#State 20 194 ACTIONS => { 195 'error' => 19, 196 "%%" => 39, 197 'IDENT' => 18 198 }, 199 GOTOS => { 200 'rules' => 38 201 } 202 }, 203 {#State 21 204 ACTIONS => { 205 "\n" => 40 206 } 207 }, 208 {#State 22 209 DEFAULT => -14 210 }, 211 {#State 23 212 DEFAULT => -0 213 }, 214 {#State 24 215 ACTIONS => { 216 'LITERAL' => 41, 217 'IDENT' => 26 218 }, 219 GOTOS => { 220 'symlist' => 43, 221 'ident' => 44, 222 'symbol' => 42 223 } 224 }, 225 {#State 25 226 ACTIONS => { 227 'IDENT' => 45 228 } 229 }, 230 {#State 26 231 DEFAULT => -4 232 }, 233 {#State 27 234 ACTIONS => { 235 "\n" => 46 236 } 237 }, 238 {#State 28 239 ACTIONS => { 240 'LITERAL' => 41, 241 'IDENT' => 26 242 }, 243 GOTOS => { 244 'symlist' => 47, 245 'ident' => 44, 246 'symbol' => 42 247 } 248 }, 249 {#State 29 250 DEFAULT => -5 251 }, 252 {#State 30 253 DEFAULT => -18 254 }, 255 {#State 31 256 ACTIONS => { 257 'IDENT' => 26 258 }, 259 GOTOS => { 260 'ident' => 48, 261 'identlist' => 49 262 } 263 }, 264 {#State 32 265 DEFAULT => -8 266 }, 267 {#State 33 268 ACTIONS => { 269 "\n" => 50 270 } 271 }, 272 {#State 34 273 DEFAULT => -46 274 }, 275 {#State 35 276 DEFAULT => -1 277 }, 278 {#State 36 279 ACTIONS => { 280 'CODE' => 57, 281 'LITERAL' => 41, 282 'IDENT' => 26 283 }, 284 DEFAULT => -35, 285 GOTOS => { 286 'rhselts' => 56, 287 'rule' => 51, 288 'code' => 52, 289 'rhs' => 53, 290 'ident' => 44, 291 'rhselt' => 58, 292 'rhss' => 55, 293 'symbol' => 54 294 } 295 }, 296 {#State 37 297 DEFAULT => -30 298 }, 299 {#State 38 300 DEFAULT => -27 301 }, 302 {#State 39 303 DEFAULT => -25 304 }, 305 {#State 40 306 DEFAULT => -15 307 }, 308 {#State 41 309 DEFAULT => -2 310 }, 311 {#State 42 312 DEFAULT => -22 313 }, 314 {#State 43 315 ACTIONS => { 316 "\n" => 60, 317 'LITERAL' => 41, 318 'IDENT' => 26 319 }, 320 GOTOS => { 321 'ident' => 44, 322 'symbol' => 59 323 } 324 }, 325 {#State 44 326 DEFAULT => -3 327 }, 328 {#State 45 329 ACTIONS => { 330 ">" => 61 331 } 332 }, 333 {#State 46 334 DEFAULT => -13 335 }, 336 {#State 47 337 ACTIONS => { 338 "\n" => 62, 339 'LITERAL' => 41, 340 'IDENT' => 26 341 }, 342 GOTOS => { 343 'ident' => 44, 344 'symbol' => 59 345 } 346 }, 347 {#State 48 348 DEFAULT => -24 349 }, 350 {#State 49 351 ACTIONS => { 352 "\n" => 63, 353 'IDENT' => 26 354 }, 355 GOTOS => { 356 'ident' => 64 357 } 358 }, 359 {#State 50 360 DEFAULT => -17 361 }, 362 {#State 51 363 DEFAULT => -32 364 }, 365 {#State 52 366 DEFAULT => -40 367 }, 368 {#State 53 369 ACTIONS => { 370 'PREC' => 66 371 }, 372 DEFAULT => -34, 373 GOTOS => { 374 'prec' => 65 375 } 376 }, 377 {#State 54 378 DEFAULT => -39 379 }, 380 {#State 55 381 ACTIONS => { 382 "|" => 68, 383 ";" => 67 384 } 385 }, 386 {#State 56 387 ACTIONS => { 388 'CODE' => 57, 389 'LITERAL' => 41, 390 'IDENT' => 26 391 }, 392 DEFAULT => -36, 393 GOTOS => { 394 'code' => 52, 395 'ident' => 44, 396 'rhselt' => 69, 397 'symbol' => 54 398 } 399 }, 400 {#State 57 401 DEFAULT => -44 402 }, 403 {#State 58 404 DEFAULT => -38 405 }, 406 {#State 59 407 DEFAULT => -21 408 }, 409 {#State 60 410 DEFAULT => -11 411 }, 412 {#State 61 413 DEFAULT => -20 414 }, 415 {#State 62 416 DEFAULT => -12 417 }, 418 {#State 63 419 DEFAULT => -16 420 }, 421 {#State 64 422 DEFAULT => -23 423 }, 424 {#State 65 425 ACTIONS => { 426 'CODE' => 57 427 }, 428 DEFAULT => -42, 429 GOTOS => { 430 'code' => 70, 431 'epscode' => 71 432 } 433 }, 434 {#State 66 435 ACTIONS => { 436 'LITERAL' => 41, 437 'IDENT' => 26 438 }, 439 GOTOS => { 440 'ident' => 44, 441 'symbol' => 72 442 } 443 }, 444 {#State 67 445 DEFAULT => -29 446 }, 447 {#State 68 448 ACTIONS => { 449 'CODE' => 57, 450 'LITERAL' => 41, 451 'IDENT' => 26 452 }, 453 DEFAULT => -35, 454 GOTOS => { 455 'rhselts' => 56, 456 'rule' => 73, 457 'code' => 52, 458 'rhs' => 53, 459 'ident' => 44, 460 'rhselt' => 58, 461 'symbol' => 54 462 } 463 }, 464 {#State 69 465 DEFAULT => -37 466 }, 467 {#State 70 468 DEFAULT => -43 469 }, 470 {#State 71 471 DEFAULT => -33 472 }, 473 {#State 72 474 DEFAULT => -41 475 }, 476 {#State 73 477 DEFAULT => -31 478 } 479], 480 yyrules => 481[ 482 [#Rule 0 483 '$start', 2, undef 484 ], 485 [#Rule 1 486 'yapp', 3, undef 487 ], 488 [#Rule 2 489 'symbol', 1, 490sub 491#line 30 "YappParse.yp" 492{ 493 exists($$syms{$_[1][0]}) 494 or do { 495 $$syms{$_[1][0]} = $_[1][1]; 496 $$term{$_[1][0]} = undef; 497 }; 498 $_[1] 499 } 500 ], 501 [#Rule 3 502 'symbol', 1, undef 503 ], 504 [#Rule 4 505 'ident', 1, 506sub 507#line 41 "YappParse.yp" 508{ 509 exists($$syms{$_[1][0]}) 510 or do { 511 $$syms{$_[1][0]} = $_[1][1]; 512 $$term{$_[1][0]} = undef; 513 }; 514 $_[1] 515 } 516 ], 517 [#Rule 5 518 'head', 2, undef 519 ], 520 [#Rule 6 521 'headsec', 0, undef 522 ], 523 [#Rule 7 524 'headsec', 1, undef 525 ], 526 [#Rule 8 527 'decls', 2, undef 528 ], 529 [#Rule 9 530 'decls', 1, undef 531 ], 532 [#Rule 10 533 'decl', 1, undef 534 ], 535 [#Rule 11 536 'decl', 4, 537sub 538#line 66 "YappParse.yp" 539{ 540 for (@{$_[3]}) { 541 my($symbol,$lineno)=@$_; 542 543 exists($$token{$symbol}) 544 and do { 545 _SyntaxError(0, 546 "Token $symbol redefined: ". 547 "Previously defined line $$syms{$symbol}", 548 $lineno); 549 next; 550 }; 551 $$token{$symbol}=$lineno; 552 $$term{$symbol} = [ ]; 553 } 554 undef 555 } 556 ], 557 [#Rule 12 558 'decl', 4, 559sub 560#line 84 "YappParse.yp" 561{ 562 for (@{$_[3]}) { 563 my($symbol,$lineno)=@$_; 564 565 defined($$term{$symbol}[0]) 566 and do { 567 _SyntaxError(1, 568 "Precedence for symbol $symbol redefined: ". 569 "Previously defined line $$syms{$symbol}", 570 $lineno); 571 next; 572 }; 573 $$token{$symbol}=$lineno; 574 $$term{$symbol} = [ $_[1][0], $prec ]; 575 } 576 ++$prec; 577 undef 578 } 579 ], 580 [#Rule 13 581 'decl', 3, 582sub 583#line 102 "YappParse.yp" 584{ $start=$_[2][0]; undef } 585 ], 586 [#Rule 14 587 'decl', 2, 588sub 589#line 103 "YappParse.yp" 590{ push(@$head,$_[1]); undef } 591 ], 592 [#Rule 15 593 'decl', 3, 594sub 595#line 104 "YappParse.yp" 596{ undef } 597 ], 598 [#Rule 16 599 'decl', 4, 600sub 601#line 106 "YappParse.yp" 602{ 603 for ( @{$_[3]} ) { 604 my($symbol,$lineno)=@$_; 605 606 exists($$nterm{$symbol}) 607 and do { 608 _SyntaxError(0, 609 "Non-terminal $symbol redefined: ". 610 "Previously defined line $$syms{$symbol}", 611 $lineno); 612 next; 613 }; 614 delete($$term{$symbol}); #not a terminal 615 $$nterm{$symbol}=undef; #is a non-terminal 616 } 617 } 618 ], 619 [#Rule 17 620 'decl', 3, 621sub 622#line 122 "YappParse.yp" 623{ $expect=$_[2][0]; undef } 624 ], 625 [#Rule 18 626 'decl', 2, 627sub 628#line 123 "YappParse.yp" 629{ $_[0]->YYErrok } 630 ], 631 [#Rule 19 632 'typedecl', 0, undef 633 ], 634 [#Rule 20 635 'typedecl', 3, undef 636 ], 637 [#Rule 21 638 'symlist', 2, 639sub 640#line 130 "YappParse.yp" 641{ push(@{$_[1]},$_[2]); $_[1] } 642 ], 643 [#Rule 22 644 'symlist', 1, 645sub 646#line 131 "YappParse.yp" 647{ [ $_[1] ] } 648 ], 649 [#Rule 23 650 'identlist', 2, 651sub 652#line 134 "YappParse.yp" 653{ push(@{$_[1]},$_[2]); $_[1] } 654 ], 655 [#Rule 24 656 'identlist', 1, 657sub 658#line 135 "YappParse.yp" 659{ [ $_[1] ] } 660 ], 661 [#Rule 25 662 'body', 2, 663sub 664#line 140 "YappParse.yp" 665{ 666 $start 667 or $start=$$rules[1][0]; 668 669 ref($$nterm{$start}) 670 or _SyntaxError(2,"Start symbol $start not found ". 671 "in rules section",$_[2][1]); 672 673 $$rules[0]=[ '$start', [ $start, chr(0) ], undef, undef ]; 674 } 675 ], 676 [#Rule 26 677 'body', 1, 678sub 679#line 150 "YappParse.yp" 680{ _SyntaxError(2,"No rules in input grammar",$_[1][1]); } 681 ], 682 [#Rule 27 683 'rulesec', 2, undef 684 ], 685 [#Rule 28 686 'rulesec', 1, undef 687 ], 688 [#Rule 29 689 'rules', 4, 690sub 691#line 157 "YappParse.yp" 692{ _AddRules($_[1],$_[3]); undef } 693 ], 694 [#Rule 30 695 'rules', 2, 696sub 697#line 158 "YappParse.yp" 698{ $_[0]->YYErrok } 699 ], 700 [#Rule 31 701 'rhss', 3, 702sub 703#line 161 "YappParse.yp" 704{ push(@{$_[1]},$_[3]); $_[1] } 705 ], 706 [#Rule 32 707 'rhss', 1, 708sub 709#line 162 "YappParse.yp" 710{ [ $_[1] ] } 711 ], 712 [#Rule 33 713 'rule', 3, 714sub 715#line 165 "YappParse.yp" 716{ push(@{$_[1]}, $_[2], $_[3]); $_[1] } 717 ], 718 [#Rule 34 719 'rule', 1, 720sub 721#line 166 "YappParse.yp" 722{ 723 my($code)=undef; 724 725 defined($_[1]) 726 and $_[1][-1][0] eq 'CODE' 727 and $code = ${pop(@{$_[1]})}[1]; 728 729 push(@{$_[1]}, undef, $code); 730 731 $_[1] 732 } 733 ], 734 [#Rule 35 735 'rhs', 0, undef 736 ], 737 [#Rule 36 738 'rhs', 1, undef 739 ], 740 [#Rule 37 741 'rhselts', 2, 742sub 743#line 183 "YappParse.yp" 744{ push(@{$_[1]},$_[2]); $_[1] } 745 ], 746 [#Rule 38 747 'rhselts', 1, 748sub 749#line 184 "YappParse.yp" 750{ [ $_[1] ] } 751 ], 752 [#Rule 39 753 'rhselt', 1, 754sub 755#line 187 "YappParse.yp" 756{ [ 'SYMB', $_[1] ] } 757 ], 758 [#Rule 40 759 'rhselt', 1, 760sub 761#line 188 "YappParse.yp" 762{ [ 'CODE', $_[1] ] } 763 ], 764 [#Rule 41 765 'prec', 2, 766sub 767#line 192 "YappParse.yp" 768{ 769 defined($$term{$_[2][0]}) 770 or do { 771 _SyntaxError(1,"No precedence for symbol $_[2][0]", 772 $_[2][1]); 773 return undef; 774 }; 775 776 ++$$precterm{$_[2][0]}; 777 $$term{$_[2][0]}[1]; 778 } 779 ], 780 [#Rule 42 781 'epscode', 0, 782sub 783#line 205 "YappParse.yp" 784{ undef } 785 ], 786 [#Rule 43 787 'epscode', 1, 788sub 789#line 206 "YappParse.yp" 790{ $_[1] } 791 ], 792 [#Rule 44 793 'code', 1, 794sub 795#line 209 "YappParse.yp" 796{ $_[1] } 797 ], 798 [#Rule 45 799 'tail', 0, undef 800 ], 801 [#Rule 46 802 'tail', 1, 803sub 804#line 215 "YappParse.yp" 805{ $tail=$_[1] } 806 ] 807], 808 @_); 809 bless($self,$class); 810} 811 812#line 218 "YappParse.yp" 813 814sub _Error { 815 my($value)=$_[0]->YYCurval; 816 817 my($what)= $token ? "input: '$$value[0]'" : "end of input"; 818 819 _SyntaxError(1,"Unexpected $what",$$value[1]); 820} 821 822sub _Lexer { 823 824 #At EOF 825 pos($$input) >= length($$input) 826 and return('',[ undef, -1 ]); 827 828 #In TAIL section 829 $lexlevel > 1 830 and do { 831 my($pos)=pos($$input); 832 833 $lineno[0]=$lineno[1]; 834 $lineno[1]=-1; 835 pos($$input)=length($$input); 836 return('TAILCODE',[ substr($$input,$pos), $lineno[0] ]); 837 }; 838 839 #Skip blanks 840 $lexlevel == 0 841 ? $$input=~m{\G((?: 842 [\t\ ]+ # Any white space char but \n 843 | \#[^\n]* # Perl like comments 844 | /\*.*?\*/ # C like comments 845 )+)}xsgc 846 : $$input=~m{\G((?: 847 \s+ # any white space char 848 | \#[^\n]* # Perl like comments 849 | /\*.*?\*/ # C like comments 850 )+)}xsgc 851 and do { 852 my($blanks)=$1; 853 854 #Maybe At EOF 855 pos($$input) >= length($$input) 856 and return('',[ undef, -1 ]); 857 858 $lineno[1]+= $blanks=~tr/\n//; 859 }; 860 861 $lineno[0]=$lineno[1]; 862 863 $$input=~/\G([A-Za-z_][A-Za-z0-9_]*)/gc 864 and return('IDENT',[ $1, $lineno[0] ]); 865 866 $$input=~/\G('(?:[^'\\]|\\\\|\\'|\\)+?')/gc 867 and do { 868 $1 eq "'error'" 869 and do { 870 _SyntaxError(0,"Literal 'error' ". 871 "will be treated as error token",$lineno[0]); 872 return('IDENT',[ 'error', $lineno[0] ]); 873 }; 874 return('LITERAL',[ $1, $lineno[0] ]); 875 }; 876 877 $$input=~/\G(%%)/gc 878 and do { 879 ++$lexlevel; 880 return($1, [ $1, $lineno[0] ]); 881 }; 882 883 $$input=~/\G{/gc 884 and do { 885 my($level,$from,$code); 886 887 $from=pos($$input); 888 889 $level=1; 890 while($$input=~/([{}])/gc) { 891 substr($$input,pos($$input)-1,1) eq '\\' #Quoted 892 and next; 893 $level += ($1 eq '{' ? 1 : -1) 894 or last; 895 } 896 $level 897 and _SyntaxError(2,"Unmatched { opened line $lineno[0]",-1); 898 $code = substr($$input,$from,pos($$input)-$from-1); 899 $lineno[1]+= $code=~tr/\n//; 900 return('CODE',[ $code, $lineno[0] ]); 901 }; 902 903 if($lexlevel == 0) {# In head section 904 $$input=~/\G%(left|right|nonassoc)/gc 905 and return('ASSOC',[ uc($1), $lineno[0] ]); 906 $$input=~/\G%(start)/gc 907 and return('START',[ undef, $lineno[0] ]); 908 $$input=~/\G%(expect)/gc 909 and return('EXPECT',[ undef, $lineno[0] ]); 910 $$input=~/\G%{/gc 911 and do { 912 my($code); 913 914 $$input=~/\G(.*?)%}/sgc 915 or _SyntaxError(2,"Unmatched %{ opened line $lineno[0]",-1); 916 917 $code=$1; 918 $lineno[1]+= $code=~tr/\n//; 919 return('HEADCODE',[ $code, $lineno[0] ]); 920 }; 921 $$input=~/\G%(token)/gc 922 and return('TOKEN',[ undef, $lineno[0] ]); 923 $$input=~/\G%(type)/gc 924 and return('TYPE',[ undef, $lineno[0] ]); 925 $$input=~/\G%(union)/gc 926 and return('UNION',[ undef, $lineno[0] ]); 927 $$input=~/\G([0-9]+)/gc 928 and return('NUMBER',[ $1, $lineno[0] ]); 929 930 } 931 else {# In rule section 932 $$input=~/\G%(prec)/gc 933 and return('PREC',[ undef, $lineno[0] ]); 934 } 935 936 #Always return something 937 $$input=~/\G(.)/sg 938 or die "Parse::Yapp::Grammar::Parse: Match (.) failed: report as a BUG"; 939 940 $1 eq "\n" 941 and ++$lineno[1]; 942 943 ( $1 ,[ $1, $lineno[0] ]); 944 945} 946 947sub _SyntaxError { 948 my($level,$message,$lineno)=@_; 949 950 $message= "*". 951 [ 'Warning', 'Error', 'Fatal' ]->[$level]. 952 "* $message, at ". 953 ($lineno < 0 ? "eof" : "line $lineno"). 954 ".\n"; 955 956 $level > 1 957 and die $message; 958 959 warn $message; 960 961 $level > 0 962 and ++$nberr; 963 964 $nberr == 20 965 and die "*Fatal* Too many errors detected.\n" 966} 967 968sub _AddRules { 969 my($lhs,$lineno)=@{$_[0]}; 970 my($rhss)=$_[1]; 971 972 ref($$nterm{$lhs}) 973 and do { 974 _SyntaxError(1,"Non-terminal $lhs redefined: ". 975 "Previously declared line $$syms{$lhs}",$lineno); 976 return; 977 }; 978 979 ref($$term{$lhs}) 980 and do { 981 my($where) = exists($$token{$lhs}) ? $$token{$lhs} : $$syms{$lhs}; 982 _SyntaxError(1,"Non-terminal $lhs previously ". 983 "declared as token line $where",$lineno); 984 return; 985 }; 986 987 ref($$nterm{$lhs}) #declared through %type 988 or do { 989 $$syms{$lhs}=$lineno; #Say it's declared here 990 delete($$term{$lhs}); #No more a terminal 991 }; 992 $$nterm{$lhs}=[]; #It's a non-terminal now 993 994 my($epsrules)=0; #To issue a warning if more than one epsilon rule 995 996 for my $rhs (@$rhss) { 997 my($tmprule)=[ $lhs, [ ], splice(@$rhs,-2) ]; #Init rule 998 999 @$rhs 1000 or do { 1001 ++$$nullable{$lhs}; 1002 ++$epsrules; 1003 }; 1004 1005 for (0..$#$rhs) { 1006 my($what,$value)=@{$$rhs[$_]}; 1007 1008 $what eq 'CODE' 1009 and do { 1010 my($name)='@'.++$labelno."-$_"; 1011 push(@$rules,[ $name, [], undef, $value ]); 1012 push(@{$$tmprule[1]},$name); 1013 next; 1014 }; 1015 push(@{$$tmprule[1]},$$value[0]); 1016 } 1017 push(@$rules,$tmprule); 1018 push(@{$$nterm{$lhs}},$#$rules); 1019 } 1020 1021 $epsrules > 1 1022 and _SyntaxError(0,"More than one empty rule for symbol $lhs",$lineno); 1023} 1024 1025sub Parse { 1026 my($self)=shift; 1027 1028 @_ > 0 1029 or croak("No input grammar\n"); 1030 1031 my($parsed)={}; 1032 1033 $input=\$_[0]; 1034 1035 $lexlevel=0; 1036 @lineno=(1,1); 1037 $nberr=0; 1038 $prec=0; 1039 $labelno=0; 1040 1041 $head=(); 1042 $tail=""; 1043 1044 $syms={}; 1045 $token={}; 1046 $term={}; 1047 $nterm={}; 1048 $rules=[ undef ]; #reserve slot 0 for start rule 1049 $precterm={}; 1050 1051 $start=""; 1052 $nullable={}; 1053 $expect=0; 1054 1055 pos($$input)=0; 1056 1057 1058 $self->YYParse(yylex => \&_Lexer, yyerror => \&_Error); 1059 1060 $nberr 1061 and _SyntaxError(2,"Errors detected: No output",-1); 1062 1063 @$parsed{ 'HEAD', 'TAIL', 'RULES', 'NTERM', 'TERM', 1064 'NULL', 'PREC', 'SYMS', 'START', 'EXPECT' } 1065 = ( $head, $tail, $rules, $nterm, $term, 1066 $nullable, $precterm, $syms, $start, $expect); 1067 1068 undef($input); 1069 undef($lexlevel); 1070 undef(@lineno); 1071 undef($nberr); 1072 undef($prec); 1073 undef($labelno); 1074 1075 undef($head); 1076 undef($tail); 1077 1078 undef($syms); 1079 undef($token); 1080 undef($term); 1081 undef($nterm); 1082 undef($rules); 1083 undef($precterm); 1084 1085 undef($start); 1086 undef($nullable); 1087 undef($expect); 1088 1089 $parsed 1090} 1091 1092 10931; 1094