0148デフォルトの名無しさん
2020/04/15(水) 15:02:35.67ID:3oL83xUjsub evalop {
my (@list) = @{$_[0]};
my $val = shift(@list)->();
while (@list) {
my ($op, $arg2) = splice @list, 0, 2;
$op->($val,$arg2->());
} $val }
use Parse::RecDescent;
$parse = new Parse::RecDescent(<<'EOG');
formula: expr /\s*\Z/ {$item[1]->()} | <error>
expr: <leftop:muldiv add_op muldiv> {sub {::evalop $item[1]}}
add_op: '+' {sub {$_[0] += $_[1]}} | '-' {sub{ $_[0] -= $_[1]}}
muldiv: <leftop:factor mult_op factor> {sub {::evalop $item[1]}}
mult_op: '*' {sub {$_[0] *= $_[1]}} | '/' {sub {$_[0] /= $_[1]}}
factor: number | '(' expr ')' {$item[2]}
number: /\d+/ {sub {$item[1]}}
EOG
for (<DATA>) {
chomp;
$ret = defined ($iret = $parse->formula($_)) ? sprintf('%d', $iret) : 'Error';
printf "$_ = %s\n", $ret;
}
__DATA__
1+2*((3-4*5)/6+7)*8-9
100/2(3+4)
100/2*(3+4)
*10
1/3*3