diff -r 837e0e828d06 -r 91148603fd70 cisco.grammar --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cisco.grammar Mon Nov 09 17:48:33 2009 +0100 @@ -0,0 +1,135 @@ +# Grammar for Cisco devices + + +{ # perl code follows + +$::res = {}; + +# Returns pointer to context hasref as specified by ctx stack. +# @param ctx_path array of ctx stack. +sub ctx { + my @ctx_path = @_; + my $ptr = $::res; + foreach my $part (@ctx_path) { + $ptr->{$part} = {} unless exists ($ptr->{$part}); + $ptr = $ptr->{$part}; + } + return $ptr; +} + +} # end of perl code + +file: # Ignore non-newline whitespace + line(s) eofile + +line: emptyline + | s_controller + | s_interface + | comment + | cmdline + | + +emptyline: eol + +comment: /^\!.*/ eol + +cmdline: l_hostname eol + | l_hash eol + | word(s) eol + +word: /[0-9a-zA-Z:\/_\#\"\.,+<>-]+/ + { $item[1] } + +type: /\w+/ + { $item[1] } + +num: /\d+/ + { $item[1] } + +range: /\d+/"-"/\d+/ + { { from => $item[1], to => $item[3] } } + +keyword: /[\w-]+/ + { $item[1] } + +identifier: /[0-9a-zA-Z:_-]+/ + { $item[1] } + +quoted_text: + { $item[1][2] } + | /[0-9a-zA-Z:\/_\#\"\.,-]+/ + { $item[1] } + +value: /[0-9a-zA-Z:\/_\#\"\.,-]+/ + { $item[1] } + +eofile: /^\Z/ + +eol: /\n/ + +rest_of_line: word(s) + | eol + +# section +section: cmdline(s) "!" + { print "section\n"; } + +# Lines w/ hash (passwd, secret etc) +l_hash: word(s) /\S+/ words(s) + | word(s) /\S+/ + +# Hostname +l_hostname: "hostname" identifier + { $::res->{hostname} = $item{identifier} } + +# Description +l_description: "description" /[^\n]+/ + { $arg{ctx}->{description} = $item[2] } + +# controller section +controller_num: /\d+\/\d+/ + { $item[1] } + +s_controller: "controller" type controller_num s_controller_l[ctx => ctx('controller', $item{controller_num}) ](s) "!" eol + { $::res->{controller}->{$item{controller_num}}->{type} = $item{type} } + +s_controller_l: l_description[ctx => $arg{ctx}] + | "channel-group" num "timeslots" range + { $arg{ctx}->{"channel-group"}->{$item{num}}->{ts} = $item{range} } + | "channel-group" num "unframed" + { $arg{ctx}->{"channel-group"}->{$item{num}}->{unframed} = 1 } + | cmdline + | emptyline + | + +# interface section +iface_name: /\w+\d+(\/\d+)?(:\d+(\.\d+)?)?/ + { $item[1] } + +s_interface: "interface" iface_name /\S*/ eol s_interface_l[ctx => ctx("interface", $item{iface_name}) ](s) "!" eol + { + print "interface $item{iface_name}\n"; + $::res->{interface}->{$item{iface_name}}->{type} = $item[3] + if length($item[3]) > 0 + } + +ip: /\d+\.\d+\.\d+\.\d+/ + { $item[1] } + +s_interface_l: l_description + | /(no)?/ "shutdown" eol + { $arg{ctx}->{shutdown} = ($item[1] eq 'no') ? 0 : 1 } + | "ip" "address" ip ip eol + { $arg{ctx}->{ip} = $item[3]; $arg{ctx}->{mask} = $item[4] } + | "encapsulation" keyword /\S*/ eol + { + $arg{ctx}->{encap} = $item[2]; + $arg{ctx}->{encap_param} = $item[3] if length($item[3]) > 0 + } + | "frame-relay" keyword keyword + { $arg{ctx}->{"frame-relay"} = {type => $item[2], value => $item[3]} } + | "bandwidth" num + { $arg{ctx}->{bandwidth} = $item{num}; } + |cmdline + | emptyline + |