Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
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 lurking in the Monastery: (10)
As of 2015-07-03 11:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (51 votes), past polls