#!/usr/local/bin/perl use warnings; use strict; use Parse::Eyapp; my $grammar = q{ %prefix R::S:: %right '=' %left '-' '+' %left '*' '/' %left NEG %tree bypass alias %% line: $exp { $_[1] } ; exp: %name NUM $NUM | %name VAR $VAR | %name ASSIGN $VAR '=' $exp | %name PLUS exp.left '+' exp.right | %name MINUS exp.left '-' exp.right | %name TIMES exp.left '*' exp.right | %name DIV exp.left '/' exp.right | %no bypass UMINUS '-' $exp %prec NEG | '(' exp ')' { $_[2] } /* Let us simplify a bit the tree */ ; %% 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/^\s+//; 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, #yydebug =>0xFF ); } }; # end grammar Parse::Eyapp->new_grammar( input=>$grammar, classname=>'Alias', firstline =>7, outputfile => 'main', ); my $parser = Alias->new(); $parser->YYData->{INPUT} = "a = -(2*3+5-1)\n"; my $t = $parser->Run; $Parse::Eyapp::Node::INDENT=0; print $t->VAR->str."\n"; # a print "***************\n"; print $t->exp->exp->left->str."\n"; # 2*3+5 print "***************\n"; print $t->exp->exp->right->str."\n"; # 1