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::do_macro_match {
my ($g1_before, $g1_after) = Marpa::R2::Context::location();
print "location() is ($g1_before, $g1_after)\n";
# location() returns the g1 location before the token
# and the g1 location after the last token
# of a symbol
my $g1_first = $g1_before + 1;
my $g1_last = $g1_after;
# We regard a token as *at* a g1 location if the g1
# location is after it, so that the first token included
# in a symbol is the one *after* the start returned
# by location. The last token in the symbol is "at",
# the g1 location *after* it, so no correction is needed.
print "G1 first is $g1_first\n";
print "G1 last is $g1_last\n";
my ($span_beg, $span_length) = $recce->g1_location_to_span(
$g1_first,
$g1_last);
print "input span starts at $span_beg\n";
print "span length is $span_length\n";
print "Jeffrey's literal does NOT give the entire match: " . $recce->literal($span_beg, $span_length) . "\n";
my @span1 = $recce->g1_location_to_span($g1_before);
my @span2 = $recce->g1_location_to_span($g1_after);
print "Mike's literal gives the entire match: ".$recce->literal($span1[0] +$span1[1], $span2[0] + $span2[1] - $span1[0] - $span1[1])."\n";
}