#!/usr/bin/perl
use
5.010;
my
$grammar
= Marpa::R2::Grammar->new(
{
start
=>
'Expression'
,
actions
=>
'My_Actions'
,
default_action
=>
'first_arg'
,
rules
=> [
{
lhs
=>
'Expression'
,
rhs
=> [
qw/Term/
] },
{
lhs
=>
'Term'
,
rhs
=> [
qw/Factor/
] },
{
lhs
=>
'Factor'
,
rhs
=> [
qw/Number/
] },
{
lhs
=>
'Term'
,
rhs
=> [
qw/Term Add Term/
],
action
=>
'do_add'
},
{
lhs
=>
'Factor'
,
rhs
=> [
qw/Factor Multiply Factor/
],
action
=>
'do_multiply'
},
],
}
);
$grammar
->precompute();
my
$recce
= Marpa::R2::Recognizer->new( {
grammar
=>
$grammar
} );
$recce
->
read
(
'Number'
, 42 );
$recce
->
read
(
'Multiply'
);
$recce
->
read
(
'Number'
, 1 );
$recce
->
read
(
'Add'
);
$recce
->
read
(
'Number'
, 7 );
sub
My_Actions::do_add {
my
(
undef
,
$t1
,
undef
,
$t2
) =
@_
;
return
$t1
+
$t2
;
}
sub
My_Actions::do_multiply {
my
(
undef
,
$t1
,
undef
,
$t2
) =
@_
;
return
$t1
*
$t2
;
}
sub
My_Actions::first_arg {
shift
;
return
shift
; }
my
$value_ref
=
$recce
->value;
my
$value
=
$value_ref
? ${
$value_ref
} :
'No Parse'
;
my
$ambiguous_grammar
= Marpa::R2::Grammar->new(
{
start
=>
'E'
,
actions
=>
'My_Actions'
,
rules
=> [
[
'E'
, [
qw/E Add E/
],
'do_add'
],
[
'E'
, [
qw/E Multiply E/
],
'do_multiply'
],
[
'E'
, [
qw/Number/
], ],
],
default_action
=>
'first_arg'
,
}
);
$ambiguous_grammar
->precompute();
my
$ambiguous_recce
=
Marpa::R2::Recognizer->new( {
grammar
=>
$ambiguous_grammar
} );
$ambiguous_recce
->
read
(
'Number'
, 42 );
$ambiguous_recce
->
read
(
'Multiply'
);
$ambiguous_recce
->
read
(
'Number'
, 1 );
$ambiguous_recce
->
read
(
'Add'
);
$ambiguous_recce
->
read
(
'Number'
, 7 );
my
@values
= ();
while
(
defined
(
my
$ambiguous_value_ref
=
$ambiguous_recce
->value() ) ) {
push
@values
, ${
$ambiguous_value_ref
};
}
Test::More::is(
$value
, 49,
'Unambiguous Value'
);
Test::More::is_deeply( [
sort
@values
], [ 336, 49 ],
'Ambiguous Values'
);
sub
fix_things {
my
(
$recce
,
$tokens
,
$token_ix
) =
@_
;
die
qq{Don't know how to fix things at $token_ix}
;
}
$recce
= Marpa::R2::Recognizer->new( {
grammar
=>
$grammar
} );
my
@tokens
= (
[
'Number'
, 42 ],
[
'Multiply'
], [
'Number'
, 1 ],
[
'Add'
], [
'Number'
, 7 ],
);
TOKEN:
for
(
my
$token_ix
= 0;
$token_ix
<=
$#tokens
;
$token_ix
++ ) {
defined
$recce
->
read
( @{
$tokens
[
$token_ix
] } )
or fix_things(
$recce
,
$token_ix
, \
@tokens
)
or
die
q{Don't know how to fix things}
;
}
$value_ref
=
$recce
->value;
$value
=
$value_ref
? ${
$value_ref
} :
'No Parse'
;
Test::More::is(
$value
, 49,
'Interactive Value'
);
1;