<?xml version="1.0" encoding="windows-1252"?>
<node id="1019403" title="Parse::RecDescent - specifying dynamic subrule repetition" created="2013-02-18 16:28:38" updated="2013-02-18 16:28:38">
<type id="115">
perlquestion</type>
<author id="1019395">
leahymr</author>
<data>
<field name="doctext">
&lt;p&gt;Dear Monks, I beg your wisdom...&lt;/p&gt;

&lt;p&gt;I am trying to parse a string for which I need to consume dynamically determined number of characters.  Can P:RD be persuaded to do that?&lt;/p&gt;

&lt;p&gt;Here is a simple example string:&lt;br&gt;
&lt;code&gt;s:5:"abcde";&lt;/code&gt; -- the '5' is the number of characters in the string&lt;/p&gt;

&lt;p&gt;Here's the hard part:&lt;br&gt;
&lt;code&gt;s:18:"s:10:"abcdefghij";";&lt;/code&gt;  -- the string can store other strings, so I can't just search for ";&lt;/p&gt;

&lt;p&gt;I know that subrules can have repetition counts, but I can't get something like&lt;br&gt;
  &lt;code&gt;String: 's: ' Count '"' Cdata($item{Count}) '";'&lt;/code&gt;
to work&lt;/p&gt;

&lt;p&gt;Here's the simplified grammar.  Is there a way I can consume the number of characters specified by $item{Count}?&lt;/p&gt;

&lt;code&gt;
my $grammar = q{

    
    CompText:  Command(s)
    
    Command:
        String
      | Integer
    
    Array: 'a:' &lt;commit&gt; Count ':{' Command(s) '}'
        { $return = "a:$item{Count}:{" . join( '', @{$item[-2]}) . "}"
        }
    
    String: 
        's:' Count ':"' Array '";'
        { $return = "s:$item{Count}:\"" . join( '', @{$item{Array}}) . "\";"
        }
          
      | 's:' Count ':"' Cdata_String '";'
        { $return = "s:$item{Count}:\"" . join( '', @{$item[-2]}) . "\";"
        }

      
    Cdata_String: Cdata(s?)
    
    Count: /\d+/
    
    Cdata: 
         /./
         
};
&lt;/code&gt;

&lt;p&gt;Thank you,&lt;br&gt;--Michael&lt;/p&gt;
</field>
</data>
</node>
