File Coverage

blib/lib/XML/Filter/Dispatcher/Parser.pm
Criterion Covered Total %
statement 86 166 51.8
branch 32 72 44.4
condition 1 12 8.3
subroutine 11 24 45.8
pod n/a
total 130 274 47.4


line stmt bran cond sub pod time code
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             ####################################################################
10             package XML::Filter::Dispatcher::Parser;
11 1     1   5 use vars qw ( @ISA );
  1         2  
  1         44  
12 1     1   6 use strict;
  1         1  
  1         62  
13              
14             @ISA= qw ( Parse::Yapp::Driver );
15             #Included Parse/Yapp/Driver.pm file----------------------------------------
16             {
17             #
18             # Module Parse::Yapp::Driver
19             #
20             # This module is part of the Parse::Yapp package available on your
21             # nearest CPAN
22             #
23             # Any use of this module in a standalone parser make the included
24             # text under the same copyright as the Parse::Yapp module itself.
25             #
26             # This notice should remain unchanged.
27             #
28             # (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.
29             # (see the pod text in Parse::Yapp module for use and distribution rights)
30             #
31              
32             package Parse::Yapp::Driver;
33              
34             require 5.004;
35              
36 1     1   4 use strict;
  1         2  
  1         23  
37              
38 1     1   4 use vars qw ( $VERSION $COMPATIBLE $FILENAME );
  1         2  
  1         70  
39              
40             $VERSION = '1.05';
41             $COMPATIBLE = '0.07';
42             $FILENAME=__FILE__;
43              
44 1     1   10 use Carp;
  1         1  
  1         1141  
45              
46             #Known parameters, all starting with YY (leading YY will be discarded)
47             my(%params)=(YYLEX => 'CODE', 'YYERROR' => 'CODE', YYVERSION => '',
48             YYRULES => 'ARRAY', YYSTATES => 'ARRAY', YYDEBUG => '');
49             #Mandatory parameters
50             my(@params)=('LEX','RULES','STATES');
51              
52             sub new {
53 5     5   13 my($class)=shift;
54 5         6 my($errst,$nberr,$token,$value,$check,$dotpos);
55 5         59 my($self)={ ERROR => \&_Error,
56             ERRST => \$errst,
57             NBERR => \$nberr,
58             TOKEN => \$token,
59             VALUE => \$value,
60             DOTPOS => \$dotpos,
61             STACK => [],
62             DEBUG => 0,
63             CHECK => \$check };
64              
65 5         24 _CheckParams( [], \%params, \@_, $self );
66              
67 5 50 33     50 exists($$self{VERSION})
68             and $$self{VERSION} < $COMPATIBLE
69             and croak "Yapp driver version $VERSION ".
70             "incompatible with version $$self{VERSION}:\n".
71             "Please recompile parser module.";
72              
73 5 50       12 ref($class)
74             and $class=ref($class);
75              
76 5         70 bless($self,$class);
77             }
78              
79             sub YYParse {
80 5     5   9 my($self)=shift;
81 5         7 my($retval);
82              
83 5         118 _CheckParams( \@params, \%params, \@_, $self );
84              
85 5 50       19 if($$self{DEBUG}) {
86 0         0 _DBLoad();
87 0         0 $retval = eval '$self->_DBParse()';#Do not create stab entry on compile
88 0 0       0 $@ and die $@;
89             }
90             else {
91 5         20 $retval = $self->_Parse();
92             }
93 5         18 $retval
94             }
95              
96             sub YYData {
97 0     0   0 my($self)=shift;
98              
99 0 0       0 exists($$self{USER})
100             or $$self{USER}={};
101              
102 0         0 $$self{USER};
103            
104             }
105              
106             sub YYErrok {
107 0     0   0 my($self)=shift;
108              
109 0         0 ${$$self{ERRST}}=0;
  0         0  
110 0         0 undef;
111             }
112              
113             sub YYNberr {
114 0     0   0 my($self)=shift;
115              
116 0         0 ${$$self{NBERR}};
  0         0  
117             }
118              
119             sub YYRecovering {
120 0     0   0 my($self)=shift;
121              
122 0         0 ${$$self{ERRST}} != 0;
  0         0  
123             }
124              
125             sub YYAbort {
126 0     0   0 my($self)=shift;
127              
128 0         0 ${$$self{CHECK}}='ABORT';
  0         0  
129 0         0 undef;
130             }
131              
132             sub YYAccept {
133 5     5   10 my($self)=shift;
134              
135 5         8 ${$$self{CHECK}}='ACCEPT';
  5         12  
136 5         10 undef;
137             }
138              
139             sub YYError {
140 0     0   0 my($self)=shift;
141              
142 0         0 ${$$self{CHECK}}='ERROR';
  0         0  
143 0         0 undef;
144             }
145              
146             sub YYSemval {
147 0     0   0 my($self)=shift;
148 0         0 my($index)= $_[0] - ${$$self{DOTPOS}} - 1;
  0         0  
149              
150 0         0 $index < 0
151 0 0 0     0 and -$index <= @{$$self{STACK}}
152             and return $$self{STACK}[$index][1];
153              
154 0         0 undef; #Invalid index
155             }
156              
157             sub YYCurtok {
158 0     0   0 my($self)=shift;
159              
160             @_
161 0 0       0 and ${$$self{TOKEN}}=$_[0];
  0         0  
162 0         0 ${$$self{TOKEN}};
  0         0  
163             }
164              
165             sub YYCurval {
166 0     0   0 my($self)=shift;
167              
168             @_
169 0 0       0 and ${$$self{VALUE}}=$_[0];
  0         0  
170 0         0 ${$$self{VALUE}};
  0         0  
171             }
172              
173             sub YYExpect {
174 0     0   0 my($self)=shift;
175              
176 0         0 keys %{$self->{STATES}[$self->{STACK}[-1][0]]{ACTIONS}}
  0         0  
177             }
178              
179             sub YYLexer {
180 0     0   0 my($self)=shift;
181              
182 0         0 $$self{LEX};
183             }
184              
185              
186             #################
187             # Private stuff #
188             #################
189              
190              
191             sub _CheckParams {
192 10     10   20 my($mandatory,$checklist,$inarray,$outhash)=@_;
193 10         12 my($prm,$value);
194 10         16 my($prmlst)={};
195              
196 10         42 while(($prm,$value)=splice(@$inarray,0,2)) {
197 25         42 $prm=uc($prm);
198 25 50       59 exists($$checklist{$prm})
199             or croak("Unknow parameter '$prm'");
200 25 50       59 ref($value) eq $$checklist{$prm}
201             or croak("Invalid value for parameter '$prm'");
202 25         66 $prm=unpack('@2A*',$prm);
203 25         98 $$outhash{$prm}=$value;
204             }
205 10         35 for (@$mandatory) {
206 15 50       48 exists($$outhash{$_})
207             or croak("Missing mandatory parameter '".lc($_)."'");
208             }
209             }
210              
211             sub _Error {
212 0     0   0 print "Parse error.\n";
213             }
214              
215             sub _DBLoad {
216             {
217 1     1   6 no strict 'refs';
  1     0   2  
  1         1283  
  0         0  
218              
219 0 0       0 exists(${__PACKAGE__.'::'}{_DBParse})#Already loaded ?
  0         0  
220             and return;
221             }
222 0         0 my($fname)=__FILE__;
223 0         0 my(@drv);
224 0 0       0 open(DRV,"<$fname") or die "Report this as a BUG: Cannot open $fname";
225 0         0 while() {
226             /^\s*sub\s+_Parse\s*{\s*$/ .. /^\s*}\s*#\s*_Parse\s*$/
227 0 0       0 and do {
228 0         0 s/^#DBG>//;
229 0         0 push(@drv,$_);
230             }
231             }
232 0         0 close(DRV);
233              
234 0         0 $drv[0]=~s/_P/_DBP/;
235 0         0 eval join('',@drv);
236             }
237              
238             #Note that for loading debugging version of the driver,
239             #this file will be parsed from 'sub _Parse' up to '}#_Parse' inclusive.
240             #So, DO NOT remove comment at end of sub !!!
241             sub _Parse {
242 5     5   11 my($self)=shift;
243              
244 5         17 my($rules,$states,$lex,$error)
245             = @$self{ 'RULES', 'STATES', 'LEX', 'ERROR' };
246 5         17 my($errstatus,$nberror,$token,$value,$stack,$check,$dotpos)
247             = @$self{ 'ERRST', 'NBERR', 'TOKEN', 'VALUE', 'STACK', 'CHECK', 'DOTPOS' };
248              
249             #DBG> my($debug)=$$self{DEBUG};
250             #DBG> my($dbgerror)=0;
251              
252             #DBG> my($ShowCurToken) = sub {
253             #DBG> my($tok)='>';
254             #DBG> for (split('',$$token)) {
255             #DBG> $tok.= (ord($_) < 32 or ord($_) > 126)
256             #DBG> ? sprintf('<%02X>',ord($_))
257             #DBG> : $_;
258             #DBG> }
259             #DBG> $tok.='<';
260             #DBG> };
261              
262 5         10 $$errstatus=0;
263 5         7 $$nberror=0;
264 5         12 ($$token,$$value)=(undef,undef);
265 5         17 @$stack=( [ 0, undef ] );
266 5         8 $$check='';
267              
268 5         7 while(1) {
269 95         107 my($actions,$act,$stateno);
270              
271 95         128 $stateno=$$stack[-1][0];
272 95         121 $actions=$$states[$stateno];
273              
274             #DBG> print STDERR ('-' x 40),"\n";
275             #DBG> $debug & 0x2
276             #DBG> and print STDERR "In state $stateno:\n";
277             #DBG> $debug & 0x08
278             #DBG> and print STDERR "Stack:[".
279             #DBG> join(',',map { $$_[0] } @$stack).
280             #DBG> "]\n";
281              
282              
283 95 100       179 if (exists($$actions{ACTIONS})) {
284              
285             defined($$token)
286 60 100       193 or do {
287 10         27 ($$token,$$value)=&$lex($self);
288             #DBG> $debug & 0x01
289             #DBG> and print STDERR "Need token. Got ".&$ShowCurToken."\n";
290             };
291              
292 60 50       209 $act= exists($$actions{ACTIONS}{$$token})
    100          
293             ? $$actions{ACTIONS}{$$token}
294             : exists($$actions{DEFAULT})
295             ? $$actions{DEFAULT}
296             : undef;
297             }
298             else {
299 35         53 $act=$$actions{DEFAULT};
300             #DBG> $debug & 0x01
301             #DBG> and print STDERR "Don't need token.\n";
302             }
303              
304             defined($act)
305 95 50       196 and do {
306              
307             $act > 0
308 95 100       2054 and do { #shift
309              
310             #DBG> $debug & 0x04
311             #DBG> and print STDERR "Shift and go to state $act.\n";
312              
313             $$errstatus
314 10 50       22 and do {
315 0         0 --$$errstatus;
316              
317             #DBG> $debug & 0x10
318             #DBG> and $dbgerror
319             #DBG> and $$errstatus == 0
320             #DBG> and do {
321             #DBG> print STDERR "**End of Error recovery.\n";
322             #DBG> $dbgerror=0;
323             #DBG> };
324             };
325              
326              
327 10         26 push(@$stack,[ $act, $$value ]);
328              
329 10 100       29 $$token ne '' #Don't eat the eof
330             and $$token=$$value=undef;
331 10         13 next;
332             };
333              
334             #reduce
335 85         95 my($lhs,$len,$code,@sempar,$semval);
336 85         81 ($lhs,$len,$code)=@{$$rules[-$act]};
  85         212  
337              
338             #DBG> $debug & 0x04
339             #DBG> and $act
340             #DBG> and print STDERR "Reduce using rule ".-$act." ($lhs,$len): ";
341              
342 85 100       770 $act
343             or $self->YYAccept();
344              
345 85         100 $$dotpos=$len;
346              
347             unpack('A1',$lhs) eq '@' #In line rule
348 85 50       239 and do {
349 0 0       0 $lhs =~ /^\@[0-9]+\-([0-9]+)$/
350             or die "In line rule name '$lhs' ill formed: ".
351             "report it as a BUG.\n";
352 0         0 $$dotpos = $1;
353             };
354              
355 90         414 @sempar = $$dotpos
356 85 100       585 ? map { $$_[1] } @$stack[ -$$dotpos .. -1 ]
357             : ();
358              
359 85 100       230 $semval = $code ? &$code( $self, @sempar )
    100          
360             : @sempar ? $sempar[0] : undef;
361              
362 85         135 splice(@$stack,-$len,$len);
363              
364             $$check eq 'ACCEPT'
365 85 100       383 and do {
366              
367             #DBG> $debug & 0x04
368             #DBG> and print STDERR "Accept.\n";
369              
370 5         20 return($semval);
371             };
372              
373             $$check eq 'ABORT'
374 80 50       154 and do {
375              
376             #DBG> $debug & 0x04
377             #DBG> and print STDERR "Abort.\n";
378              
379 0         0 return(undef);
380              
381             };
382              
383             #DBG> $debug & 0x04
384             #DBG> and print STDERR "Back to state $$stack[-1][0], then ";
385              
386             $$check eq 'ERROR'
387 80 50       156 or do {
388             #DBG> $debug & 0x04
389             #DBG> and print STDERR
390             #DBG> "go to state $$states[$$stack[-1][0]]{GOTOS}{$lhs}.\n";
391              
392             #DBG> $debug & 0x10
393             #DBG> and $dbgerror
394             #DBG> and $$errstatus == 0
395             #DBG> and do {
396             #DBG> print STDERR "**End of Error recovery.\n";
397             #DBG> $dbgerror=0;
398             #DBG> };
399              
400 80         274 push(@$stack,
401             [ $$states[$$stack[-1][0]]{GOTOS}{$lhs}, $semval ]);
402 80         111 $$check='';
403 80         342 next;
404             };
405              
406             #DBG> $debug & 0x04
407             #DBG> and print STDERR "Forced Error recovery.\n";
408              
409 0           $$check='';
410              
411             };
412              
413             #Error
414             $$errstatus
415 0 0         or do {
416              
417 0           $$errstatus = 1;
418 0           &$error($self);
419 0 0         $$errstatus # if 0, then YYErrok has been called
420             or next; # so continue parsing
421              
422             #DBG> $debug & 0x10
423             #DBG> and do {
424             #DBG> print STDERR "**Entering Error recovery.\n";
425             #DBG> ++$dbgerror;
426             #DBG> };
427              
428 0           ++$$nberror;
429              
430             };
431              
432             $$errstatus == 3 #The next token is not valid: discard it
433 0 0         and do {
434             $$token eq '' # End of input: no hope
435 0 0         and do {
436             #DBG> $debug & 0x10
437             #DBG> and print STDERR "**At eof: aborting.\n";
438 0           return(undef);
439             };
440              
441             #DBG> $debug & 0x10
442             #DBG> and print STDERR "**Dicard invalid token ".&$ShowCurToken.".\n";
443              
444 0           $$token=$$value=undef;
445             };
446              
447 0           $$errstatus=3;
448              
449 0   0       while( @$stack
      0        
450             and ( not exists($$states[$$stack[-1][0]]{ACTIONS})
451             or not exists($$states[$$stack[-1][0]]{ACTIONS}{error})
452             or $$states[$$stack[-1][0]]{ACTIONS}{error} <= 0)) {
453              
454             #DBG> $debug & 0x10
455             #DBG> and print STDERR "**Pop state $$stack[-1][0].\n";
456              
457 0           pop(@$stack);
458             }
459              
460             @$stack
461 0 0         or do {
462              
463             #DBG> $debug & 0x10
464             #DBG> and print STDERR "**No state left on stack: aborting.\n";
465              
466 0           return(undef);
467             };
468              
469             #shift the error token
470              
471             #DBG> $debug & 0x10
472             #DBG> and print STDERR "**Shift \$error token and go to state ".
473             #DBG> $$states[$$stack[-1][0]]{ACTIONS}{error}.
474             #DBG> ".\n";
475              
476 0           push(@$stack, [ $$states[$$stack[-1][0]]{ACTIONS}{error}, undef ]);
477              
478             }
479              
480             #never reached
481 0           croak("Error in driver logic. Please, report it as a BUG");
482              
483             }#_Parse
484             #DO NOT remove comment
485              
486             1;
487              
488             }
489             #End of include--------------------------------------------------
490              
491              
492             #line 9 "xfdxpath.yp"
493              
494             use Carp;
495             use UNIVERSAL;
496             use XML::Filter::Dispatcher::Ops;
497              
498             sub _no {
499             my $p = shift;
500             # push @{$p->{USER}->{NONONO}}, join(
501             die join(
502             "",
503             "XPath construct not supported: ",
504             join( " ", map
505             defined $_
506             ? ref $_
507             ? do {
508             my $f = ref $_;
509             $f =~ s/^XFD:://;
510             $f;
511             }
512             : $_
513             : "" ,
514             @_
515             ),
516             " (grammar rule at ",
517             (caller)[1],
518             ", line ",
519             (caller)[2],
520             ")"
521             );
522              
523             return ();
524             }
525              
526             sub _step {
527             my @ops = grep $_, @_;
528              
529             for ( 0..$#ops-1 ) {
530             $ops[$_]->set_next( $ops[$_+1] );
531             }
532            
533             return $ops[0];
534             }
535              
536              
537             sub new {
538             my($class)=shift;
539             ref($class)
540             and $class=ref($class);
541              
542             my($self)=$class->SUPER::new( yyversion => '1.05',
543             yystates =>
544             [
545             {#State 0
546             ACTIONS => {
547             'DOT_DOT' => 1,
548             'MINUS' => 4,
549             'SLASH_SLASH' => 2,
550             'AT' => 7,
551             'LITERAL' => 8,
552             'SLASH' => 11,
553             'NUMBER' => 15,
554             'FUNCTION_NAME' => 16,
555             'DOT' => 17,
556             'DOLLAR_QNAME' => 19,
557             'LPAR' => 21,
558             'AXIS_NAME' => 26
559             },
560             DEFAULT => -45,
561             GOTOS => {
562             'and_expr' => 18,
563             'absolute_location_path' => 3,
564             'or_expr' => 20,
565             'equality_expr' => 6,
566             'relative_location_path' => 5,
567             'path_expr' => 9,
568             'axis' => 10,
569             'step' => 12,
570             'expr' => 13,
571             'additive_expr' => 22,
572             'location_path' => 14,
573             'unary_expr' => 23,
574             'primary_expr' => 24,
575             'union_expr' => 25,
576             'relational_expr' => 28,
577             'multiplicative_expr' => 27
578             }
579             },
580             {#State 1
581             DEFAULT => -44
582             },
583             {#State 2
584             ACTIONS => {
585             'DOT_DOT' => 1,
586             'DOT' => 17,
587             'AT' => 7,
588             'AXIS_NAME' => 26
589             },
590             DEFAULT => -45,
591             GOTOS => {
592             'step' => 12,
593             'relative_location_path' => 29,
594             'axis' => 10
595             }
596             },
597             {#State 3
598             DEFAULT => -35
599             },
600             {#State 4
601             ACTIONS => {
602             'DOT_DOT' => 1,
603             'MINUS' => 4,
604             'SLASH_SLASH' => 2,
605             'AT' => 7,
606             'LITERAL' => 8,
607             'SLASH' => 11,
608             'NUMBER' => 15,
609             'FUNCTION_NAME' => 16,
610             'DOT' => 17,
611             'DOLLAR_QNAME' => 19,
612             'LPAR' => 21,
613             'AXIS_NAME' => 26
614             },
615             DEFAULT => -45,
616             GOTOS => {
617             'absolute_location_path' => 3,
618             'relative_location_path' => 5,
619             'path_expr' => 9,
620             'axis' => 10,
621             'step' => 12,
622             'location_path' => 14,
623             'primary_expr' => 24,
624             'unary_expr' => 30,
625             'union_expr' => 25
626             }
627             },
628             {#State 5
629             ACTIONS => {
630             'SLASH_SLASH' => 31,
631             'SLASH' => 32
632             },
633             DEFAULT => -34
634             },
635             {#State 6
636             ACTIONS => {
637             'BANG_EQUALS' => 35,
638             'EQUALS_EQUALS' => 34,
639             'EQUALS' => 33
640             },
641             DEFAULT => -5
642             },
643             {#State 7
644             DEFAULT => -47
645             },
646             {#State 8
647             DEFAULT => -52
648             },
649             {#State 9
650             DEFAULT => -27
651             },
652             {#State 10
653             ACTIONS => {
654             'TEXT' => 38,
655             'NAME_COLON_STAR' => 36,
656             'QNAME' => 40,
657             'STAR' => 42,
658             'PI' => 41,
659             'COMMENT' => 37,
660             'NODE' => 39
661             },
662             GOTOS => {
663             'node_test' => 43
664             }
665             },
666             {#State 11
667             ACTIONS => {
668             'NAME_COLON_STAR' => -45,
669             'AT' => 7,
670             'COMMENT' => -45,
671             'DOT' => 17,
672             'STAR' => -45,
673             'AXIS_NAME' => 26,
674             'DOT_DOT' => 1,
675             'TEXT' => -45,
676             'NODE' => -45,
677             'QNAME' => -45,
678             'PI' => -45
679             },
680             DEFAULT => -36,
681             GOTOS => {
682             'step' => 12,
683             'relative_location_path' => 44,
684             'axis' => 10
685             }
686             },
687             {#State 12
688             DEFAULT => -39
689             },
690             {#State 13
691             ACTIONS => {
692             '' => 45
693             }
694             },
695             {#State 14
696             DEFAULT => -29
697             },
698             {#State 15
699             DEFAULT => -53
700             },
701             {#State 16
702             ACTIONS => {
703             'LPAR' => 46
704             }
705             },
706             {#State 17
707             DEFAULT => -43
708             },
709             {#State 18
710             ACTIONS => {
711             'AMP_AMP' => 47,
712             'AMP' => 48,
713             'AND' => 49
714             },
715             DEFAULT => -2
716             },
717             {#State 19
718             DEFAULT => -50
719             },
720             {#State 20
721             ACTIONS => {
722             'VBAR_VBAR' => 50,
723             'OR' => 51
724             },
725             DEFAULT => -1
726             },
727             {#State 21
728             ACTIONS => {
729             'DOT_DOT' => 1,
730             'MINUS' => 4,
731             'SLASH_SLASH' => 2,
732             'AT' => 7,
733             'LITERAL' => 8,
734             'SLASH' => 11,
735             'NUMBER' => 15,
736             'FUNCTION_NAME' => 16,
737             'DOT' => 17,
738             'DOLLAR_QNAME' => 19,
739             'LPAR' => 21,
740             'AXIS_NAME' => 26
741             },
742             DEFAULT => -45,
743             GOTOS => {
744             'and_expr' => 18,
745             'absolute_location_path' => 3,
746             'or_expr' => 20,
747             'equality_expr' => 6,
748             'relative_location_path' => 5,
749             'path_expr' => 9,
750             'axis' => 10,
751             'step' => 12,
752             'expr' => 52,
753             'additive_expr' => 22,
754             'location_path' => 14,
755             'primary_expr' => 24,
756             'unary_expr' => 23,
757             'union_expr' => 25,
758             'relational_expr' => 28,
759             'multiplicative_expr' => 27
760             }
761             },
762             {#State 22
763             ACTIONS => {
764             'MINUS' => 53,
765             'PLUS' => 54
766             },
767             DEFAULT => -13
768             },
769             {#State 23
770             DEFAULT => -21
771             },
772             {#State 24
773             DEFAULT => -48,
774             GOTOS => {
775             'predicates' => 55
776             }
777             },
778             {#State 25
779             ACTIONS => {
780             'VBAR' => 56
781             },
782             DEFAULT => -25
783             },
784             {#State 26
785             ACTIONS => {
786             'COLON_COLON' => 57
787             }
788             },
789             {#State 27
790             ACTIONS => {
791             'MULTIPLY' => 58,
792             'MOD' => 59,
793             'DIV' => 60
794             },
795             DEFAULT => -18
796             },
797             {#State 28
798             ACTIONS => {
799             'LTE' => 63,
800             'LT' => 64,
801             'GTE' => 61,
802             'GT' => 62
803             },
804             DEFAULT => -9
805             },
806             {#State 29
807             ACTIONS => {
808             'SLASH_SLASH' => 31,
809             'SLASH' => 32
810             },
811             DEFAULT => -38
812             },
813             {#State 30
814             DEFAULT => -26
815             },
816             {#State 31
817             ACTIONS => {
818             'DOT_DOT' => 1,
819             'DOT' => 17,
820             'AT' => 7,
821             'AXIS_NAME' => 26
822             },
823             DEFAULT => -45,
824             GOTOS => {
825             'step' => 65,
826             'axis' => 10
827             }
828             },
829             {#State 32
830             ACTIONS => {
831             'DOT_DOT' => 1,
832             'DOT' => 17,
833             'AT' => 7,
834             'AXIS_NAME' => 26
835             },
836             DEFAULT => -45,
837             GOTOS => {
838             'step' => 66,
839             'axis' => 10
840             }
841             },
842             {#State 33
843             ACTIONS => {
844             'DOT_DOT' => 1,
845             'MINUS' => 4,
846             'SLASH_SLASH' => 2,
847             'AT' => 7,
848             'LITERAL' => 8,
849             'SLASH' => 11,
850             'NUMBER' => 15,
851             'FUNCTION_NAME' => 16,
852             'DOT' => 17,
853             'DOLLAR_QNAME' => 19,
854             'LPAR' => 21,
855             'AXIS_NAME' => 26
856             },
857             DEFAULT => -45,
858             GOTOS => {
859             'absolute_location_path' => 3,
860             'relative_location_path' => 5,
861             'path_expr' => 9,
862             'axis' => 10,
863             'step' => 12,
864             'additive_expr' => 22,
865             'location_path' => 14,
866             'primary_expr' => 24,
867             'unary_expr' => 23,
868             'union_expr' => 25,
869             'relational_expr' => 67,
870             'multiplicative_expr' => 27
871             }
872             },
873             {#State 34
874             ACTIONS => {
875             'DOT_DOT' => 1,
876             'MINUS' => 4,
877             'SLASH_SLASH' => 2,
878             'AT' => 7,
879             'LITERAL' => 8,
880             'SLASH' => 11,
881             'NUMBER' => 15,
882             'FUNCTION_NAME' => 16,
883             'DOT' => 17,
884             'DOLLAR_QNAME' => 19,
885             'LPAR' => 21,
886             'AXIS_NAME' => 26
887             },
888             DEFAULT => -45,
889             GOTOS => {
890             'absolute_location_path' => 3,
891             'relative_location_path' => 5,
892             'path_expr' => 9,
893             'axis' => 10,
894             'step' => 12,
895             'additive_expr' => 22,
896             'location_path' => 14,
897             'primary_expr' => 24,
898             'unary_expr' => 23,
899             'union_expr' => 25,
900             'relational_expr' => 68,
901             'multiplicative_expr' => 27
902             }
903             },
904             {#State 35
905             ACTIONS => {
906             'DOT_DOT' => 1,
907             'MINUS' => 4,
908             'SLASH_SLASH' => 2,
909             'AT' => 7,
910             'LITERAL' => 8,
911             'SLASH' => 11,
912             'NUMBER' => 15,
913             'FUNCTION_NAME' => 16,
914             'DOT' => 17,
915             'DOLLAR_QNAME' => 19,
916             'LPAR' => 21,
917             'AXIS_NAME' => 26
918             },
919             DEFAULT => -45,
920             GOTOS => {
921             'absolute_location_path' => 3,
922             'relative_location_path' => 5,
923             'path_expr' => 9,
924             'axis' => 10,
925             'step' => 12,
926             'additive_expr' => 22,
927             'location_path' => 14,
928             'primary_expr' => 24,
929             'unary_expr' => 23,
930             'union_expr' => 25,
931             'relational_expr' => 69,
932             'multiplicative_expr' => 27
933             }
934             },
935             {#State 36
936             DEFAULT => -61
937             },
938             {#State 37
939             ACTIONS => {
940             'LPAR' => 70
941             }
942             },
943             {#State 38
944             ACTIONS => {
945             'LPAR' => 71
946             }
947             },
948             {#State 39
949             ACTIONS => {
950             'LPAR' => 72
951             }
952             },
953             {#State 40
954             DEFAULT => -59
955             },
956             {#State 41
957             ACTIONS => {
958             'LPAR' => 73
959             }
960             },
961             {#State 42
962             DEFAULT => -60
963             },
964             {#State 43
965             DEFAULT => -48,
966             GOTOS => {
967             'predicates' => 74
968             }
969             },
970             {#State 44
971             ACTIONS => {
972             'SLASH_SLASH' => 31,
973             'SLASH' => 32
974             },
975             DEFAULT => -37
976             },
977             {#State 45
978             DEFAULT => 0
979             },
980             {#State 46
981             ACTIONS => {
982             'DOT_DOT' => 1,
983             'MINUS' => 4,
984             'SLASH_SLASH' => 2,
985             'AT' => 7,
986             'LITERAL' => 8,
987             'SLASH' => 11,
988             'NUMBER' => 15,
989             'FUNCTION_NAME' => 16,
990             'DOT' => 17,
991             'DOLLAR_QNAME' => 19,
992             'LPAR' => 21,
993             'AXIS_NAME' => 26,
994             'RPAR' => -55
995             },
996             DEFAULT => -45,
997             GOTOS => {
998             'and_expr' => 18,
999             'absolute_location_path' => 3,
1000             'or_expr' => 20,
1001             'equality_expr' => 6,
1002             'relative_location_path' => 5,
1003             'args' => 75,
1004             'opt_args' => 77,
1005             'path_expr' => 9,
1006             'axis' => 10,
1007             'step' => 12,
1008             'expr' => 76,
1009             'additive_expr' => 22,
1010             'location_path' => 14,
1011             'primary_expr' => 24,
1012             'unary_expr' => 23,
1013             'union_expr' => 25,
1014             'relational_expr' => 28,
1015             'multiplicative_expr' => 27
1016             }
1017             },
1018             {#State 47
1019             ACTIONS => {
1020             'DOT_DOT' => 1,
1021             'MINUS' => 4,
1022             'SLASH_SLASH' => 2,
1023             'AT' => 7,
1024             'LITERAL' => 8,
1025             'SLASH' => 11,
1026             'NUMBER' => 15,
1027             'FUNCTION_NAME' => 16,
1028             'DOT' => 17,
1029             'DOLLAR_QNAME' => 19,
1030             'LPAR' => 21,
1031             'AXIS_NAME' => 26
1032             },
1033             DEFAULT => -45,
1034             GOTOS => {
1035             'absolute_location_path' => 3,
1036             'equality_expr' => 78,
1037             'relative_location_path' => 5,
1038             'path_expr' => 9,
1039             'axis' => 10,
1040             'step' => 12,
1041             'additive_expr' => 22,
1042             'location_path' => 14,
1043             'primary_expr' => 24,
1044             'unary_expr' => 23,
1045             'union_expr' => 25,
1046             'relational_expr' => 28,
1047             'multiplicative_expr' => 27
1048             }
1049             },
1050             {#State 48
1051             ACTIONS => {
1052             'DOT_DOT' => 1,
1053             'MINUS' => 4,
1054             'SLASH_SLASH' => 2,
1055             'AT' => 7,
1056             'LITERAL' => 8,
1057             'SLASH' => 11,
1058             'NUMBER' => 15,
1059             'FUNCTION_NAME' => 16,
1060             'DOT' => 17,
1061             'DOLLAR_QNAME' => 19,
1062             'LPAR' => 21,
1063             'AXIS_NAME' => 26
1064             },
1065             DEFAULT => -45,
1066             GOTOS => {
1067             'absolute_location_path' => 3,
1068             'equality_expr' => 79,
1069             'relative_location_path' => 5,
1070             'path_expr' => 9,
1071             'axis' => 10,
1072             'step' => 12,
1073             'additive_expr' => 22,
1074             'location_path' => 14,
1075             'primary_expr' => 24,
1076             'unary_expr' => 23,
1077             'union_expr' => 25,
1078             'relational_expr' => 28,
1079             'multiplicative_expr' => 27
1080             }
1081             },
1082             {#State 49
1083             ACTIONS => {
1084             'DOT_DOT' => 1,
1085             'MINUS' => 4,
1086             'SLASH_SLASH' => 2,
1087             'AT' => 7,
1088             'LITERAL' => 8,
1089             'SLASH' => 11,
1090             'NUMBER' => 15,
1091             'FUNCTION_NAME' => 16,
1092             'DOT' => 17,
1093             'DOLLAR_QNAME' => 19,
1094             'LPAR' => 21,
1095             'AXIS_NAME' => 26
1096             },
1097             DEFAULT => -45,
1098             GOTOS => {
1099             'absolute_location_path' => 3,
1100             'equality_expr' => 80,
1101             'relative_location_path' => 5,
1102             'path_expr' => 9,
1103             'axis' => 10,
1104             'step' => 12,
1105             'additive_expr' => 22,
1106             'location_path' => 14,
1107             'primary_expr' => 24,
1108             'unary_expr' => 23,
1109             'union_expr' => 25,
1110             'relational_expr' => 28,
1111             'multiplicative_expr' => 27
1112             }
1113             },
1114             {#State 50
1115             ACTIONS => {
1116             'DOT_DOT' => 1,
1117             'MINUS' => 4,
1118             'SLASH_SLASH' => 2,
1119             'AT' => 7,
1120             'LITERAL' => 8,
1121             'SLASH' => 11,
1122             'NUMBER' => 15,
1123             'FUNCTION_NAME' => 16,
1124             'DOT' => 17,
1125             'DOLLAR_QNAME' => 19,
1126             'LPAR' => 21,
1127             'AXIS_NAME' => 26
1128             },
1129             DEFAULT => -45,
1130             GOTOS => {
1131             'and_expr' => 81,
1132             'absolute_location_path' => 3,
1133             'equality_expr' => 6,
1134             'relative_location_path' => 5,
1135             'path_expr' => 9,
1136             'axis' => 10,
1137             'step' => 12,
1138             'additive_expr' => 22,
1139             'location_path' => 14,
1140             'primary_expr' => 24,
1141             'unary_expr' => 23,
1142             'union_expr' => 25,
1143             'relational_expr' => 28,
1144             'multiplicative_expr' => 27
1145             }
1146             },
1147             {#State 51
1148             ACTIONS => {
1149             'DOT_DOT' => 1,
1150             'MINUS' => 4,
1151             'SLASH_SLASH' => 2,
1152             'AT' => 7,
1153             'LITERAL' => 8,
1154             'SLASH' => 11,
1155             'NUMBER' => 15,
1156             'FUNCTION_NAME' => 16,
1157             'DOT' => 17,
1158             'DOLLAR_QNAME' => 19,
1159             'LPAR' => 21,
1160             'AXIS_NAME' => 26
1161             },
1162             DEFAULT => -45,
1163             GOTOS => {
1164             'and_expr' => 82,
1165             'absolute_location_path' => 3,
1166             'equality_expr' => 6,
1167             'relative_location_path' => 5,
1168             'path_expr' => 9,
1169             'axis' => 10,
1170             'step' => 12,
1171             'additive_expr' => 22,
1172             'location_path' => 14,
1173             'primary_expr' => 24,
1174             'unary_expr' => 23,
1175             'union_expr' => 25,
1176             'relational_expr' => 28,
1177             'multiplicative_expr' => 27
1178             }
1179             },
1180             {#State 52
1181             ACTIONS => {
1182             'RPAR' => 83
1183             }
1184             },
1185             {#State 53
1186             ACTIONS => {
1187             'DOT_DOT' => 1,
1188             'MINUS' => 4,
1189             'SLASH_SLASH' => 2,
1190             'AT' => 7,
1191             'LITERAL' => 8,
1192             'SLASH' => 11,
1193             'NUMBER' => 15,
1194             'FUNCTION_NAME' => 16,
1195             'DOT' => 17,
1196             'DOLLAR_QNAME' => 19,
1197             'LPAR' => 21,
1198             'AXIS_NAME' => 26
1199             },
1200             DEFAULT => -45,
1201             GOTOS => {
1202             'absolute_location_path' => 3,
1203             'relative_location_path' => 5,
1204             'path_expr' => 9,
1205             'axis' => 10,
1206             'step' => 12,
1207             'location_path' => 14,
1208             'primary_expr' => 24,
1209             'unary_expr' => 23,
1210             'union_expr' => 25,
1211             'multiplicative_expr' => 84
1212             }
1213             },
1214             {#State 54
1215             ACTIONS => {
1216             'DOT_DOT' => 1,
1217             'MINUS' => 4,
1218             'SLASH_SLASH' => 2,
1219             'AT' => 7,
1220             'LITERAL' => 8,
1221             'SLASH' => 11,
1222             'NUMBER' => 15,
1223             'FUNCTION_NAME' => 16,
1224             'DOT' => 17,
1225             'DOLLAR_QNAME' => 19,
1226             'LPAR' => 21,
1227             'AXIS_NAME' => 26
1228             },
1229             DEFAULT => -45,
1230             GOTOS => {
1231             'absolute_location_path' => 3,
1232             'relative_location_path' => 5,
1233             'path_expr' => 9,
1234             'axis' => 10,
1235             'step' => 12,
1236             'location_path' => 14,
1237             'primary_expr' => 24,
1238             'unary_expr' => 23,
1239             'union_expr' => 25,
1240             'multiplicative_expr' => 85
1241             }
1242             },
1243             {#State 55
1244             ACTIONS => {
1245             'SLASH_SLASH' => 86,
1246             'SLASH' => 88,
1247             'LSQB' => 89
1248             },
1249             DEFAULT => -31,
1250             GOTOS => {
1251             'segment' => 87
1252             }
1253             },
1254             {#State 56
1255             ACTIONS => {
1256             'DOT_DOT' => 1,
1257             'SLASH_SLASH' => 2,
1258             'AT' => 7,
1259             'LITERAL' => 8,
1260             'SLASH' => 11,
1261             'NUMBER' => 15,
1262             'FUNCTION_NAME' => 16,
1263             'DOT' => 17,
1264             'DOLLAR_QNAME' => 19,
1265             'LPAR' => 21,
1266             'AXIS_NAME' => 26
1267             },
1268             DEFAULT => -45,
1269             GOTOS => {
1270             'step' => 12,
1271             'absolute_location_path' => 3,
1272             'primary_expr' => 24,
1273             'location_path' => 14,
1274             'relative_location_path' => 5,
1275             'path_expr' => 90,
1276             'axis' => 10
1277             }
1278             },
1279             {#State 57
1280             DEFAULT => -46
1281             },
1282             {#State 58
1283             ACTIONS => {
1284             'DOT_DOT' => 1,
1285             'MINUS' => 4,
1286             'SLASH_SLASH' => 2,
1287             'AT' => 7,
1288             'LITERAL' => 8,
1289             'SLASH' => 11,
1290             'NUMBER' => 15,
1291             'FUNCTION_NAME' => 16,
1292             'DOT' => 17,
1293             'DOLLAR_QNAME' => 19,
1294             'LPAR' => 21,
1295             'AXIS_NAME' => 26
1296             },
1297             DEFAULT => -45,
1298             GOTOS => {
1299             'absolute_location_path' => 3,
1300             'relative_location_path' => 5,
1301             'path_expr' => 9,
1302             'axis' => 10,
1303             'step' => 12,
1304             'location_path' => 14,
1305             'primary_expr' => 24,
1306             'unary_expr' => 91,
1307             'union_expr' => 25
1308             }
1309             },
1310             {#State 59
1311             ACTIONS => {
1312             'DOT_DOT' => 1,
1313             'MINUS' => 4,
1314             'SLASH_SLASH' => 2,
1315             'AT' => 7,
1316             'LITERAL' => 8,
1317             'SLASH' => 11,
1318             'NUMBER' => 15,
1319             'FUNCTION_NAME' => 16,
1320             'DOT' => 17,
1321             'DOLLAR_QNAME' => 19,
1322             'LPAR' => 21,
1323             'AXIS_NAME' => 26
1324             },
1325             DEFAULT => -45,
1326             GOTOS => {
1327             'absolute_location_path' => 3,
1328             'relative_location_path' => 5,
1329             'path_expr' => 9,
1330             'axis' => 10,
1331             'step' => 12,
1332             'location_path' => 14,
1333             'primary_expr' => 24,
1334             'unary_expr' => 92,
1335             'union_expr' => 25
1336             }
1337             },
1338             {#State 60
1339             ACTIONS => {
1340             'DOT_DOT' => 1,
1341             'MINUS' => 4,
1342             'SLASH_SLASH' => 2,
1343             'AT' => 7,
1344             'LITERAL' => 8,
1345             'SLASH' => 11,
1346             'NUMBER' => 15,
1347             'FUNCTION_NAME' => 16,
1348             'DOT' => 17,
1349             'DOLLAR_QNAME' => 19,
1350             'LPAR' => 21,
1351             'AXIS_NAME' => 26
1352             },
1353             DEFAULT => -45,
1354             GOTOS => {
1355             'absolute_location_path' => 3,
1356             'relative_location_path' => 5,
1357             'path_expr' => 9,
1358             'axis' => 10,
1359             'step' => 12,
1360             'location_path' => 14,
1361             'primary_expr' => 24,
1362             'unary_expr' => 93,
1363             'union_expr' => 25
1364             }
1365             },
1366             {#State 61
1367             ACTIONS => {
1368             'DOT_DOT' => 1,
1369             'MINUS' => 4,
1370             'SLASH_SLASH' => 2,
1371             'AT' => 7,
1372             'LITERAL' => 8,
1373             'SLASH' => 11,
1374             'NUMBER' => 15,
1375             'FUNCTION_NAME' => 16,
1376             'DOT' => 17,
1377             'DOLLAR_QNAME' => 19,
1378             'LPAR' => 21,
1379             'AXIS_NAME' => 26
1380             },
1381             DEFAULT => -45,
1382             GOTOS => {
1383             'absolute_location_path' => 3,
1384             'relative_location_path' => 5,
1385             'path_expr' => 9,
1386             'axis' => 10,
1387             'step' => 12,
1388             'additive_expr' => 94,
1389             'location_path' => 14,
1390             'primary_expr' => 24,
1391             'unary_expr' => 23,
1392             'union_expr' => 25,
1393             'multiplicative_expr' => 27
1394             }
1395             },
1396             {#State 62
1397             ACTIONS => {
1398             'DOT_DOT' => 1,
1399             'MINUS' => 4,
1400             'SLASH_SLASH' => 2,
1401             'AT' => 7,
1402             'LITERAL' => 8,
1403             'SLASH' => 11,
1404             'NUMBER' => 15,
1405             'FUNCTION_NAME' => 16,
1406             'DOT' => 17,
1407             'DOLLAR_QNAME' => 19,
1408             'LPAR' => 21,
1409             'AXIS_NAME' => 26
1410             },
1411             DEFAULT => -45,
1412             GOTOS => {
1413             'absolute_location_path' => 3,
1414             'relative_location_path' => 5,
1415             'path_expr' => 9,
1416             'axis' => 10,
1417             'step' => 12,
1418             'additive_expr' => 95,
1419             'location_path' => 14,
1420             'primary_expr' => 24,
1421             'unary_expr' => 23,
1422             'union_expr' => 25,
1423             'multiplicative_expr' => 27
1424             }
1425             },
1426             {#State 63
1427             ACTIONS => {
1428             'DOT_DOT' => 1,
1429             'MINUS' => 4,
1430             'SLASH_SLASH' => 2,
1431             'AT' => 7,
1432             'LITERAL' => 8,
1433             'SLASH' => 11,
1434             'NUMBER' => 15,
1435             'FUNCTION_NAME' => 16,
1436             'DOT' => 17,
1437             'DOLLAR_QNAME' => 19,
1438             'LPAR' => 21,
1439             'AXIS_NAME' => 26
1440             },
1441             DEFAULT => -45,
1442             GOTOS => {
1443             'absolute_location_path' => 3,
1444             'relative_location_path' => 5,
1445             'path_expr' => 9,
1446             'axis' => 10,
1447             'step' => 12,
1448             'additive_expr' => 96,
1449             'location_path' => 14,
1450             'primary_expr' => 24,
1451             'unary_expr' => 23,
1452             'union_expr' => 25,
1453             'multiplicative_expr' => 27
1454             }
1455             },
1456             {#State 64
1457             ACTIONS => {
1458             'DOT_DOT' => 1,
1459             'MINUS' => 4,
1460             'SLASH_SLASH' => 2,
1461             'AT' => 7,
1462             'LITERAL' => 8,
1463             'SLASH' => 11,
1464             'NUMBER' => 15,
1465             'FUNCTION_NAME' => 16,
1466             'DOT' => 17,
1467             'DOLLAR_QNAME' => 19,
1468             'LPAR' => 21,
1469             'AXIS_NAME' => 26
1470             },
1471             DEFAULT => -45,
1472             GOTOS => {
1473             'absolute_location_path' => 3,
1474             'relative_location_path' => 5,
1475             'path_expr' => 9,
1476             'axis' => 10,
1477             'step' => 12,
1478             'additive_expr' => 97,
1479             'location_path' => 14,
1480             'primary_expr' => 24,
1481             'unary_expr' => 23,
1482             'union_expr' => 25,
1483             'multiplicative_expr' => 27
1484             }
1485             },
1486             {#State 65
1487             DEFAULT => -41
1488             },
1489             {#State 66
1490             DEFAULT => -40
1491             },
1492             {#State 67
1493             ACTIONS => {
1494             'LTE' => 63,
1495             'LT' => 64,
1496             'GTE' => 61,
1497             'GT' => 62
1498             },
1499             DEFAULT => -10
1500             },
1501             {#State 68
1502             ACTIONS => {
1503             'LTE' => 63,
1504             'LT' => 64,
1505             'GTE' => 61,
1506             'GT' => 62
1507             },
1508             DEFAULT => -12
1509             },
1510             {#State 69
1511             ACTIONS => {
1512             'LTE' => 63,
1513             'LT' => 64,
1514             'GTE' => 61,
1515             'GT' => 62
1516             },
1517             DEFAULT => -11
1518             },
1519             {#State 70
1520             ACTIONS => {
1521             'RPAR' => 98
1522             }
1523             },
1524             {#State 71
1525             ACTIONS => {
1526             'RPAR' => 99
1527             }
1528             },
1529             {#State 72
1530             ACTIONS => {
1531             'RPAR' => 100
1532             }
1533             },
1534             {#State 73
1535             ACTIONS => {
1536             'LITERAL' => 101
1537             },
1538             DEFAULT => -66,
1539             GOTOS => {
1540             'opt_literal' => 102
1541             }
1542             },
1543             {#State 74
1544             ACTIONS => {
1545             'LSQB' => 89
1546             },
1547             DEFAULT => -42
1548             },
1549             {#State 75
1550             ACTIONS => {
1551             'COMMA' => 103
1552             },
1553             DEFAULT => -56
1554             },
1555             {#State 76
1556             DEFAULT => -57
1557             },
1558             {#State 77
1559             ACTIONS => {
1560             'RPAR' => 104
1561             }
1562             },
1563             {#State 78
1564             ACTIONS => {
1565             'BANG_EQUALS' => 35,
1566             'EQUALS_EQUALS' => 34,
1567             'EQUALS' => 33
1568             },
1569             DEFAULT => -7
1570             },
1571             {#State 79
1572             ACTIONS => {
1573             'BANG_EQUALS' => 35,
1574             'EQUALS_EQUALS' => 34,
1575             'EQUALS' => 33
1576             },
1577             DEFAULT => -8
1578             },
1579             {#State 80
1580             ACTIONS => {
1581             'BANG_EQUALS' => 35,
1582             'EQUALS_EQUALS' => 34,
1583             'EQUALS' => 33
1584             },
1585             DEFAULT => -6
1586             },
1587             {#State 81
1588             ACTIONS => {
1589             'AMP_AMP' => 47,
1590             'AMP' => 48,
1591             'AND' => 49
1592             },
1593             DEFAULT => -4
1594             },
1595             {#State 82
1596             ACTIONS => {
1597             'AMP_AMP' => 47,
1598             'AMP' => 48,
1599             'AND' => 49
1600             },
1601             DEFAULT => -3
1602             },
1603             {#State 83
1604             DEFAULT => -51
1605             },
1606             {#State 84
1607             ACTIONS => {
1608             'MULTIPLY' => 58,
1609             'MOD' => 59,
1610             'DIV' => 60
1611             },
1612             DEFAULT => -20
1613             },
1614             {#State 85
1615             ACTIONS => {
1616             'MULTIPLY' => 58,
1617             'MOD' => 59,
1618             'DIV' => 60
1619             },
1620             DEFAULT => -19
1621             },
1622             {#State 86
1623             ACTIONS => {
1624             'DOT_DOT' => 1,
1625             'DOT' => 17,
1626             'AT' => 7,
1627             'AXIS_NAME' => 26
1628             },
1629             DEFAULT => -45,
1630             GOTOS => {
1631             'step' => 12,
1632             'relative_location_path' => 105,
1633             'axis' => 10
1634             }
1635             },
1636             {#State 87
1637             DEFAULT => -30
1638             },
1639             {#State 88
1640             ACTIONS => {
1641             'DOT_DOT' => 1,
1642             'DOT' => 17,
1643             'AT' => 7,
1644             'AXIS_NAME' => 26
1645             },
1646             DEFAULT => -45,
1647             GOTOS => {
1648             'step' => 12,
1649             'relative_location_path' => 106,
1650             'axis' => 10
1651             }
1652             },
1653             {#State 89
1654             ACTIONS => {
1655             'DOT_DOT' => 1,
1656             'MINUS' => 4,
1657             'SLASH_SLASH' => 2,
1658             'AT' => 7,
1659             'LITERAL' => 8,
1660             'SLASH' => 11,
1661             'NUMBER' => 15,
1662             'FUNCTION_NAME' => 16,
1663             'DOT' => 17,
1664             'DOLLAR_QNAME' => 19,
1665             'LPAR' => 21,
1666             'AXIS_NAME' => 26
1667             },
1668             DEFAULT => -45,
1669             GOTOS => {
1670             'and_expr' => 18,
1671             'absolute_location_path' => 3,
1672             'or_expr' => 20,
1673             'equality_expr' => 6,
1674             'relative_location_path' => 5,
1675             'path_expr' => 9,
1676             'axis' => 10,
1677             'step' => 12,
1678             'expr' => 107,
1679             'additive_expr' => 22,
1680             'location_path' => 14,
1681             'primary_expr' => 24,
1682             'unary_expr' => 23,
1683             'union_expr' => 25,
1684             'relational_expr' => 28,
1685             'multiplicative_expr' => 27
1686             }
1687             },
1688             {#State 90
1689             DEFAULT => -28
1690             },
1691             {#State 91
1692             DEFAULT => -22
1693             },
1694             {#State 92
1695             DEFAULT => -24
1696             },
1697             {#State 93
1698             DEFAULT => -23
1699             },
1700             {#State 94
1701             ACTIONS => {
1702             'MINUS' => 53,
1703             'PLUS' => 54
1704             },
1705             DEFAULT => -17
1706             },
1707             {#State 95
1708             ACTIONS => {
1709             'MINUS' => 53,
1710             'PLUS' => 54
1711             },
1712             DEFAULT => -15
1713             },
1714             {#State 96
1715             ACTIONS => {
1716             'MINUS' => 53,
1717             'PLUS' => 54
1718             },
1719             DEFAULT => -16
1720             },
1721             {#State 97
1722             ACTIONS => {
1723             'MINUS' => 53,
1724             'PLUS' => 54
1725             },
1726             DEFAULT => -14
1727             },
1728             {#State 98
1729             DEFAULT => -63
1730             },
1731             {#State 99
1732             DEFAULT => -64
1733             },
1734             {#State 100
1735             DEFAULT => -65
1736             },
1737             {#State 101
1738             DEFAULT => -67
1739             },
1740             {#State 102
1741             ACTIONS => {
1742             'RPAR' => 108
1743             }
1744             },
1745             {#State 103
1746             ACTIONS => {
1747             'DOT_DOT' => 1,
1748             'MINUS' => 4,
1749             'SLASH_SLASH' => 2,
1750             'AT' => 7,
1751             'LITERAL' => 8,
1752             'SLASH' => 11,
1753             'NUMBER' => 15,
1754             'FUNCTION_NAME' => 16,
1755             'DOT' => 17,
1756             'DOLLAR_QNAME' => 19,
1757             'LPAR' => 21,
1758             'AXIS_NAME' => 26
1759             },
1760             DEFAULT => -45,
1761             GOTOS => {
1762             'and_expr' => 18,
1763             'absolute_location_path' => 3,
1764             'or_expr' => 20,
1765             'equality_expr' => 6,
1766             'relative_location_path' => 5,
1767             'path_expr' => 9,
1768             'axis' => 10,
1769             'step' => 12,
1770             'expr' => 109,
1771             'additive_expr' => 22,
1772             'location_path' => 14,
1773             'primary_expr' => 24,
1774             'unary_expr' => 23,
1775             'union_expr' => 25,
1776             'relational_expr' => 28,
1777             'multiplicative_expr' => 27
1778             }
1779             },
1780             {#State 104
1781             DEFAULT => -54
1782             },
1783             {#State 105
1784             ACTIONS => {
1785             'SLASH_SLASH' => 31,
1786             'SLASH' => 32
1787             },
1788             DEFAULT => -33
1789             },
1790             {#State 106
1791             ACTIONS => {
1792             'SLASH_SLASH' => 31,
1793             'SLASH' => 32
1794             },
1795             DEFAULT => -32
1796             },
1797             {#State 107
1798             ACTIONS => {
1799             'RSQB' => 110
1800             }
1801             },
1802             {#State 108
1803             DEFAULT => -62
1804             },
1805             {#State 109
1806             DEFAULT => -58
1807             },
1808             {#State 110
1809             DEFAULT => -49
1810             }
1811             ],
1812             yyrules =>
1813             [
1814             [#Rule 0
1815             '$start', 2, undef
1816             ],
1817             [#Rule 1
1818             'expr', 1, undef
1819             ],
1820             [#Rule 2
1821             'or_expr', 1, undef
1822             ],
1823             [#Rule 3
1824             'or_expr', 3,
1825             sub
1826             #line 107 "xfdxpath.yp"
1827             { XFD::Operator::or->new( @_[1,3] ) }
1828             ],
1829             [#Rule 4
1830             'or_expr', 3,
1831             sub
1832             #line 108 "xfdxpath.yp"
1833             {
1834             die "XPath uses 'or' instead of Perl's '||'\n";
1835             }
1836             ],
1837             [#Rule 5
1838             'and_expr', 1, undef
1839             ],
1840             [#Rule 6
1841             'and_expr', 3,
1842             sub
1843             #line 115 "xfdxpath.yp"
1844             { XFD::Operator::and->new( @_[1,3] ) }
1845             ],
1846             [#Rule 7
1847             'and_expr', 3,
1848             sub
1849             #line 116 "xfdxpath.yp"
1850             {
1851             die "XPath uses 'and' instead of Perl's '&&'\n";
1852             }
1853             ],
1854             [#Rule 8
1855             'and_expr', 3,
1856             sub
1857             #line 119 "xfdxpath.yp"
1858             {
1859             die "XPath uses 'and' instead of Perl's '&'\n";
1860             }
1861             ],
1862             [#Rule 9
1863             'equality_expr', 1, undef
1864             ],
1865             [#Rule 10
1866             'equality_expr', 3,
1867             sub
1868             #line 126 "xfdxpath.yp"
1869             { XFD::relational_op equals => @_[1,3] }
1870             ],
1871             [#Rule 11
1872             'equality_expr', 3,
1873             sub
1874             #line 127 "xfdxpath.yp"
1875             { XFD::relational_op not_equals => @_[1,3] }
1876             ],
1877             [#Rule 12
1878             'equality_expr', 3,
1879             sub
1880             #line 128 "xfdxpath.yp"
1881             {
1882             die "XPath uses '=' instead of Perl's '=='\n";
1883             }
1884             ],
1885             [#Rule 13
1886             'relational_expr', 1, undef
1887             ],
1888             [#Rule 14
1889             'relational_expr', 3,
1890             sub
1891             #line 135 "xfdxpath.yp"
1892             { XFD::relational_op lt => @_[1,3] }
1893             ],
1894             [#Rule 15
1895             'relational_expr', 3,
1896             sub
1897             #line 136 "xfdxpath.yp"
1898             { XFD::relational_op gt => @_[1,3] }
1899             ],
1900             [#Rule 16
1901             'relational_expr', 3,
1902             sub
1903             #line 137 "xfdxpath.yp"
1904             { XFD::relational_op lte => @_[1,3] }
1905             ],
1906             [#Rule 17
1907             'relational_expr', 3,
1908             sub
1909             #line 138 "xfdxpath.yp"
1910             { XFD::relational_op gte => @_[1,3] }
1911             ],
1912             [#Rule 18
1913             'additive_expr', 1, undef
1914             ],
1915             [#Rule 19
1916             'additive_expr', 3,
1917             sub
1918             #line 143 "xfdxpath.yp"
1919             { XFD::math_op addition => @_[1,3] }
1920             ],
1921             [#Rule 20
1922             'additive_expr', 3,
1923             sub
1924             #line 144 "xfdxpath.yp"
1925             { XFD::math_op subtraction => @_[1,3] }
1926             ],
1927             [#Rule 21
1928             'multiplicative_expr', 1, undef
1929             ],
1930             [#Rule 22
1931             'multiplicative_expr', 3,
1932             sub
1933             #line 149 "xfdxpath.yp"
1934             { XFD::math_op multiplication => @_[1,3] }
1935             ],
1936             [#Rule 23
1937             'multiplicative_expr', 3,
1938             sub
1939             #line 150 "xfdxpath.yp"
1940             { XFD::math_op division => @_[1,3] }
1941             ],
1942             [#Rule 24
1943             'multiplicative_expr', 3,
1944             sub
1945             #line 151 "xfdxpath.yp"
1946             { XFD::math_op modulus => @_[1,3] }
1947             ],
1948             [#Rule 25
1949             'unary_expr', 1, undef
1950             ],
1951             [#Rule 26
1952             'unary_expr', 2,
1953             sub
1954             #line 156 "xfdxpath.yp"
1955             { XFD::Negation->new( $_[2] ) }
1956             ],
1957             [#Rule 27
1958             'union_expr', 1, undef
1959             ],
1960             [#Rule 28
1961             'union_expr', 3,
1962             sub
1963             #line 161 "xfdxpath.yp"
1964             {
1965             for ( $_[1], $_[3] ) {
1966             next if $_->can( "set_next" );
1967             $_ = ref $_;
1968             s/^XFD:://;
1969             die "Can't use a $_ in a union, perhaps you want || instead of |\n";
1970             }
1971              
1972             my $union;
1973             if ( $_[1]->isa( "XFD::union" ) ) {
1974             $_[1]->add( $_[3] );
1975             $union = $_[1];
1976             }
1977             else {
1978             $union = XFD::union->new( @_[1,3] )
1979             }
1980             $union;
1981             }
1982             ],
1983             [#Rule 29
1984             'path_expr', 1, undef
1985             ],
1986             [#Rule 30
1987             'path_expr', 3,
1988             sub
1989             #line 183 "xfdxpath.yp"
1990             {
1991             return $_[1] unless defined $_[2] || defined $_[3];
1992              
1993             my $expr = $_[1];
1994             $expr = $expr->[0] if $expr->isa( "XFD::Parens" );
1995              
1996             ## TODO: Cope with nodesets passed in vars or
1997             ## returned from functions.
1998             die "node-set is required before a predicate or '/' (variables and functions returning nodesets are not (yet) supported)"
1999             unless $expr->isa( "XFD::PathTest" );
2000              
2001             $expr->set_next( $_[2] ) if defined $_[2];
2002             $expr->set_next( $_[3] ) if defined $_[3];
2003             $expr;
2004             }
2005             ],
2006             [#Rule 31
2007             'segment', 0, undef
2008             ],
2009             [#Rule 32
2010             'segment', 2,
2011             sub
2012             #line 202 "xfdxpath.yp"
2013             { $_[2] }
2014             ],
2015             [#Rule 33
2016             'segment', 2,
2017             sub
2018             #line 203 "xfdxpath.yp"
2019             {
2020             my $op = XFD::Axis::descendant_or_self->new;
2021             $op->set_next( $_[2] );
2022             $op;
2023             }
2024             ],
2025             [#Rule 34
2026             'location_path', 1, undef
2027             ],
2028             [#Rule 35
2029             'location_path', 1, undef
2030             ],
2031             [#Rule 36
2032             'absolute_location_path', 1,
2033             sub
2034             #line 215 "xfdxpath.yp"
2035             { XFD::doc_node->new }
2036             ],
2037             [#Rule 37
2038             'absolute_location_path', 2,
2039             sub
2040             #line 216 "xfdxpath.yp"
2041             {
2042             my $op = XFD::doc_node->new;
2043             $op->set_next( $_[2] );
2044             $op;
2045             }
2046             ],
2047             [#Rule 38
2048             'absolute_location_path', 2,
2049             sub
2050             #line 221 "xfdxpath.yp"
2051             {
2052             ## /descendant-or-self::node()/relative_location_path
2053             my $op = XFD::doc_node->new;
2054             my $step = _step(
2055             XFD::Axis::descendant_or_self->new,
2056             XFD::EventType::node->new,
2057             );
2058             $op->set_next( $step );
2059             $step->set_next( $_[2] );
2060             $op;
2061             }
2062             ],
2063             [#Rule 39
2064             'relative_location_path', 1, undef
2065             ],
2066             [#Rule 40
2067             'relative_location_path', 3,
2068             sub
2069             #line 235 "xfdxpath.yp"
2070             { $_[1]->set_next( $_[3] ) ; $_[1] }
2071             ],
2072             [#Rule 41
2073             'relative_location_path', 3,
2074             sub
2075             #line 238 "xfdxpath.yp"
2076             {
2077             my $step = _step(
2078             XFD::Axis::descendant_or_self->new,
2079             XFD::EventType::node->new,
2080             );
2081             $_[1]->set_next( $step );
2082             $step->set_next( $_[3] );
2083             $_[1];
2084             }
2085             ],
2086             [#Rule 42
2087             'step', 3,
2088             sub
2089             #line 250 "xfdxpath.yp"
2090             { _step( @_[1..$#_] ) }
2091             ],
2092             [#Rule 43
2093             'step', 1,
2094             sub
2095             #line 251 "xfdxpath.yp"
2096             { XFD::self_node->new }
2097             ],
2098             [#Rule 44
2099             'step', 1,
2100             sub
2101             #line 252 "xfdxpath.yp"
2102             { _no @_; }
2103             ],
2104             [#Rule 45
2105             'axis', 0,
2106             sub
2107             #line 256 "xfdxpath.yp"
2108             { XFD::Axis::child->new }
2109             ],
2110             [#Rule 46
2111             'axis', 2,
2112             sub
2113             #line 257 "xfdxpath.yp"
2114             { XFD::axis( $_[1] ) }
2115             ],
2116             [#Rule 47
2117             'axis', 1,
2118             sub
2119             #line 258 "xfdxpath.yp"
2120             { XFD::Axis::attribute->new }
2121             ],
2122             [#Rule 48
2123             'predicates', 0, undef
2124             ],
2125             [#Rule 49
2126             'predicates', 4,
2127             sub
2128             #line 263 "xfdxpath.yp"
2129             {
2130             my $p = XFD::predicate->new( $_[3] );
2131             if ( defined $_[1] ) {
2132             $_[1]->set_next( $p );
2133             return $_[1];
2134             }
2135             return $p;
2136             }
2137             ],
2138             [#Rule 50
2139             'primary_expr', 1,
2140             sub
2141             #line 274 "xfdxpath.yp"
2142             { XFD::VariableReference->new( $_[1] ) }
2143             ],
2144             [#Rule 51
2145             'primary_expr', 3,
2146             sub
2147             #line 275 "xfdxpath.yp"
2148             { XFD::Parens->new( $_[2] ) }
2149             ],
2150             [#Rule 52
2151             'primary_expr', 1, undef
2152             ],
2153             [#Rule 53
2154             'primary_expr', 1, undef
2155             ],
2156             [#Rule 54
2157             'primary_expr', 4,
2158             sub
2159             #line 278 "xfdxpath.yp"
2160             { XFD::function( @_[1,3] ) }
2161             ],
2162             [#Rule 55
2163             'opt_args', 0,
2164             sub
2165             #line 282 "xfdxpath.yp"
2166             { [] }
2167             ],
2168             [#Rule 56
2169             'opt_args', 1, undef
2170             ],
2171             [#Rule 57
2172             'args', 1,
2173             sub
2174             #line 287 "xfdxpath.yp"
2175             { [ $_[1] ] }
2176             ],
2177             [#Rule 58
2178             'args', 3,
2179             sub
2180             #line 288 "xfdxpath.yp"
2181             {
2182             push @{$_[1]}, $_[3];
2183             $_[1];
2184             }
2185             ],
2186             [#Rule 59
2187             'node_test', 1,
2188             sub
2189             #line 295 "xfdxpath.yp"
2190             {
2191             $XFD::dispatcher->{Namespaces}
2192             ? do {
2193             my ( $ns_uri, $local_name ) =
2194             XFD::PathTest->_parse_ns_uri_and_localname( $_[1] );
2195              
2196             my $op = XFD::namespace_test->new( $ns_uri );
2197             $op->set_next(
2198             XFD::node_local_name->new( $local_name )
2199             );
2200             $op;
2201             }
2202             : XFD::node_name->new( $_[1] );
2203             }
2204             ],
2205             [#Rule 60
2206             'node_test', 1,
2207             sub
2208             #line 309 "xfdxpath.yp"
2209             { XFD::EventType::principal_event_type->new; }
2210             ],
2211             [#Rule 61
2212             'node_test', 1,
2213             sub
2214             #line 310 "xfdxpath.yp"
2215             {
2216             my ( $ns_uri ) =
2217             XFD::PathTest->_parse_ns_uri_and_localname( $_[1] );
2218             XFD::namespace_test->new( $ns_uri )
2219             }
2220             ],
2221             [#Rule 62
2222             'node_test', 4,
2223             sub
2224             #line 315 "xfdxpath.yp"
2225             { XFD::EventType::processing_instruction
2226             ->new( $_[2] ) }
2227             ],
2228             [#Rule 63
2229             'node_test', 3,
2230             sub
2231             #line 317 "xfdxpath.yp"
2232             { XFD::EventType::comment ->new }
2233             ],
2234             [#Rule 64
2235             'node_test', 3,
2236             sub
2237             #line 318 "xfdxpath.yp"
2238             { XFD::EventType::text ->new }
2239             ],
2240             [#Rule 65
2241             'node_test', 3,
2242             sub
2243             #line 319 "xfdxpath.yp"
2244             { XFD::EventType::node ->new }
2245             ],
2246             [#Rule 66
2247             'opt_literal', 0, undef
2248             ],
2249             [#Rule 67
2250             'opt_literal', 1,
2251             sub
2252             #line 324 "xfdxpath.yp"
2253             { _no @_; }
2254             ]
2255             ],
2256             @_);
2257             bless($self,$class);
2258             }
2259              
2260             #line 327 "xfdxpath.yp"
2261              
2262              
2263             =head1
2264              
2265             XML::Filter::Dispatcher::Parser - Parses the XPath subset used by ...::Dispatcher
2266              
2267             =head1 SYNOPSIS
2268              
2269             use XML::Filter::Dispatcher::Parser;
2270              
2271             my $result = XML::Filter::Dispatcher::Parser->parse( $xpath );
2272              
2273             =head1 DESCRIPTION
2274              
2275             Some notes on the parsing and evaluation:
2276              
2277             =over
2278              
2279             =item *
2280              
2281             Result Objects
2282              
2283             The result expressions alway return true or false. For XPath
2284             expressions that would normally return a node-set, the result is true if
2285             the current SAX event would build a node that would be in the node set.
2286             No floating point or string return objects are supported (this may
2287             change).
2288              
2289             =item *
2290              
2291             Context
2292              
2293             The XPath context node is the document root (theoretically; in reality
2294             there is none). The variables are the Dispatcher's data members, and
2295             the function library is XXX.
2296              
2297             Not sure what to do about the context position, but the context size is
2298             of necessity undefined.
2299              
2300             The namespace mapping will be added in when I grok the NamespaceHelper.
2301              
2302             =back
2303              
2304             =cut
2305              
2306             use Carp;
2307              
2308             my %tokens = (qw(
2309             . DOT
2310             .. DOT_DOT
2311             @ AT
2312             * STAR
2313             ( LPAR
2314             ) RPAR
2315             [ LSQB
2316             ] RSQB
2317             :: COLON_COLON
2318             / SLASH
2319             // SLASH_SLASH
2320             | VBAR
2321             + PLUS
2322             - MINUS
2323             = EQUALS
2324             != BANG_EQUALS
2325             > GT
2326             < LT
2327             >= GTE
2328             <= LTE
2329              
2330             == EQUALS_EQUALS
2331             || VBAR_VBAR
2332             && AMP_AMP
2333             & AMP
2334             ),
2335             "," => "COMMA"
2336             );
2337              
2338             my $simple_tokens =
2339             join "|",
2340             map
2341             quotemeta,
2342             reverse
2343             sort {
2344             length $a <=> length $b
2345             } keys %tokens;
2346              
2347             my $NCName = "(?:[a-zA-Z_][a-zA-Z0-9_.-]*)"; ## TODO: comb. chars & Extenders
2348              
2349             my %EventType = qw(
2350             node NODE
2351             text TEXT
2352             comment COMMENT
2353             processing-instruction PI
2354             );
2355              
2356             my $EventType = "(?:" .
2357             join( "|", map quotemeta, sort {length $a <=> length $b} keys %EventType ) .
2358             ")";
2359              
2360             my $AxisName = "(?:" . join( "|", split /\n+/, <
2361             ancestor
2362             ancestor-or-self
2363             attribute
2364             child
2365             descendant
2366             descendant-or-self
2367             following
2368             following-sibling
2369             namespace
2370             parent
2371             preceding
2372             preceding-sibling
2373             self
2374             end
2375             AXIS_LIST_END
2376              
2377             my %preceding_tokens = map { ( $_ => undef ) } ( qw(
2378             @ :: [
2379             and or mod div
2380             *
2381             / // | + - = != < <= > >=
2382              
2383             == & && ||
2384             ),
2385             "(", ","
2386             ) ;
2387              
2388              
2389             sub debugging () { 0 }
2390              
2391              
2392             sub lex {
2393             my ( $p ) = @_;
2394              
2395             ## Optimization notes: we aren't parsing War and Peace here, so
2396             ## readability over performance.
2397              
2398             my $d = $p->{USER};
2399             my $input = \$d->{Input};
2400              
2401             ## This needs to be more contextual, only recognizing axis/function-name
2402             if ( ( pos( $$input ) || 0 ) == length $$input ) {
2403             $d->{LastToken} = undef;
2404             return ( '', undef );
2405             }
2406              
2407             my ( $token, $val ) ;
2408             ## First do the disambiguation rules:
2409              
2410             ## If there is a preceding token and the preceding token is not
2411             ## one of "@", "::", "(", "[", "," or an Operator,
2412             if ( defined $d->{LastToken}
2413             && ! exists $preceding_tokens{$d->{LastToken}}
2414             ) {
2415             ## a * must be recognized as a MultiplyOperator
2416             if ( $$input =~ /\G\s*\*/gc ) {
2417             ( $token, $val ) = ( MULTIPLY => "*" );
2418             }
2419             ## an NCName must be recognized as an OperatorName.
2420             elsif ( $$input =~ /\G\s*($NCName)/gc ) {
2421             die "Expected and, or, mod or div, got '$1'\n"
2422             unless 0 <= index "and|or|mod|div", $1;
2423             ( $token, $val ) = ( uc $1, $1 );
2424             }
2425             }
2426              
2427             ## NOTE: \s is only an approximation for ExprWhitespace
2428             unless ( defined $token ) {
2429             $$input =~ m{\G\s*(?:
2430             ## If the character following an NCName (possibly after
2431             ## intervening ExprWhitespace) is (, then the token must be
2432             ## recognized as a EventType or a FunctionName.
2433             ($NCName)\s*(?=\()
2434              
2435             ## If the two characters following an NCName (possibly after
2436             ## intervening ExprWhitespace) are ::, then the token must be
2437             ## recognized as an AxisName
2438             |($NCName)\s*(?=::)
2439              
2440             ## Otherwise, it's just a normal lexer.
2441             |($NCName:\*) #NAME_COLON_STAR
2442             |((?:$NCName:)?$NCName) #QNAME
2443             |('[^']*'|"[^"]*") #LITERAL
2444             |(-?\d+(?:\.\d+)?|\.\d+) #NUMBER
2445             |\$((?:$NCName:)?$NCName) #DOLLAR_QNAME
2446             |($simple_tokens)
2447             )\s*}gcx;
2448              
2449             ( $token, $val ) =
2450             defined $1 ? (
2451             exists $EventType{$1}
2452             ? ( $EventType{$1}, $1 )
2453             : ( FUNCTION_NAME => $1 )
2454             ) :
2455            
2456             defined $2 ? ( AXIS_NAME => $2 ) :
2457             defined $3 ? ( NAME_COLON_STAR => $3 ) :
2458             defined $4 ? ( QNAME => $4 ) :
2459             defined $5 ? ( LITERAL => do {
2460             my $s = substr( $5, 1, -1 );
2461             $s =~ s/([\\'])/\\$1/g;
2462             XFD::StringConstant->new( $s );
2463             }
2464             ) :
2465             defined $6 ? ( NUMBER =>
2466             XFD::NumericConstant->new( "$6")
2467             ) :
2468             defined $7 ? ( DOLLAR_QNAME => $7 ) :
2469             defined $8 ? ( $tokens{$8} => $8 ) :
2470             die "Failed to parse '$$input' at ",
2471             pos $$input,
2472             "\n";
2473             }
2474              
2475             $d->{LastToken} = $val;
2476              
2477             if ( debugging ) {
2478             warn
2479             "'",
2480             $$input,
2481             "' (",
2482             pos $$input,
2483             "):",
2484             join( " => ", map defined $_ ? $_ : "", $token, $val ),
2485             "\n";
2486             }
2487              
2488             return ( $token, $val );
2489             }
2490              
2491              
2492             sub error {
2493             my ( $p ) = @_;
2494             print "Couldn't parse '$p->{USER}->{Input}' at position ", pos $p->{USER}->{Input}, "\n";
2495             }
2496              
2497             ## _parse is an internal, reentrant entry point; it's used to parse rules
2498             ## and subrules.
2499             sub _parse {
2500             my $self = shift;
2501             my ( $expr, $action_code ) = @_;
2502              
2503             my $options = $XFD::dispatcher;
2504              
2505             warn "Parsing '$expr'\n" if $options->{Debug};
2506              
2507             my $p = XML::Filter::Dispatcher::Parser->new(
2508             yylex => \&lex,
2509             yyerror => \&error,
2510             ( $options->{Debug} || 0 ) > 5
2511             ? ( yydebug => 0x1D )
2512             : (),
2513             );
2514              
2515             %{$p->{USER}} = %$options if $options;
2516             $p->{USER}->{Input} = $expr;
2517             local $XFD::dispatcher->{ParseNestingDepth}
2518             = $XFD::dispatcher->{ParseNestingDepth} + 1;
2519              
2520             my $op_tree = eval {
2521             $p->YYParse; ## <== the actual parse
2522             };
2523              
2524             die $@ if $@;
2525              
2526             die map "$_\n", @{$p->{USER}->{NONONO}}
2527             if $p->{USER}->{NONONO} ;
2528              
2529             return undef unless defined $op_tree;
2530              
2531             die "grammar returned '$op_tree', needed a ref\n"
2532             unless ref $op_tree;
2533              
2534             ## TODO: figure a way to allow a limited subset
2535             ## of EventPath patterns, kinda like allowing
2536             ## a pattern match against the generated Op tree,
2537             ## or alternate grammar files. The former could
2538             ## give more helpful error messages, the latter
2539             ## could be more flexible because it would allow
2540             ## non-standard grammars.
2541             $op_tree = XFD::ExprEval->new( $op_tree )
2542             unless $op_tree->isa( "XFD::PathTest" );
2543              
2544             $op_tree->set_next( XFD::action( $action_code ) );
2545              
2546             return $op_tree;
2547             }
2548              
2549              
2550             sub parse {
2551             my $self = shift;
2552             local $XFD::dispatcher = shift;
2553             my ( $expr, $context ) = @_;
2554              
2555             $XFD::dispatcher->{ParseNestingDepth} = 0;
2556             $XFD::dispatcher->{OpTree} ||= XFD::union->new;
2557              
2558             my $op_tree = $self->_parse( @_ );
2559              
2560             my $rule = XFD::Rule->new( $expr );
2561             $rule->set_next( $op_tree );
2562             $XFD::dispatcher->{OpTree}->add( $rule );
2563             }
2564              
2565             1 ;
2566              
2567             1;