# HG changeset patch # User "Tomas Zeman " # Date 1258321938 -3600 # Node ID c170b1da9b6e18ebf8f77029d53ff9dcc6b81209 # Parent 91148603fd70d88d9e5e1b3e27d310ea593d74c3 cisco.grammar: refactored to use indentation markers fro proper in-section parsing; more controller, interface properties diff -r 91148603fd70 -r c170b1da9b6e cisco.grammar --- a/cisco.grammar Mon Nov 09 17:48:33 2009 +0100 +++ b/cisco.grammar Sun Nov 15 22:52:18 2009 +0100 @@ -1,6 +1,8 @@ # Grammar for Cisco devices +# Configuration is expected to be preprocessed via following command: +# perl -ne '/(^\s*)(\S.*)$/; print length($1)." $2\n"' - +# { # perl code follows $::res = {}; @@ -22,22 +24,22 @@ file: # Ignore non-newline whitespace line(s) eofile -line: emptyline - | s_controller +line: s_controller | s_interface - | comment - | cmdline + | indent comment + | indent cmdline + | indent emptyline | emptyline: eol -comment: /^\!.*/ eol +comment: /!.*/ eol cmdline: l_hostname eol | l_hash eol | word(s) eol -word: /[0-9a-zA-Z:\/_\#\"\.,+<>-]+/ +word: /[0-9a-zA-Z:\/_\#\"\.,+<>()&{}-]+/ { $item[1] } type: /\w+/ @@ -46,6 +48,9 @@ num: /\d+/ { $item[1] } +indent: /\d+/ + { $item[1] } + range: /\d+/"-"/\d+/ { { from => $item[1], to => $item[3] } } @@ -74,8 +79,13 @@ section: cmdline(s) "!" { print "section\n"; } +l_section: /[1-9]/ word(s) eol + | /[1-9]/ "!" eol + | /[1-9]/ eol + | + # Lines w/ hash (passwd, secret etc) -l_hash: word(s) /\S+/ words(s) +l_hash: word(s) /\S+/ word(s) | word(s) /\S+/ # Hostname @@ -90,38 +100,53 @@ controller_num: /\d+\/\d+/ { $item[1] } -s_controller: "controller" type controller_num s_controller_l[ctx => ctx('controller', $item{controller_num}) ](s) "!" eol +s_controller: "0" "controller" type controller_num eol s_controller_l[ctx => ctx('controller', $item{controller_num}) ](s) "0" "!" eol { $::res->{controller}->{$item{controller_num}}->{type} = $item{type} } -s_controller_l: l_description[ctx => $arg{ctx}] +s_controller_l: "1" s_controller_content[ctx => $arg{ctx}] eol + | l_section + +s_controller_content: 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 - | + | "framing" keyword + { $arg{ctx}->{framing} = $item{keyword} } + +# Vlan range +vlan_s_range: /\d+/"-"/\d+/ + { + for (my $i = $item[1]; $i <= $item[3]; $i++) { + $arg{ctx}->{$arg{key}}->{$i} = 1; } + } + | /\d+/ + { $arg{ctx}->{$arg{key}}->{$item[1]} = 1 } +vlan_range: vlan_s_range","vlan_range + | vlan_s_range # interface section -iface_name: /\w+\d+(\/\d+)?(:\d+(\.\d+)?)?/ +iface_name: /\w+\d+[0-9\/\.:]*/ { $item[1] } -s_interface: "interface" iface_name /\S*/ eol s_interface_l[ctx => ctx("interface", $item{iface_name}) ](s) "!" eol +s_interface: "0" "interface" iface_name /\S*/ eol s_interface_l[ctx => ctx("interface", $item{iface_name}) ](s) "0" "!" eol { - print "interface $item{iface_name}\n"; - $::res->{interface}->{$item{iface_name}}->{type} = $item[3] - if length($item[3]) > 0 + $::res->{interface}->{$item{iface_name}}->{type} = $item[4] + if length($item[4]) > 0 } ip: /\d+\.\d+\.\d+\.\d+/ { $item[1] } -s_interface_l: l_description - | /(no)?/ "shutdown" eol +s_interface_l: "1" s_interface_content[ctx => $arg{ctx}] eol + | l_section + +s_interface_content: l_description[ctx => $arg{ctx}] + | /(no)?/ "shutdown" { $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 + | "ip" "address" ip ip + { $arg{ctx}->{ip} = $item[3]; $arg{ctx}->{mask} = $item[3] } + | "encapsulation" keyword /\S*/ { $arg{ctx}->{encap} = $item[2]; $arg{ctx}->{encap_param} = $item[3] if length($item[3]) > 0 @@ -129,7 +154,13 @@ | "frame-relay" keyword keyword { $arg{ctx}->{"frame-relay"} = {type => $item[2], value => $item[3]} } | "bandwidth" num - { $arg{ctx}->{bandwidth} = $item{num}; } - |cmdline - | emptyline - | + { $arg{ctx}->{bandwidth} = $item{num} } + | "ip" "vrf" "forwarding" word + { $arg{ctx}->{"ip-vrf-fwd"} = $item{word} } + | "switchport" "mode" /access|trunk/ + { $arg{ctx}->{"switchport-mode"} = $item[3] } + | "switchport" "access" "vlan" num + { $arg{ctx}->{vlan} = $item{num} } + | "switchport" "trunk" "encapsulation" keyword + { $arg{ctx}->{"trunk-encap"} = $item{keyword} } + | "switchport" "trunk" "allowed" "vlan" vlan_range[ctx => $arg{ctx}, key => "vlan"]