use Marpa::R2;

my $dsl = <<'END_OF_DSL';
:default ::= action => [name,values]
lexeme default = latm => 1

:start ::= matches

matches ::= match+
match ::= id | non_id
id ::= identifier action => do_id
non_id ::= other

identifier ~ [\w]+
other ~ [\W]+
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 = '#####abc##';
my $length_read = $recce->read( \$input );

my $value_ref = $recce->value;
my $value = ${$value_ref};


sub CodeProcess::do_id {
    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 "literal is " . $recce->literal($span_beg, $span_length) . "\n";
    print 'but $_[1] shows this id rule matched '.$_[1]."\n";
 }

