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";
}

Reply via email to