#!/usr/bin/perl
use
5.010001;
my
$null_grammar
= Marpa::R3::Scanless::G->new(
{
bless_package
=>
'My_Nodes'
,
source
=> \(
<<'END_OF_SOURCE'),
:default ::= action => [g1start,g1length,name,values]
discard default = event => :symbol=off
lexeme default = action => [ g1start, g1length, start, length, value ]
Script ::=
:discard ~ whitespace event => ws
whitespace ~ [\s]
END_OF_SOURCE
}
);
for
my
$input
(
q{}
,
' '
,
' '
,
' '
) {
my
$recce
= Marpa::R3::Scanless::R->new(
{
grammar
=>
$null_grammar
},
);
my
$length
=
length
$input
;
my
$pos
=
$recce
->
read
( \
$input
);
my
$p_events
= gather_events(
$recce
,
$pos
,
$length
);
my
$actual_events
=
join
q{ }
,
map
{
$_
->[0],
$_
->[-1] } @{
$p_events
};
my
$expected_events
=
join
q{ }
, ( (
'ws 0'
) x
$length
);
Test::More::is(
$actual_events
,
$expected_events
,
"Test of $length discarded spaces"
);
my
$value_ref
=
$recce
->value();
die
"No parse was found\n"
if
not
defined
$value_ref
;
my
$result
= ${
$value_ref
};
}
my
$grammar2
= Marpa::R3::Scanless::G->new(
{
bless_package
=>
'My_Nodes'
,
source
=> \(
<<'END_OF_SOURCE'),
:default ::= action => [g1start,g1length,name,values]
discard default = event => :symbol=off
lexeme default = action => [ g1start, g1length, start, length, value ]
Script ::=
:discard ~ whitespace event => ws
whitespace ~ [\s]
:discard ~ bracketed event => bracketed
bracketed ~ '(' <no close bracket> ')'
<no close bracket> ~ [^)]*
END_OF_SOURCE
}
);
for
my
$input
(
q{ (x) }
,
q{(x) }
,
q{ (x)}
)
{
my
$recce
= Marpa::R3::Scanless::R->new( {
grammar
=>
$grammar2
}, );
my
$length
=
length
$input
;
my
$pos
=
$recce
->
read
( \
$input
);
my
$p_events
= gather_events(
$recce
,
$pos
,
$length
);
my
$actual_events
=
join
q{ }
,
map
{
$_
->[0],
$_
->[-1] } @{
$p_events
};
my
$expected_events
=
$input
;
$expected_events
=~ s/[(] [x]+ [)]/bracketed 0/xms;
$expected_events
=~ s/\A \s /ws 0 /xms;
$expected_events
=~ s/\s \z/ ws 0/xms;
Test::More::is(
$actual_events
,
$expected_events
,
qq{Test of two discard types, input="$input"}
);
my
$value_ref
=
$recce
->value();
die
"No parse was found\n"
if
not
defined
$value_ref
;
my
$result
= ${
$value_ref
};
}
my
$non_trivial_grammar
= Marpa::R3::Scanless::G->new(
{
bless_package
=>
'My_Nodes'
,
source
=> \(
<<'END_OF_SOURCE'),
:default ::= action => [g1start,g1length,name,values]
discard default = event => :symbol=off
lexeme default = action => [ g1start, g1length, start, length, value ]
text ::= a b c
a ~ 'a'
b ~ 'b'
c ~ 'c'
:discard ~ whitespace event => ws
whitespace ~ [\s]
END_OF_SOURCE
}
);
for
my
$pattern
(0 .. 15)
{
my
@spaces
=
split
//xms,
sprintf
"%04b"
,
$pattern
;
my
@chars
=
qw{a b c}
;
my
@input
= ();
for
my
$i
(0 .. 2) {
push
@input
,
' '
if
$spaces
[
$i
];
push
@input
,
$chars
[
$i
];
}
push
@input
,
' '
if
$spaces
[3];
my
@expected
= ();
for
my
$i
(0 .. 3) {
push
@expected
,
"ws $i"
if
$spaces
[
$i
];
}
my
$input
=
join
q{}
,
@input
;
my
$recce
= Marpa::R3::Scanless::R->new( {
grammar
=>
$non_trivial_grammar
}, );
my
$length
=
length
$input
;
my
$pos
=
$recce
->
read
( \
$input
);
my
$p_events
= gather_events(
$recce
,
$pos
,
$length
);
my
$actual_events
=
join
q{ }
,
map
{
$_
->[0],
$_
->[-1] } @{
$p_events
};
my
$expected_events
=
join
q{ }
,
@expected
;
Test::More::is(
$actual_events
,
$expected_events
,
qq{Test of non-trivial parse, input="$input"}
);
my
$value_ref
=
$recce
->value();
die
"No parse was found\n"
if
not
defined
$value_ref
;
my
$result
= ${
$value_ref
};
}
sub
gather_events {
my
(
$recce
,
$pos
,
$length
) =
@_
;
my
@actual_events
;
READ:
while
(1) {
EVENT:
for
my
$event
( @{
$recce
->events() } ) {
my
(
$name
,
@other_stuff
) = @{
$event
};
push
@actual_events
,
$event
;
}
last
READ
if
$pos
>=
$length
;
$pos
=
$recce
->resume(
$pos
);
}
return
\
@actual_events
;
}