Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Parse::RecDescent and <score: ...> directive

by kabel (Chaplain)
on Sep 22, 2003 at 16:15 UTC ( #293177=note: print w/ replies, xml ) Need Help??


in reply to Parse::RecDescent and <score: ...> directive

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:

  • there can be possible zero to inf hosts and
  • each hosts associates either an ip or a range.

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


Comment on Re: Parse::RecDescent and <score: ...> directive
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://293177]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2014-09-24 02:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (244 votes), past polls