#!perl
use
5.010001;
use
POSIX
qw(setlocale LC_ALL)
;
POSIX::setlocale(LC_ALL,
"C"
);
my
$g
= Marpa::R3::Scanless::G->new(
{
source
=> \(
<<'END_OF_SOURCE'),
lexeme default = action => [ name, value ]
Expr ::=
Number
| Expr '**' Expr
| Expr '-' Expr
Number ~ [\d]+
:discard ~ whitespace
whitespace ~ [\s]+
END_OF_SOURCE
}
);
my
$input
=
<<EOI;
2**7-3**10
EOI
my
$r
= Marpa::R3::Scanless::R->new( {
grammar
=>
$g
} );
$r
->
read
( \
$input
);
{
my
$ambiguous_status
=
$r
->ambiguous();
my
$expected
=
<<'EOS';
Ambiguous symch at Glade=2, Symbol=<Expr>:
The ambiguity is from line 1, column 1 to line 1, column 10
Text is: 2**7-3**10
There are 2 symches
Symch 0 is a rule: Expr ::= Expr '**' Expr
Symch 1 is a rule: Expr ::= Expr '-' Expr
EOS
Marpa::R3::Test::is(
$ambiguous_status
,
$expected
,
'ambiguous_status()'
);
Test::More::ok( (
$r
->ambiguity_metric() > 1 ),
'ambiguity_metric()'
);
}
{
$r
->series_restart();
my
$asf
= Marpa::R3::ASF->new( {
slr
=>
$r
} );
my
$full_result
=
$asf
->traverse( {}, \
&full_traverser
);
my
$actual
=
join
"\n"
, @{
$full_result
},
q{}
;
my
$expected
=
<<'EOS';
(Expr (Expr (Expr (2)) (**) (Expr (Expr (7)) (-) (Expr (3)))) (**) (Expr (10)))
(Expr (Expr (Expr (Expr (2)) (**) (Expr (7))) (-) (Expr (3))) (**) (Expr (10)))
(Expr (Expr (2)) (**) (Expr (Expr (Expr (7)) (-) (Expr (3))) (**) (Expr (10))))
(Expr (Expr (2)) (**) (Expr (Expr (7)) (-) (Expr (Expr (3)) (**) (Expr (10)))))
(Expr (Expr (Expr (2)) (**) (Expr (7))) (-) (Expr (Expr (3)) (**) (Expr (10))))
EOS
Marpa::R3::Test::is(
$actual
,
$expected
,
'Result of ASF traversal'
);
}
sub
full_traverser {
my
(
$glade
,
$scratch
) =
@_
;
my
$rule_id
=
$glade
->rule_id();
my
$symbol_id
=
$glade
->symbol_id();
my
$symbol_name
=
$g
->symbol_name(
$symbol_id
);
if
( not
defined
$rule_id
) {
my
$literal
=
$glade
->literal();
return
[
"($literal)"
];
}
my
@return_value
= ();
CHOICE:
while
(1) {
my
$length
=
$glade
->rh_length();
my
@results
= ( [] );
for
my
$rh_ix
( 0 ..
$length
- 1 ) {
my
@new_results
= ();
for
my
$old_result
(
@results
) {
my
$child_value
=
$glade
->rh_value(
$rh_ix
);
for
my
$new_value
( @{
$child_value
} ) {
push
@new_results
, [ @{
$old_result
},
$new_value
];
}
}
@results
=
@new_results
;
}
if
(
$symbol_name
eq
'[:start]'
) {
return
[
map
{
join
q{}
, @{
$_
} }
@results
];
}
my
$join_ws
=
q{ }
;
$join_ws
=
qq{\n }
if
$symbol_name
eq
'S'
;
push
@return_value
,
map
{
'('
.
$symbol_name
.
q{ }
. (
join
$join_ws
, @{
$_
} ) .
')'
}
@results
;
last
CHOICE
if
not
defined
$glade
->
next
();
}
return
\
@return_value
;
}