|
Packit |
292bd0 |
#
|
|
Packit |
292bd0 |
# Calc.yp
|
|
Packit |
292bd0 |
#
|
|
Packit |
292bd0 |
# Parse::Yapp input grammar example.
|
|
Packit |
292bd0 |
#
|
|
Packit |
292bd0 |
# This file is PUBLIC DOMAIN
|
|
Packit |
292bd0 |
#
|
|
Packit |
292bd0 |
#
|
|
Packit |
292bd0 |
%right '='
|
|
Packit |
292bd0 |
%left '-' '+'
|
|
Packit |
292bd0 |
%left '*' '/'
|
|
Packit |
292bd0 |
%left NEG
|
|
Packit |
292bd0 |
%right '^'
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
%%
|
|
Packit |
292bd0 |
input: #empty
|
|
Packit |
292bd0 |
| input line { push(@{$_[1]},$_[2]); $_[1] }
|
|
Packit |
292bd0 |
;
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
line: '\n' { $_[1] }
|
|
Packit |
292bd0 |
| exp '\n' { print "$_[1]\n" }
|
|
Packit |
292bd0 |
| error '\n' { $_[0]->YYErrok }
|
|
Packit |
292bd0 |
;
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
exp: NUM
|
|
Packit |
292bd0 |
| VAR { $_[0]->YYData->{VARS}{$_[1]} }
|
|
Packit |
292bd0 |
| VAR '=' exp { $_[0]->YYData->{VARS}{$_[1]}=$_[3] }
|
|
Packit |
292bd0 |
| exp '+' exp { $_[1] + $_[3] }
|
|
Packit |
292bd0 |
| exp '-' exp { $_[1] - $_[3] }
|
|
Packit |
292bd0 |
| exp '*' exp { $_[1] * $_[3] }
|
|
Packit |
292bd0 |
| exp '/' exp {
|
|
Packit |
292bd0 |
$_[3]
|
|
Packit |
292bd0 |
and return($_[1] / $_[3]);
|
|
Packit |
292bd0 |
$_[0]->YYData->{ERRMSG}
|
|
Packit |
292bd0 |
= "Illegal division by zero.\n";
|
|
Packit |
292bd0 |
$_[0]->YYError;
|
|
Packit |
292bd0 |
undef
|
|
Packit |
292bd0 |
}
|
|
Packit |
292bd0 |
| '-' exp %prec NEG { -$_[2] }
|
|
Packit |
292bd0 |
| exp '^' exp { $_[1] ** $_[3] }
|
|
Packit |
292bd0 |
| '(' exp ')' { $_[2] }
|
|
Packit |
292bd0 |
;
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
%%
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
sub _Error {
|
|
Packit |
292bd0 |
exists $_[0]->YYData->{ERRMSG}
|
|
Packit |
292bd0 |
and do {
|
|
Packit |
292bd0 |
print $_[0]->YYData->{ERRMSG};
|
|
Packit |
292bd0 |
delete $_[0]->YYData->{ERRMSG};
|
|
Packit |
292bd0 |
return;
|
|
Packit |
292bd0 |
};
|
|
Packit |
292bd0 |
print "Syntax error.\n";
|
|
Packit |
292bd0 |
}
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
sub _Lexer {
|
|
Packit |
292bd0 |
my($parser)=shift;
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
$parser->YYData->{INPUT}
|
|
Packit |
292bd0 |
or $parser->YYData->{INPUT} = <STDIN>
|
|
Packit |
292bd0 |
or return('',undef);
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
$parser->YYData->{INPUT}=~s/^[ \t]//;
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
for ($parser->YYData->{INPUT}) {
|
|
Packit |
292bd0 |
s/^([0-9]+(?:\.[0-9]+)?)//
|
|
Packit |
292bd0 |
and return('NUM',$1);
|
|
Packit |
292bd0 |
s/^([A-Za-z][A-Za-z0-9_]*)//
|
|
Packit |
292bd0 |
and return('VAR',$1);
|
|
Packit |
292bd0 |
s/^(.)//s
|
|
Packit |
292bd0 |
and return($1,$1);
|
|
Packit |
292bd0 |
}
|
|
Packit |
292bd0 |
}
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
sub Run {
|
|
Packit |
292bd0 |
my($self)=shift;
|
|
Packit |
292bd0 |
$self->YYParse( yylex => \&_Lexer, yyerror => \&_Error );
|
|
Packit |
292bd0 |
}
|
|
Packit |
292bd0 |
|
|
Packit |
292bd0 |
my($calc)=new Calc;
|
|
Packit |
292bd0 |
$calc->Run;
|