Your CodeProcess::do_macro_match is still wrong, please read
https://metacpan.org/pod/distribution/Marpa-R2/pod/Scanless/R.pod#g1_location_to_span()
.
"Mike's" workaround is quite correct, you have to "merge" the G1 start and
end locations.
Clearer code in attachment.
Le samedi 4 août 2018 16:24:44 UTC+2, Michael Spertus a écrit :
>
> Hi Jeffrey,
> While that works for the simple example, it seems to fail for slightly
> more complex examples (Now I don''t feel bad about having had trouble with
> this to begin with!)
>
> The attached a program that demonstrates the problem and the (surprisingly
> messy) fix as shown by the following output
>
> location() is (0, 3)
>> G1 first is 1
>> G1 last is 3
>> input span starts at 0
>> span length is 7
>>
>> *Jeffrey's literal is not the entire match: #defineMike's literal is the
>> entire match: #define foo bar*
>>
>>
> In any case, I have a working solution now, so I'm good to go.
>
> Thanks,
>
> Mike
>
--
You received this message because you are subscribed to the Google Groups
"marpa parser" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
use Marpa::R2;
my $dsl = <<'END_OF_DSL';
:default ::= action => [name,values]
lexeme default = latm => 1
:start ::= matches
matches ::= match+
match ::= id | macro action => do_macro_match
macro ::= '#define' identifier identifier
id ::= identifier
identifier ~ [\w]+
:discard ~ whitespace
whitespace ~ [\s]+
END_OF_DSL
my $grammar = Marpa::R2::Scanless::G->new( { source => \$dsl } );
my $recce = Marpa::R2::Scanless::R->new(
{ grammar => $grammar, semantics_package => 'CodeProcess' } );
my $input = '#define foo bar';
my $length_read = $recce->read( \$input );
my $value_ref = $recce->value;
my $value = ${$value_ref};
sub CodeProcess::span_merge {
my ($g1_before, $g1_after) = Marpa::R2::Context::location();
my @span_first = $recce->g1_location_to_span($g1_before + 1);
my @span_last = $recce->g1_location_to_span($g1_after);
my @starts = ($span_first[0], $span_last[0]);
my @ends = ($span_first[0] + $span_first[1], $span_last[0] + $span_last[1]);
my $span_merge_start = ($starts[0] < $starts[1]) ? $starts[0] : $starts[1];
my $span_merge_end = ($ends [0] > $ends [1]) ? $ends [0] : $ends [1];
return ($span_merge_start, $span_merge_end - $span_merge_start);
}
sub CodeProcess::do_macro_match {
print "Span merge's literal gives the entire match: ".$recce->literal(CodeProcess::span_merge())."\n";
}