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 58 59 60 61 62 63 64 65 66 67 68
|
#!/usr/bin/perl
use v5.14;
use warnings;
package ExprParser;
use base qw( Parser::MGC );
use Syntax::Keyword::Try;
# An expression is a list of terms, joined by + or - operators
sub parse
{
my $self = shift;
my $val = $self->parse_term;
1 while $self->any_of(
sub { $self->expect( "+" ); $self->commit; $val += $self->parse_term; 1 },
sub { $self->expect( "-" ); $self->commit; $val -= $self->parse_term; 1 },
sub { 0 },
);
return $val;
}
# A term is a list of factors, joined by * or - operators
sub parse_term
{
my $self = shift;
my $val = $self->parse_factor;
1 while $self->any_of(
sub { $self->expect( "*" ); $self->commit; $val *= $self->parse_factor; 1 },
sub { $self->expect( "/" ); $self->commit; $val /= $self->parse_factor; 1 },
sub { 0 },
);
return $val;
}
# A factor is either a parenthesized expression, or an integer
sub parse_factor
{
my $self = shift;
$self->any_of(
sub { $self->committed_scope_of( "(", 'parse', ")" ) },
sub { $self->token_int },
);
}
if( !caller ) {
my $parser = __PACKAGE__->new;
while( defined( my $line = <STDIN> ) ) {
try {
my $ret = $parser->from_string( $line );
print "$ret\n";
}
catch ( $e ) {
print $e;
}
}
}
1;
|