File: inline_computation.t

package info (click to toggle)
libregexp-grammars-perl 1.058-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,328 kB
  • sloc: perl: 53,328; makefile: 2
file content (57 lines) | stat: -rw-r--r-- 1,459 bytes parent folder | download | duplicates (7)
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
49
50
51
52
53
54
55
56
57
use 5.010;
use warnings;

use Test::More 'no_plan'; 

use List::Util qw< reduce >;

my $calculator = do{
    use Regexp::Grammars;
    qr{
        <Answer>

        <rule: Answer>
            <[Operand=Mult]> ** <[Op=(\+|\-)]>
                (?{ $MATCH = shift @{$MATCH{Operand}};
                    for my $term (@{$MATCH{Operand}}) {
                        my $op = shift @{$MATCH{Op}};
                        if ($op eq '+') { $MATCH += $term; }
                        else            { $MATCH -= $term; }
                    }
                })

        <rule: Mult>
            <[Operand=Pow]> ** <[Op=(\*|/|%)]>
                (?{ $MATCH = reduce { eval($a . shift(@{$MATCH{Op}}) . $b) }
                                    @{$MATCH{Operand}};
                })

        <rule: Pow>
            <[Operand=Term]> ** <Op=(\^)> 
                (?{ $MATCH = reduce { $b ** $a } reverse @{$MATCH{Operand}}; })

        <rule: Term>
               <MATCH=Literal>
          | \( <MATCH=Answer> \)

        <token: Literal>
            <MATCH=( [+-]? \d++ (?: \. \d++ )?+ )>
    }xms
};

while (my $input = <DATA>) {
    chomp $input;
    my ($expr, $result) = split /\s*=\s*/, $input;
    ok +($expr =~ $calculator) => "Matched expression: $expr";
    cmp_ok $/{Answer}, '==', $result => "Got right answer ($result)";
}

__DATA__
2^3*4+5   = 37
2+3*4^5   = 3074
2+3*4+5   = 19
2*3+4*5   = 26
2*(3+4)*5 = 70
2+3+4-5   = 4
100/10/2  = 5
100/10*2  = 20