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

Hi,

I am facing an issue with using the %item hash for subrules which have a "(?)" repetition specifier (i.e. match one or zero times). As an example, please have a look at the code below: For the below code, I am expecting that I get following output input

2 0 a

instead, I get

input a

The documentation states that when we use (s), the value associated with the rule is not a scalar but a reference to a list of scalars. Does this hold for the (?) construct too? If yes, then the below code should work as I dereference the value "$item{range}->[0]".

Thanks and Regards,

Aditya

use Parse::RecDescent; my $text = "input [2:0] a"; my $grammar = q { rule : 'input' range(?) identifier { print $item[1]."\n"; if (defined @{$item{range}->[0]}) { my @arr = @{$item{range}->[0]}; foreach my $i (@arr) { print $i."\n"; } } print $item{identifier}; } range : "[" from_num ":" to_num "]" {$return = [$item{from_num}, $ +item{to_num}]} from_num : number {$return = $item{number}} to_num : number {$return = $item{number}} number : /[0-9][0-9_]*/ identifier : /[a-zA-Z][a-zA-Z_0-9\.]*/ }; my $parser = new Parse::RecDescent($grammar) or die "Bad Grammar"; $parser->rule($text);

Code tags added by GrandFather

Replies are listed 'Best First'.
Re: RecDescent Issue: using item hash with (?) repetition specifier
by ikegami (Patriarch) on Apr 02, 2009 at 21:47 UTC

    Please don't put use <pre>. Use <c> instead. It has numerous benefits.

    Please don't put your entire post in <pre> or <c> tags. It hurts readability. Just place <p> at the start of every paragraph instead.

    Being new is no excuse. Previewing your node would have revealed a problem.

    Finally, the second item is range(?), not range. Use the right name as the hash key (range(?)), and your code works. (Using $item[2] would also work.)

    Tip:

    my $grammar = q { ... };
    will get you into problems. Use
    my $grammar = <<'__EOI__'; ... __EOI__
    instead.

    Tip: "." is not special in character classes, so it doesn't need to be escaped then.

Re: RecDescent Issue: using item hash with (?) repetition specifier
by almut (Canon) on Apr 02, 2009 at 23:23 UTC

    Your key should be 'range(?)' — as the docs say:

    "The results of named subrules are stored in the hash under each subrule's name (including the repetition specifier, if any)"

    With that change, i.e.

    if (defined @{$item{'range(?)'}->[0]}) { my @arr = @{$item{'range(?)'}->[0]}; foreach my $i (@arr) { print $i."\n"; } }

    I do get the expected output:

    input 2 0 a
Re: RecDescent Issue: using item hash with (?) repetition specifier
by jethro (Monsignor) on Apr 02, 2009 at 21:41 UTC

    Please don't use pre tags. Use p-tags for text and c- or code-tags for code. I promise I'll take a closer look after you have edited your post

      On-site CSS can be used to work round the horrible page-widening effect:

      pre { white-space: pre-wrap }

      I suppose there's a good reason why <pre> is permitted at all?