FAQ
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

Search Discussions

  • Damian Conway at Sep 10, 2001 at 8:26 am
    Hi Eric,

    Sorry for the delay in replying...I am a victim of my own notoriety nowadays
    and my response time suffers accordingly :-(

    You asked:
    (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?
    Nothing. You messed up KEYWORD instead ;-)

    What you meant was:

    KEYWORD:
    /^(new|public)\b/

    In other words, a keyword is 'new' or 'public'
    with a word boundary immediately after it.
    ^^^^^^^^^^^^^^^^^^^^

    (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.
    A bug. I overlooked the possibility of autoactions injecting @itempos usages
    when writing the code that decides whether to include @itempos calculations
    in a grammar. I've patched that now and credited you with its discovery.
    You're comment is the appropriate workaround in the meantime.

    (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.
    I'll add that to the ToDo list.

    Damian
  • Eric Liao at Sep 10, 2001 at 5:53 pm
    Damian,

    Thanks!

    Before 'universal' action becomes a feature, I'll find a way to simulate
    that.

    Eric

    -----Original Message-----
    From: Damian Conway
    Sent: Monday, September 10, 2001 1:27 AM
    To: recdescent@perl.org; Eric Liao
    Subject: Re: 2 questions (...! and itempos) and 1 wish ('universal'
    action)


    Hi Eric,

    Sorry for the delay in replying...I am a victim of my own notoriety
    nowadays
    and my response time suffers accordingly :-(

    You asked:
    (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?

    Nothing. You messed up KEYWORD instead ;-)

    What you meant was:

    KEYWORD:
    /^(new|public)\b/

    In other words, a keyword is 'new' or 'public'
    with a word boundary immediately after it.
    ^^^^^^^^^^^^^^^^^^^^

    (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.
    A bug. I overlooked the possibility of autoactions injecting @itempos
    usages
    when writing the code that decides whether to include @itempos
    calculations
    in a grammar. I've patched that now and credited you with its discovery.
    You're comment is the appropriate workaround in the meantime.

    (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.
    I'll add that to the ToDo list.

    Damian

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouprecdescent @
categoriesperl
postedSep 4, '01 at 7:43p
activeSep 10, '01 at 5:53p
posts3
users2
websitemetacpan.org...

2 users in discussion

Eric Liao: 2 posts Damian Conway: 1 post

People

Translate

site design / logo © 2018 Grokbase