1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
use v5.10;
use warnings;
my $calculator = do{
use Regexp::Grammars;
qr{
<Answer>
<rule: Answer>
<X=Mult> \+ <Y=Answer>
(?{ $MATCH = $MATCH{X} + $MATCH{Y}; })
| <X=Mult> - <Y=Answer>
(?{ $MATCH = $MATCH{X} - $MATCH{Y}; })
| <MATCH=Mult>
<rule: Mult>
<X=Pow> \* <Y=Mult>
(?{ $MATCH = $MATCH{X} * $MATCH{Y}; })
| <X=Pow> / <Y=Mult>
(?{ $MATCH = $MATCH{X} / $MATCH{Y}; })
| <X=Pow> % <Y=Mult>
(?{ $MATCH = $MATCH{X} % $MATCH{Y}; })
| <MATCH=Pow>
<rule: Pow>
<[Term]>+ % \^
(?{
$MATCH = 1;
$MATCH = $_ ** $MATCH for reverse @{$MATCH{Term}};
})
|
<MATCH=Term>
<rule: Term>
<MATCH=Literal>
| - \( <Answer> \) <MATCH= (?{ -1 * $MATCH{Answer} })>
| [+]? \( <MATCH=Answer> \)
<token: Literal>
<MATCH=( [+-]? \d++ (?: \. \d++ )?+ )>
}xms
};
while (my $input = <>) {
if ($input =~ $calculator) {
say '--> ', $/{Answer};
}
}
|