2 questions (...! and itempos) and 1 wish ('universal' action)

[email protected] ("Eric Liao")
Newsgroups perl.recdescent
Message-ID <[email protected]>
Hi All,

This is my first post to the list.  Please let me know if the format is
not acceptable.

I have two questions and here's the code to show them.

(1) The way the IDENT production is written does not accept
'newgoodident' as a valid identifier because it starts with one of the
keywords.  In reality, 'newgoodident' is a valid identifier, and
changing the rule from IDENT to IDENT2 gives the correct result (change
'Got $item[2]' to 'Got $item[1]' if you try IDENT2).  The problem with
IDENT2, which uses negative lookbehind, is that the long list of
keywords is duplicated and is messy.  What did I do wrong with IDENT?

(2) At the end of the grammar there's presence of commented-out
'@itempos'.  Strangely, I discovered that the presence of '@itempos' or
at least '$itempos[' (with left square bracket) anywhere inside the
grammar, even if commented out, seems to be necessary for the various
$itempos{...}{...} variables to be accessible from inside AUTOACTION.
Without the presence, I got an error like this:

       ERROR: Internal error in generated parser code!
       (Hint: Global symbol "@itempos" requires explicit package name
       at (eval 10) line 104, <DATA> line 1. Global symbol
       "@itempos" requires explicit package name at (eval 10)
       line 179, <DATA> line 1. BEGIN not safe after errors--
       compilation aborted at (eval 10) line 297, <DATA> line
       1. )

Can this be a bug?  Or is this because $itempos{...}{...} variables are
designed to be used only in the actions of individual rules?  I hope
not.  Or, please point out if I did anything wrong.

(3) Wish to have: I realize that AUTOACTION is executed for a matching
rule only when no action is defined for that rule.  But I ran into
situations where a universal kind of action would be useful (mostly for
debugging purposes but where setting the TRACE flag seems overkill).  By
'universal' I mean an action that is executed for ALL matching rules
regardless of whether individual action exists.  This 'universal' action
can either precede or follow the execution of individual action.

Thank you,
Eric Liao


##### START OF CODE
use strict;
use Parse::RecDescent;
undef $/;
my $input = <DATA>;
$::RD_AUTOACTION = q{
   if ($item[0] eq 'IDENT') {
      print "Got $item[2] at column $itempos[1]{column}{from}\n";
   }
   print "Remaining: $text\n" unless ($text =~ /^\s*$/);
   1;
};
$main::grammar =<<'EOG';
identifiers:
   IDENT IDENT
   
IDENT:
   ...!KEYWORD /[_a-z][_a-z0-9]*/i

IDENT2:
   /(?!(?:public|new)\b)[_a-z][_a-z0-9]*/i
   
KEYWORD:
   'new' | 'public'

# @itempos
EOG
$main::parser = new Parse::RecDescent($main::grammar)  or  die "invalid
grammar";
my $result = $main::parser->identifiers($input);
__DATA__
goodident newgoodident
##### END OF CODE
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.