yapp -v myParser.yp #### 1 shift/reduce conflict #### $^W=0; use Parse::Yapp; my($parser,$grammar); my($yapptxt); $grammar=join('',); $parser=new Parse::Yapp(input => $grammar); $yapptxt=$parser->Output(classname => 'MyParser'); eval $yapptxt; my($parser); $parser=new MyParser(); $parser->YYData->{DATA}= [ "a and B\n" ]; $data=$parser->YYData->{DATA}[0]; print "data=[$data]\n"; exit; __DATA__ %% CCLFind: CCLFind Op Elements | Elements ; Op: 'and' | 'or' | 'not' ; # -- The above means that Elements are separated by boolean operators. Elements: '(' CCLFind ')' #! | Set | Terms | Qualifiers Relation Terms | Qualifiers Relation '(' CCLFind ')' | Qualifiers '=' string '-' string ; # -- Elements is either a recursive definition, a result set reference, a # -- list of terms, qualifiers followed by terms, qualifiers followed # -- by a recursive definition or qualifiers in a range (lower - upper). #!Set: 'set' = string #!; # -- Reference to a result set Terms: Terms Prox Term | Term ; # -- Proximity of terms. Term: Term string | string ; # -- This basically means that a term may include a blank Qualifiers: Qualifiers ',' string | string ; # -- Qualifiers is a list of strings separated by comma Relation: '=' | '>=' | '<=' | '<>' | '>' | '<' ; # -- Relational operators. This really doesn't follow the ISO8777 # -- standard. Prox: '%' | '!' ; # -- Proximity operator %% sub _Error { exists $_[0]->YYData->{ERRMSG} and do { print $_[0]->YYData->{ERRMSG}; delete $_[0]->YYData->{ERRMSG}; return; }; print "Syntax error.\n"; } sub _Lexer { my($parser)=shift; $parser->YYData->{INPUT} or $parser->YYData->{INPUT} = or return('',undef); $parser->YYData->{INPUT}=~s/^[ \t]//; for ($parser->YYData->{INPUT}) { s/^([0-9]+(?:\.[0-9]+)?)// and return('NUM',$1); s/^([A-Za-z][A-Za-z0-9_]*)// and return('VAR',$1); s/^(.)//s and return($1,$1); } } sub Run { my($self)=shift; $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error ); }