Created
January 8, 2013 17:28
-
-
Save arodland/4485844 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Math::Parser; | |
use strict; | |
use warnings; | |
use Method::Signatures::Simple; | |
use Marpa::R2 2.026; | |
use MarpaX::Lex::Easy; | |
my $grammar = Marpa::R2::Grammar->new({ | |
actions => 'Math::Parser::Actions', | |
start => 'Expression', | |
rules => q{ | |
Expression ::= NUMBER action => number | |
| (LPAREN) Expression (RPAREN) action => parens assoc => group | |
|| Expression (ASTERISK) Expression action => multiply | |
| Expression (SLASH) Expression action => divide | |
|| Expression (PLUS) Expression action => add | |
| Expression (MINUS) Expression action => subtract | |
}, | |
}); | |
$grammar->precompute; | |
print $grammar->show_rules; | |
my %tokens = ( | |
'LPAREN' => [ qr/\G[(]/ ], | |
'RPAREN' => [ qr/\G[)]/ ], | |
'ASTERISK' => [ qr/\G[*]/ ], | |
'SLASH' => [ qr/\G[\/]/ ], | |
'PLUS' => [ qr/\G[+]/ ], | |
'MINUS' => [ qr/\G[-]/ ], | |
'NUMBER' => [ qr/\G([-+]?[0-9.]+(?:e[+-]?[0-9]+)?)/, sub { 0 + $1 } ], | |
); | |
method parse_line ($line) { | |
my $rec = Marpa::R2::Recognizer->new({ | |
grammar => $grammar, | |
ranking_method => 'rule', | |
trace_terminals => 1, | |
trace_actions => 1, | |
trace_values => 1, | |
}); | |
my $lex = MarpaX::Lex::Easy->new( | |
tokens => \%tokens, | |
recognizer => $rec, | |
automatic_whitespace => 1, | |
whitespace_pattern => qr/\G\s+/, | |
); | |
return $lex->read_and_parse($line); | |
} | |
package Math::Parser::Actions; | |
sub parens { | |
return $_[1]; | |
} | |
sub multiply { | |
return $_[1] * $_[2]; | |
} | |
sub divide { | |
return $_[1] / $_[2]; | |
} | |
sub add { | |
return $_[1] + $_[2]; | |
} | |
sub subtract { | |
return $_[1] - $_[2]; | |
} | |
sub number { | |
return $_[1]; | |
} | |
package main; | |
while (<>) { | |
chomp; | |
print Math::Parser->parse_line($_), "\n"; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package Math::Parser; | |
use strict; | |
use warnings; | |
use Method::Signatures::Simple; | |
use Marpa::R2 2.026; | |
my $grammar = Marpa::R2::Scanless::G->new({ | |
action_object => 'Math::Parser::Actions', | |
source => \q{ | |
:start ::= Expression | |
Expression ::= NUMBER action => number | |
| ('(') Expression (')') action => parens assoc => group | |
|| Expression ('*') Expression action => multiply | |
| Expression ('/') Expression action => divide | |
|| Expression ('+') Expression action => add | |
| Expression ('-') Expression action => subtract | |
NUMBER ~ SIGN FLOATING EXPONENT | |
SIGN ~ [-+] | |
SIGN ~ | |
FLOATING ~ [0-9.]+ | |
EXPONENT ~ 'e' SIGN DIGITS | |
EXPONENT ~ | |
DIGITS ~ [0-9]+ | |
:discard ~ WS | |
WS ~ [\s]+ | |
}, | |
}); | |
print $grammar->show_rules; | |
method parse_line ($line) { | |
my $rec = Marpa::R2::Scanless::R->new({ | |
grammar => $grammar, | |
trace_terminals => 1, | |
trace_values => 1, | |
}); | |
$rec->read(\$line); | |
my $value = $rec->value; | |
if (defined $value) { | |
return $$value; | |
} else { | |
die "Parse error"; | |
} | |
} | |
package Math::Parser::Actions; | |
# I really just wanted actions, not action_object ;) | |
sub new { | |
return bless {}; | |
} | |
sub parens { | |
return $_[1]; | |
} | |
sub multiply { | |
return $_[1] * $_[2]; | |
} | |
sub divide { | |
return $_[1] / $_[2]; | |
} | |
sub add { | |
return $_[1] + $_[2]; | |
} | |
sub subtract { | |
return $_[1] - $_[2]; | |
} | |
sub number { | |
return $_[1]; | |
} | |
package main; | |
while (<>) { | |
chomp; | |
print Math::Parser->parse_line($_), "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment