pl@nereida:~/LEyapp/examples$ cat -n CalcSimple.eyp 1 # CalcSimple.eyp 2 %right '=' 3 %left '-' '+' 4 %left '*' '/' 5 %left NEG 6 %right '^' 7 %{ 8 my %s; 9 %} 10 11 %% 12 start: input { [ $_[1], \%s] } 13 ; 14 15 input: 16 /* empty */ { [] } 17 | input line { push(@{$_[1]},$_[2]) if defined($_[2]); $_[1] } 18 ; 19 20 line: 21 '\n' { undef } 22 | $exp '\n' { print "$exp\n"; $exp } 23 | error '\n' { $_[0]->YYErrok; undef } 24 ; 25 26 exp: 27 NUM 28 | $VAR { $s{$VAR} } 29 | VAR.x '=' exp.y { $s{$x} = $y } 30 | exp.x '+' exp.y { $x + $y } 31 | exp.x '-' exp.y { $x - $y } 32 | exp.x '*' exp.y { $x * $y } 33 | exp.x '^' exp.y { $x ** $y } 34 | exp.x '/' exp.y 35 { 36 my $parser = shift; 37 38 $y and return($x / $y); 39 $parser->YYData->{ERRMSG} 40 = "Illegal division by zero.\n"; 41 $parser->YYError; 42 undef 43 } 44 | '-' $exp %prec NEG 45 { -$exp } 46 | '(' $exp ')' 47 { $exp } 48 ; 49 50 %% 51 52 sub _Error { 53 my $private = $_[0]->YYData; 54 55 exists $private->{ERRMSG} 56 and do { 57 print $private->{ERRMSG}; 58 delete $private->{ERRMSG}; 59 return; 60 }; 61 print "Syntax error.\n"; 62 } 63 64 my $input; 65 66 sub _Lexer { 67 my($parser)=shift; 68 69 # topicalize $input 70 for ($input) { 71 s/^[ \t]//; # skip whites 72 return('',undef) unless $_; 73 return('NUM',$1) if s{^([0-9]+(?:\.[0-9]+)?)}{}; 74 return('VAR',$1) if s/^([A-Za-z][A-Za-z0-9_]*)//; 75 return($1,$1) if s/^(.)//s; 76 } 77 78 return('',undef); 79 } 80 81 sub Run { 82 my($self)=shift; 83 84 $input = shift; 85 return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error, 86 #yydebug => 0xF 87 ); 88 }
Casiano Rodríguez León