cisco.grammar
changeset 11 c170b1da9b6e
parent 10 91148603fd70
child 12 0b509f26f4d3
equal deleted inserted replaced
10:91148603fd70 11:c170b1da9b6e
     1 # Grammar for Cisco devices
     1 # Grammar for Cisco devices
       
     2 # Configuration is expected to be preprocessed via following command:
       
     3 # perl -ne '/(^\s*)(\S.*)$/; print length($1)." $2\n"'
     2 
     4 
     3 <autotree>
     5 #<autotree>
     4 { # perl code follows
     6 { # perl code follows
     5 
     7 
     6 $::res = {};
     8 $::res = {};
     7 
     9 
     8 # Returns pointer to context hasref as specified by ctx stack.
    10 # Returns pointer to context hasref as specified by ctx stack.
    20 } # end of perl code
    22 } # end of perl code
    21 
    23 
    22 file:		<skip: qr/[^\S\n]*/>	# Ignore non-newline whitespace
    24 file:		<skip: qr/[^\S\n]*/>	# Ignore non-newline whitespace
    23 		line(s) eofile
    25 		line(s) eofile
    24 
    26 
    25 line: 		emptyline
    27 line: 		s_controller
    26 		| s_controller
       
    27 		| s_interface
    28 		| s_interface
    28 		| comment
    29 		| indent comment
    29 		| cmdline 
    30 		| indent cmdline 
       
    31 		| indent emptyline
    30 		| <error>
    32 		| <error>
    31 
    33 
    32 emptyline:	eol
    34 emptyline:	eol
    33 
    35 
    34 comment: 	/^\!.*/ eol
    36 comment: 	/!.*/ eol
    35 
    37 
    36 cmdline:	l_hostname eol
    38 cmdline:	l_hostname eol
    37 		| l_hash eol
    39 		| l_hash eol
    38 		| word(s) eol
    40 		| word(s) eol
    39 
    41 
    40 word:		/[0-9a-zA-Z:\/_\#\"\.,+<>-]+/
    42 word:		/[0-9a-zA-Z:\/_\#\"\.,+<>()&{}-]+/
    41 		{ $item[1] }
    43 		{ $item[1] }
    42 
    44 
    43 type:		/\w+/
    45 type:		/\w+/
    44 		{ $item[1] }
    46 		{ $item[1] }
    45 
    47 
    46 num:		/\d+/
    48 num:		/\d+/
       
    49 		{ $item[1] }
       
    50 
       
    51 indent:		/\d+/
    47 		{ $item[1] }
    52 		{ $item[1] }
    48 
    53 
    49 range:		/\d+/"-"/\d+/
    54 range:		/\d+/"-"/\d+/
    50 		{ { from => $item[1], to => $item[3] } } 
    55 		{ { from => $item[1], to => $item[3] } } 
    51 
    56 
    72 
    77 
    73 # section
    78 # section
    74 section:	cmdline(s) "!"
    79 section:	cmdline(s) "!"
    75 		{ print "section\n"; }
    80 		{ print "section\n"; }
    76 
    81 
       
    82 l_section:	/[1-9]/ word(s) eol
       
    83 		| /[1-9]/ "!" eol
       
    84 		| /[1-9]/ eol
       
    85 		| <error>
       
    86 
    77 # Lines w/ hash (passwd, secret etc)
    87 # Lines w/ hash (passwd, secret etc)
    78 l_hash:		word(s) /\S+/ words(s)
    88 l_hash:		word(s) /\S+/ word(s)
    79 		| word(s) /\S+/
    89 		| word(s) /\S+/
    80 
    90 
    81 # Hostname
    91 # Hostname
    82 l_hostname:	"hostname" identifier
    92 l_hostname:	"hostname" identifier
    83 		{ $::res->{hostname} = $item{identifier} }
    93 		{ $::res->{hostname} = $item{identifier} }
    88 
    98 
    89 # controller section
    99 # controller section
    90 controller_num:	/\d+\/\d+/
   100 controller_num:	/\d+\/\d+/
    91 		{ $item[1] }
   101 		{ $item[1] }
    92 
   102 
    93 s_controller:	"controller" type controller_num s_controller_l[ctx => ctx('controller', $item{controller_num}) ](s) "!" eol
   103 s_controller:	"0" "controller" type controller_num eol s_controller_l[ctx => ctx('controller', $item{controller_num}) ](s) "0" "!" eol
    94 		{ $::res->{controller}->{$item{controller_num}}->{type} = $item{type} }
   104 		{ $::res->{controller}->{$item{controller_num}}->{type} = $item{type} }
    95 
   105 
    96 s_controller_l:	l_description[ctx => $arg{ctx}]
   106 s_controller_l:	"1" s_controller_content[ctx => $arg{ctx}] eol
       
   107 		| l_section
       
   108 
       
   109 s_controller_content: l_description[ctx => $arg{ctx}]
    97 		| "channel-group" num "timeslots" range
   110 		| "channel-group" num "timeslots" range
    98 		{ $arg{ctx}->{"channel-group"}->{$item{num}}->{ts} = $item{range} }
   111 		{ $arg{ctx}->{"channel-group"}->{$item{num}}->{ts} = $item{range} }
    99 		| "channel-group" num "unframed"
   112 		| "channel-group" num "unframed"
   100 		{ $arg{ctx}->{"channel-group"}->{$item{num}}->{unframed} = 1 }
   113 		{ $arg{ctx}->{"channel-group"}->{$item{num}}->{unframed} = 1 }
   101 		| cmdline
   114 		| "framing" keyword
   102 		| emptyline
   115 		{ $arg{ctx}->{framing} = $item{keyword} }
   103 		| <error>
   116 
       
   117 # Vlan range
       
   118 vlan_s_range:	/\d+/"-"/\d+/
       
   119 		{
       
   120 		for (my $i = $item[1]; $i <= $item[3]; $i++) {
       
   121 			$arg{ctx}->{$arg{key}}->{$i} = 1; }
       
   122 		}
       
   123 		| /\d+/
       
   124 		{ $arg{ctx}->{$arg{key}}->{$item[1]} = 1 }
       
   125 vlan_range: 	vlan_s_range","vlan_range
       
   126 		| vlan_s_range
   104 
   127 
   105 # interface section
   128 # interface section
   106 iface_name:	/\w+\d+(\/\d+)?(:\d+(\.\d+)?)?/
   129 iface_name:	/\w+\d+[0-9\/\.:]*/
   107 		{ $item[1] }
   130 		{ $item[1] }
   108 
   131 
   109 s_interface:	"interface" iface_name /\S*/ eol s_interface_l[ctx => ctx("interface", $item{iface_name}) ](s) "!" eol
   132 s_interface:	"0" "interface" iface_name /\S*/ eol s_interface_l[ctx => ctx("interface", $item{iface_name}) ](s) "0" "!" eol
   110 		{
   133 		{
   111 		print "interface $item{iface_name}\n";
   134 		$::res->{interface}->{$item{iface_name}}->{type} = $item[4]
   112 		$::res->{interface}->{$item{iface_name}}->{type} = $item[3]
   135 			if length($item[4]) > 0
   113 			if length($item[3]) > 0
       
   114 		}
   136 		}
   115 
   137 
   116 ip:		/\d+\.\d+\.\d+\.\d+/
   138 ip:		/\d+\.\d+\.\d+\.\d+/
   117 		{ $item[1] }
   139 		{ $item[1] }
   118 
   140 
   119 s_interface_l:	l_description
   141 s_interface_l:  "1" s_interface_content[ctx => $arg{ctx}] eol
   120 		| /(no)?/ "shutdown" eol
   142 		| l_section
       
   143 
       
   144 s_interface_content: l_description[ctx => $arg{ctx}]
       
   145 		| /(no)?/ "shutdown"
   121 		{ $arg{ctx}->{shutdown} = ($item[1] eq 'no') ? 0 : 1 }
   146 		{ $arg{ctx}->{shutdown} = ($item[1] eq 'no') ? 0 : 1 }
   122 		| "ip" "address" ip ip eol
   147 		| "ip" "address" ip ip
   123 		{ $arg{ctx}->{ip} = $item[3]; $arg{ctx}->{mask} = $item[4] }
   148 		{ $arg{ctx}->{ip} = $item[3]; $arg{ctx}->{mask} = $item[3] }
   124 		| "encapsulation" keyword /\S*/ eol
   149 		| "encapsulation" keyword /\S*/
   125 		{
   150 		{
   126 		$arg{ctx}->{encap} = $item[2];
   151 		$arg{ctx}->{encap} = $item[2];
   127 		$arg{ctx}->{encap_param} = $item[3] if length($item[3]) > 0
   152 		$arg{ctx}->{encap_param} = $item[3] if length($item[3]) > 0
   128 		}
   153 		}
   129 		| "frame-relay" keyword keyword
   154 		| "frame-relay" keyword keyword
   130 		{ $arg{ctx}->{"frame-relay"} = {type => $item[2], value => $item[3]} }
   155 		{ $arg{ctx}->{"frame-relay"} = {type => $item[2], value => $item[3]} }
   131 		| "bandwidth" num
   156 		| "bandwidth" num
   132 		{ $arg{ctx}->{bandwidth} = $item{num}; }
   157 		{ $arg{ctx}->{bandwidth} = $item{num} }
   133 		|cmdline
   158 		| "ip" "vrf" "forwarding" word
   134 		| emptyline
   159 		{ $arg{ctx}->{"ip-vrf-fwd"} = $item{word} }
   135 		| <error>
   160 		| "switchport" "mode" /access|trunk/
       
   161 		{ $arg{ctx}->{"switchport-mode"} = $item[3] }
       
   162 		| "switchport" "access" "vlan" num
       
   163 		{ $arg{ctx}->{vlan} = $item{num} }
       
   164 		| "switchport" "trunk" "encapsulation" keyword
       
   165 		{ $arg{ctx}->{"trunk-encap"} = $item{keyword} }
       
   166 		| "switchport" "trunk" "allowed" "vlan" vlan_range[ctx => $arg{ctx}, key => "vlan"]