Skip to content

Instantly share code, notes, and snippets.

@pstuifzand
Created March 30, 2012 18:10
Show Gist options
  • Save pstuifzand/2253565 to your computer and use it in GitHub Desktop.
Save pstuifzand/2253565 to your computer and use it in GitHub Desktop.
Using Marpa with a tree structure
use Marpa::XS;
use Data::Dumper;
my $grammar = Marpa::XS::Grammar->new(
{ start => 'Expression',
actions => 'My_Actions',
rules => [
# This rebuilds the tree
{ lhs => 'Expression', rhs => [qw/Term/], action => 'Return_0' },
{ lhs => 'Term', rhs => [qw/+ Term Term/], action => 'All'},
{ lhs => 'Term', rhs => [qw/Factor/], action => 'Return_0' },
{ lhs => 'Factor', rhs => [qw/* Factor Factor/], action => 'All' },
{ lhs => 'Factor', rhs => [qw/Number/], action => 'Return_0' },
# Simplication rules
# n + 0 ==> n
{ lhs => 'Term', rhs => [qw/+ 0 Term/], action => 'Return_2'},
{ lhs => 'Term', rhs => [qw/+ Term 0/], action => 'Return_1'},
# n * 1 ==> n
{ lhs => 'Factor', rhs => [qw/* 1 Factor/], action => 'Return_2' },
{ lhs => 'Factor', rhs => [qw/* Factor 1/], action => 'Return_1' },
# n * 0 ==> 0
{ lhs => 'Factor', rhs => [qw/* 0 Factor/], action => 'Zero' },
{ lhs => 'Factor', rhs => [qw/* Factor 0/], action => 'Zero' },
],
}
);
$grammar->precompute();
sub My_Actions::Return_0 { shift; return $_[0]; }
sub My_Actions::Return_1 { shift; return $_[1]; }
sub My_Actions::Return_2 { shift; return $_[2]; }
sub My_Actions::All { shift; return \@_; }
sub My_Actions::Zero { shift; return 0; }
my $rec = Marpa::XS::Recognizer->new({grammar => $grammar});
my $expr = [ '+', [ '*', 10, 2 ], 0 ];
$rec->alternative('Term', $expr, 5);
$rec->alternative('+', '+', 1);
$rec->earleme_complete;
$rec->alternative('Factor', $expr->[1], 3);
$rec->alternative('*', '*', 1);
$rec->earleme_complete;
$rec->alternative($expr->[1][1], $expr->[1][1], 1);
$rec->alternative('Number', $expr->[1][1], 1);
$rec->earleme_complete;
$rec->alternative($expr->[1][2], $expr->[1][2], 1);
$rec->alternative('Number', $expr->[1][2], 1);
$rec->earleme_complete;
$rec->alternative($expr->[2], $expr->[2], 1);
$rec->alternative('Number', $expr->[2], 1);
$rec->earleme_complete;
$rec->end_input;
while (my $v = ${$rec->value}) {
print Dumper($v);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment