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


in reply to Parse::RecDescent - specifying dynamic subrule repetition

I know that subrules can have repetition counts, but I can't get something like

String: 's: ' Count '"' Cdata($item{Count}) '";' to work

I'm a mere beginner with P:RD, but previously I have found the lack of backreferences to be very frustrating. Rule names are not double quote-ish things, so variables are not interpolated into rule names. But literal strings or regexes in your rules are double quote-ish things, so variables are interpolated into them. You can use that fact to create a backreference:

use strict; use warnings; use 5.012; use Parse::RecDescent; $::RD_ERRORS = 1; #Parser dies when it encounters an error $::RD_WARN = 1; #Enable warnings - warn on unused rules &c. $::RD_HINT = 1; #Give out hints to help fix problems. #$::RD_TRACE = 1; #Trace parsers' behaviour my $text = <<'END_OF_TEXT'; 5:abcdefghi END_OF_TEXT my $grammar = <<'END_OF_GRAMMAR'; { use 5.012; use Data::Dumper; my $count_match; #****DECLARE A VARIABLE**** } line: section(s /:/) section: count { $count_match = $item{count} } #**SET THE VARIABLE** | word {say Dumper(\@item)} count: m{ \d+ }xms word: m| .{$count_match} |xms #***INTERPOLATE THE VARIABLE*** END_OF_GRAMMAR my $parser = Parse::RecDescent->new($grammar) or die "Bad grammar!\n"; defined $parser->line($text) or die "Can't match text"; --output:-- $VAR1 = [ 'section', 'abcde' ];

However, your grammar needs to employ recursion in order to match your more complicated strings, i.e patterns within a pattern. And recursion is very hard. The only way I know how to do recursion in a programming language whose syntax is not specifically designed for recursion, i.e. perl, is by trial and error (thousands of times) until I get it right.

If you are just beginning with P::RD, here are some tips I wrote up: http://www.perlmonks.org/index.pl?node_id=1015944