http://www.perlmonks.org?node_id=522779


in reply to Re: Parse::RecDescent and Dynamically Matched Subrule Repetition
in thread Parse::RecDescent and Dynamically Matched Subrule Repetition

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__