#!/usr/bin/perl
use
5.010;
use
Fatal
qw( open close )
;
my
$progress_report
=
q{}
;
my
$grammar
= Marpa::R2::Grammar->new(
{
start
=>
'Expression'
,
actions
=>
'My_Actions'
,
default_action
=>
'first_arg'
,
rules
=> [
{
lhs
=>
'Expression'
,
rhs
=> [
qw/Factor/
] },
{
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'
},
],
}
);
open
my
$trace_fh
,
q{>}
, \(
my
$trace_output
=
q{}
);
$grammar
->set( {
trace_file_handle
=>
$trace_fh
} );
$grammar
->precompute();
my
@tokens
= (
[
'Number'
, 42 ],
[
'Multiply'
,
q{*}
],
[
'Number'
, 1 ],
[
'Add'
,
q{+}
],
[
'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
$recce
= Marpa::R2::Recognizer->new(
{
grammar
=>
$grammar
,
trace_terminals
=> 2 } );
my
$token_ix
= 0;
TOKEN:
for
my
$token_and_value
(
@tokens
) {
last
TOKEN
if
not
defined
$recce
->
read
( @{
$token_and_value
} );
}
$progress_report
=
$recce
->show_progress( 0, -1 );
my
$value_ref
=
$recce
->value;
my
$value
=
$value_ref
? ${
$value_ref
} :
'No Parse'
;
Test::More::is(
$value
, 42,
'value'
);
Marpa::R2::Test::is(
$progress_report
,
<<'END_PROGRESS_REPORT', 'progress report' );
P0 @0-0 Expression -> . Factor
P2 @0-0 Factor -> . Number
P4 @0-0 Factor -> . Factor Multiply Factor
F0 @0-1 Expression -> Factor .
F2 @0-1 Factor -> Number .
R4:1 @0-1 Factor -> Factor . Multiply Factor
P2 @2-2 Factor -> . Number
P4 @2-2 Factor -> . Factor Multiply Factor
R4:2 @0-2 Factor -> Factor Multiply . Factor
F0 @0-3 Expression -> Factor .
F2 @2-3 Factor -> Number .
R4:1 x2 @0,2-3 Factor -> Factor . Multiply Factor
F4 @0-3 Factor -> Factor Multiply Factor .
END_PROGRESS_REPORT
$Data::Dumper::Indent
= 0;
$Data::Dumper::Terse
= 1;
my
$report0
=
$recce
->progress(0);
chomp
(
my
$expected_report0
=
<<'END_PROGRESS_REPORT');
[[0,0,0],[2,0,0],[4,0,0]]
END_PROGRESS_REPORT
Marpa::R2::Test::is( Data::Dumper::Dumper(
$report0
),
$expected_report0
,
'progress report at location 0'
);
$report0
=
$recce
->progress(-4);
Marpa::R2::Test::is( Data::Dumper::Dumper(
$report0
),
$expected_report0
,
'progress report at location -4'
);
my
$report1
=
$recce
->progress(1);
chomp
(
my
$expected_report1
=
<<'END_PROGRESS_REPORT');
[[0,-1,0],[2,-1,0],[4,1,0]]
END_PROGRESS_REPORT
Marpa::R2::Test::is( Data::Dumper::Dumper(
$report1
),
$expected_report1
,
'progress report at location 1'
);
$report1
=
$recce
->progress(-3);
Marpa::R2::Test::is( Data::Dumper::Dumper(
$report1
),
$expected_report1
,
'progress report at location -3'
);
my
$report2
=
$recce
->progress(2);
chomp
(
my
$expected_report2
=
<<'END_PROGRESS_REPORT');
[[2,0,2],[4,0,2],[4,2,0]]
END_PROGRESS_REPORT
Marpa::R2::Test::is( Data::Dumper::Dumper(
$report2
),
$expected_report2
,
'progress report at location 2'
);
$report2
=
$recce
->progress(-2);
Marpa::R2::Test::is( Data::Dumper::Dumper(
$report2
),
$expected_report2
,
'progress report at location -2'
);
my
$latest_report
=
$recce
->progress();
chomp
(
my
$expected_report3
=
<<'END_PROGRESS_REPORT');
[[0,-1,0],[2,-1,2],[4,-1,0],[4,1,0],[4,1,2]]
END_PROGRESS_REPORT
Marpa::R2::Test::is( Data::Dumper::Dumper(
$latest_report
),
$expected_report3
,
'progress report at location 3'
);
my
$report3
=
$recce
->progress(3);
Marpa::R2::Test::is( Data::Dumper::Dumper(
$report3
),
$expected_report3
,
'progress report at location 3'
);
$latest_report
=
$recce
->progress(-1);
Marpa::R2::Test::is( Data::Dumper::Dumper(
$latest_report
),
$expected_report3
,
'progress report at location -1'
);
Marpa::R2::Test::is(
$trace_output
,
<<'END_TRACE_OUTPUT', 'trace output' );
Inaccessible symbol: Add
Inaccessible symbol: Term
Setting trace_terminals option
Expecting "Number" at earleme 0
Accepted "Number" at 0-1
Expecting "Multiply" at 1
Accepted "Multiply" at 1-2
Expecting "Number" at 2
Accepted "Number" at 2-3
Expecting "Multiply" at 3
Rejected "Add" at 3-4
END_TRACE_OUTPUT
1;