rob_au has asked for the wisdom of the Perl Monks concerning the following question:

I have a question regarding subrules within grammars used with Parse::RecDescent - The following code best illustrates the best test case that I can identify which highlights my problem.

#!/usr/bin/perl use Parse::RecDescent; use Test::More 'no_plan'; my $grammar = q { argument: element ((comma element)(s))(?) element: /[\w.-_]+/ comma: ',' }; my $sql = Parse::RecDescent->new( $grammar ); while ( chomp( my $test = <DATA> ) ) { my ( $result, $statement ) = split /,/, $test, 2; ok( defined $sql->argument( $statement ) == $result, $test ); } __DATA__ 0, 1,arg1 0,arg1, 1,arg1,arg2 0,arg1,arg2, 1,arg1,arg2,arg3

Note that with this test code, each of the lines within the __DATA__ section are tested against the grammar and the expected result, either pass or fail, is indicated by the 1 or 0 at the start of the line respectively.

However, despite these expected results, the grammar does not reject the lines arg1, and arg1,arg2,, which ideally should be rejected due to the incomplete match of the subrule (comma element) - In these cases, a trace shows that the subrule terminal comma is matched and consumed, despite the entire subrule, consisting of comma and element, not being matched. I am sure this is a relatively straight-forward oversight within the grammar on my part, but I am at a loss as to how to correct this.

 

perl -le 'print+unpack("N",pack("B32","00000000000000000000001000110011"))'

Edited 2003-02-22 by Ovid

Replies are listed 'Best First'.
•Re: Parse::RecDescent sub-rule question
by merlyn (Sage) on Feb 22, 2003 at 13:46 UTC
    It's matching a portion of the string, which is legal unless you also anchor the end of the pattern. I typically use /\z/ at the end of my top-level pattern.

    Also, your comma-separated string can be parsed simply with

    argument: element(s /,/)
    as shown in the P::RD examples on the manpage.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.