package VladimirBot::Math; use strict; use Parse::Earley; use Data::Dumper; $Data::Dumper::Deparse = 1; #$Data::Dumper::Maxdepth = 4; # Here I push myself onto the module call stack push @VladimirBot::vladimir_module, 'Math'; #$Parse::Earley::DEBUG = 1; #$Data::Dumper::Maxdepth = 5; $Data::Dumper::Indent = 1; sub print_tree { my ($tree, $indent) = @_; if($tree->{tok}) { print 'terminal (' . $tree->{lhs} . '): '; print $tree->{tok}; } elsif ($tree->{production}) { print "production: "; print $tree->{lhs}; } print "\n"; if($tree->{left} && $tree->{left}[0]->{left}) { #if($tree->{left}) { print $indent . 'left - '; print_tree($tree->{left}[0], $indent . ' '); } if($tree->{down}) { print $indent . 'down - '; print_tree($tree->{down}[0], $indent . ' '); } } sub parse { my $sentence = shift; my $grammar = <<'END'; input: expr | 'what' 'is' expr { $_[2] } | 'what' 'is' expr '?' { $_[2] } expr: mul_expr '+' expr | mul_expr '-' expr | mul_expr mul_expr: term '*' mul_expr | term '/' mul_expr | term term: '(' expr ')' | /\d+(\.\d+)?/ # | number # # number: # ones # | tens ones # | tens # | ones 'hundred' 'and' tens ones # | ones 'hundred' 'and' tens # | Ones 'hundred' 'and' ones # # ones: # 'one' { '1' } # | 'two' { '2' } # | 'three' { '3' } # | 'four' { '4' } # | 'five' { '5' } # | 'six' { '6' } # | 'seven' { '6' } # | 'eight' { '6' } # | 'nine' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } # | 'six' { '6' } END #print "Trying to parse: $sentence\n"; my $parser = new Parse::Earley; $parser->grammar($grammar); $parser->start('input'); do { $parser->advance($sentence) } until( $parser->fails($sentence, 'input') or $parser->matches($sentence, 'input')); #print "Parse failed\n" if $parser->fails($sentence, 'input'); if ($parser->matches($sentence, 'input')) { my $out; print "Parse succeeded\n"; my $graph; ($graph) = $parser->matches($sentence, 'input'); #my $action = $parser->{actions}; #my $e = $parser->eval_production($action, $graph); my $e = $parser->eval_production($graph); #my $e = Parse::Earley::eval_production($action, $graph); $out = "result: $e = "; $out .= (eval $e); $out .= "\n"; return $out; #print "here"; #print "graph: " . Dumper(\$graph) . "\n"; #print "Tree:\n"; #print_tree($graph, ' '); } return 0; } 1;