File Coverage

blib/lib/Parse/Yapp/Parse.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


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