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