Syntactic Confectionery Delight PerlMonks

### Re^2: Parse::RecDescent and Dynamically Matched Subrule Repetition

by ikegami (Pope)
 on Jan 12, 2006 at 18:51 UTC ( #522779=note: print w/replies, xml ) Need Help??

You can avoid the recursion by implementing your own looping:

```my \$p = Parse::RecDescent->new(<<'__END_OF_GRAMMAR__');

{
use strict;
use warnings;
}

parse    : rec /\Z/ { \$item[1] }
rec      : POS_INT
{
\$thisparser->_parserepeat(
\$text,
\&ELEM, \$item[1], \$item[1],  # ELEM(#)
\$_noactions, \$expectation, undef
)
}
{ [ \$item[0] => \$item[2] ] }
POS_INT  : /\d+/
ELEM     : /\S+/

__END_OF_GRAMMAR__

_parserepeat is the method called to handle rule(s), rule(s?), rule(4..6), etc.

If you don't want to break the box, you could break down the problem instead:

```my \$p = Parse::RecDescent->new(<<'__END_OF_GRAMMAR__');

{
use strict;
use warnings;
}

parse    : rec /\Z/ { \$item[1] }

rec      : POS_INT rec_list[ \$item[1] ] { [ \$item[0] => \$item[2] ] }

rec_list : { \$arg[0] < 1 ? [] : undef }

| { \$arg[0] < 10 ? 1 : undef }
ELEM rec_list[ \$arg[0]-1 ]
{ [ \$item[2], @{\$item[3]} ] }

| { \$arg[0] < 100 ? 1 : undef }
ELEM(10) rec_list[ \$arg[0]-10 ]
{ [ @{\$item[2]}, @{\$item[3]} ] }

| { \$arg[0] < 1000 ? 1 : undef }
ELEM(100) rec_list[ \$arg[0]-100 ]
{ [ @{\$item[2]}, @{\$item[3]} ] }

| <error:Exceeded maximum list length of 999 elements>

POS_INT  : /\d+/
ELEM     : /\S+/

__END_OF_GRAMMAR__

Create A New User
Node Status?
node history
Node Type: note [id://522779]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2020-01-25 02:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
The worst excuse I have ever heard is:

Results (109 votes). Check out past polls.

Notices?