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