FAQ

Reset local parser variables for each new input file

Alexander Farber
Sep 13, 2004 at 8:05 am
Hi,

I have a script which compiles a grammar once and then parses quite
many files using it. The parser is placed into a separate module and
thus I have to use quite long names to refer to variables from the
parser rules (for example $My::Module::CurrentDir = '.' in a rule).

I wonder, if there is a way to define and use "local" variables in
a parser? And they shouldn't be something like $parser->{CurrentDir}
because that's even more unreadable ;-)

Something like the "Start-up actions" from the "perldoc P::RecDescent",
but they should be reset on every new parser call and not just on the
grammar compilation, like here:

bolinux72:afarber {518} cat test_pd.pl
#!/usr/bin/perl -w

use strict;
use Parse::RecDescent;
use constant GRAMMAR => q(

{ my $i = 1; }

mmpfile: letter(s) /^\Z/
letter: /([A-Z])/ { print "$i: <$1>\n"; $i++ }

);

my $parser = Parse::RecDescent->new(GRAMMAR) or die 'Bad grammar';
defined $parser->mmpfile('ABC') or warn 'Bad text 1';
defined $parser->mmpfile('klm') or warn 'Bad text 2';
defined $parser->mmpfile('XYZ') or warn 'Bad text 3';

bolinux72:afarber {519} perl test_pd.pl
1: <A>
2: <B>
3: <C>
Bad text 2 at test_pd.pl line 16.
4: <X>
5: <Y>
6: <Z>

Or, to reformulate my question: ist there a way to reset the $i above?
So that $i = 1 for every new input file, regardless if the file before
has been parsed successfully or not.

Regards
Alex
reply

Search Discussions

4 responses

  • Sean O'Rourke at Sep 13, 2004 at 12:38 pm

    At Mon, 13 Sep 2004 10:04:37 +0200, wrote:
    Something like the "Start-up actions" from the "perldoc P::RecDescent",
    but they should be reset on every new parser call and not just on the
    grammar compilation, like here:
    Can you just add an action to the beginning of your start rule, like
    so?

    mmpfile: { $i = 1 } letter(s) /^\Z/

    /s
  • Alexander Farber at Sep 13, 2004 at 1:16 pm
    Yes, I've tried that and it seems to work, but I'm
    worried about the cases when the input files don't parse.
    Will the mmpfile: { $i = 1 } still always trigger?

    Also, what is it? It's not an action for the mmprule, isn't it?
    -----Original Message-----
    From: ext Sean O'Rourke
    At Mon, 13 Sep 2004 10:04:37 +0200, wrote:
    Something like the "Start-up actions" from the "perldoc P::RecDescent",
    but they should be reset on every new parser call and not just on the
    grammar compilation, like here:
    Can you just add an action to the beginning of your start rule, like so?

    mmpfile: { $i = 1 } letter(s) /^\Z/
    bolinux72:afarber {514} perl test_pd.pl
    1: <A>
    2: <B>
    3: <C>
    Bad text 2 at test_pd.pl line 16.
    1: <X>
    2: <Y>
    3: <Z>

    bolinux72:afarber {515} cat test_pd.pl
    #!/usr/bin/perl -w

    use strict;
    use Parse::RecDescent;
    use constant GRAMMAR => q(

    { my $i = 1; }

    mmpfile: { $i = 1} letter(s) /^\Z/
    letter: /([A-Z])/ { print "$i: <$1>\n"; $i++ }

    );

    my $parser = Parse::RecDescent->new(GRAMMAR) or die 'Bad grammar';
    defined $parser->mmpfile('ABC') or warn 'Bad text 1';
    defined $parser->mmpfile('klm') or warn 'Bad text 2';
    defined $parser->mmpfile('XYZ') or warn 'Bad text 3';
  • Ron D. Smith at Sep 13, 2004 at 8:45 pm

    On Monday, Sep 13, 2004 Alexander.Farber@nokia.com said:

    Yes, I've tried that and it seems to work, but I'm
    worried about the cases when the input files don't parse.
    Will the mmpfile: { $i = 1 } still always trigger?
    Yes. Note the syntax.

    mmpfile:

    This is the name of the rule.

    { $i = 1 }

    This is an action. If it returns true (which it does, although apparently by
    "accident"), then mmpfile *may* still be parsed.

    letter(s)

    This is a one or more named sub-rule call If one or more instances of
    "letter" are found consecutively, this returns true.

    /^\Z/

    This is a regular expression match. If this regular expression matches the
    remainder of the string at this point, it returns true.

    If all items return true, then mmpfile succeeds. So far, I'm not telling you
    anything you don't already know, but the whole point is that the "{ $i = 1 }"
    action will *always* fire because it is first in line. If the action
    occurred anywhere else, there is the possibility that the desired side effect
    won't happen.

    This may or may not be good, depending on the rest of the design.
    Personally, I "don't like" the approach, because it depends on side effects
    and places the information storage somewhere else than in the parsed object
    itself, but it can be made to work as your example clearly shows. My
    objection falls under the "globals are bad" motherhood statement. Two things
    to remember are that the initializer action should always be first and that
    it must return "true".
    Also, what is it? It's not an action for the mmprule, isn't it?
    -----Original Message-----
    From: ext Sean O'Rourke
    At Mon, 13 Sep 2004 10:04:37 +0200, wrote:
    Something like the "Start-up actions" from the "perldoc P::RecDescent",
    but they should be reset on every new parser call and not just on the
    grammar compilation, like here:
    Can you just add an action to the beginning of your start rule, like so?

    mmpfile: { $i = 1 } letter(s) /^\Z/
    bolinux72:afarber {514} perl test_pd.pl
    1: <A>
    2: <B>
    3: <C>
    Bad text 2 at test_pd.pl line 16.
    1: <X>
    2: <Y>
    3: <Z>

    bolinux72:afarber {515} cat test_pd.pl
    #!/usr/bin/perl -w

    use strict;
    use Parse::RecDescent;
    use constant GRAMMAR => q(

    { my $i = 1; }

    mmpfile: { $i = 1} letter(s) /^\Z/
    letter: /([A-Z])/ { print "$i: <$1>\n"; $i++ }

    );

    my $parser = Parse::RecDescent->new(GRAMMAR) or die 'Bad grammar';
    defined $parser->mmpfile('ABC') or warn 'Bad text 1';
    defined $parser->mmpfile('klm') or warn 'Bad text 2';
    defined $parser->mmpfile('XYZ') or warn 'Bad text 3';
    --
    Intel, Corp.
    5000 W. Chandler Blvd.
    Chandler, AZ 85226

    --
    Intel, Corp.
    5000 W. Chandler Blvd.
    Chandler, AZ 85226
  • Sean O'Rourke at Sep 13, 2004 at 10:29 pm

    At Mon, 13 Sep 2004 13:45:18 -0700, "Ron D. Smith" wrote:
    { $i = 1 }

    This is an action. If it returns true (which it does, although apparently by
    "accident"), then mmpfile *may* still be parsed.
    s/true/defined/

    /s

Related Discussions

Discussion Navigation
viewthread | post