well, i do not feel very comfortable with grammars yet - you'll note this when my explanations start to get wacky ;) (to be honest, i hope i get some upvotes for formatting reasons ...)

the rule 'ip' nicely encloses a key=value pair, the same sort of rule can be applied to the mask. further, the name 'ip' is IMO not very well chosen, i rename it to 'ip_def'. finally, break the first regexp into its pieces, so you can specify whitespaces. the first rule gets:

network_object: 'network' ':' /(\w+)/ '=' '{' ip_def mask_def host(s) +'}'

your problem with hosts_or_range is that you want to do too much within one rule. at first, it is irrelevant if a host has one ip or a whole range. so you can pull 'host:' one level up.

host : 'host' ':' /\w+/ '=' '{' ip_or_range '}'

if a host has an ip, it starts with the string 'ip'. if a host has an associated ip range, it starts with 'range' - and your problem disappears

ip_or_range : 'ip' '=' ip ';' | 'range' '=' ip '-' ip ';'

in your grammar, the rule 'hosts_or_range' tries to do two jobs:

the whole thing gets (plus added return values):
my $grammar = <<'GRAMMAR'; parse: network_object(s) network_object: 'network' ':' /(\w+)/ '=' '{' ip_def mask_def host(s) +'}' { $return = { NETWORK => $item[3], SUBNET => $item[6], NETMASK => $item[7], HOSTS => $item[8], }; } mask_def : 'mask' '=' ip ';' { $return = $item[3]; } ip_def : 'ip' '=' ip ';' { $return = $item[3]; } host : 'host' ':' /\w+/ '=' '{' ip_or_range '}' { $return = [$item[3], $item[6]]; } ip_or_range : 'ip' '=' ip ';' { $return = $item[3]; } | 'range' '=' ip '-' ip ';' { $return = {RANGE_START => $item[3], RANGE_END => $item[5]}; } ip : /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ { $return = $item[1]; } GRAMMAR

fed with your example, this eventually returns:

$VAR1 = [ { 'NETMASK' => '255.255.255.0', 'HOSTS' => [ [ 'asterix', '10.1.1.10' ], [ 'obelix', '10.1.1.11' ], [ 'idefix', '10.1.1.12' ], [ 'ix_13_20', { 'RANGE_START' => '10.1.1.13', 'RANGE_END' => '10.1.1.20' } ] ], 'NETWORK' => 'north', 'SUBNET' => '10.1.1.0' } ];
HTH

In reply to Re: Parse::RecDescent and <score: ...> directive by kabel
in thread Parse::RecDescent and <score: ...> directive by orrence

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.