oneaccess.grammar
changeset 44 b9026c6ef3e9
parent 43 597596f302ef
child 45 9ba98ba61f6b
equal deleted inserted replaced
43:597596f302ef 44:b9026c6ef3e9
       
     1 # Grammar for OneAccess devices
       
     2 # Configuration is expected to be preprocessed via following command:
       
     3 # perl -ne '/(^\s*)(\S.*)$/; print length($1)." $2\n"'
       
     4 #
       
     5 # Copyright (c) 2012 Tomas Zeman <tzeman@volny.cz>
       
     6 # All rights reserved.
       
     7 #
       
     8 # Redistribution and use in source and binary forms, with or without
       
     9 # modification, are permitted providing that the following conditions 
       
    10 # are met:
       
    11 # 1. Redistributions of source code must retain the above copyright
       
    12 #    notice, this list of conditions and the following disclaimer.
       
    13 # 2. Redistributions in binary form must reproduce the above copyright
       
    14 #    notice, this list of conditions and the following disclaimer in the
       
    15 #    documentation and/or other materials provided with the distribution.
       
    16 #
       
    17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
       
    18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    20 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
       
    21 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    22 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    23 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    24 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
       
    25 # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
       
    26 # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
    27 # POSSIBILITY OF SUCH DAMAGE.
       
    28 #
       
    29 
       
    30 { # perl code follows
       
    31 
       
    32 $::res = {};
       
    33 
       
    34 # Returns pointer to context hashref as specified by ctx stack.
       
    35 # @param ctx_path array of ctx stack.
       
    36 sub ctx {
       
    37 	return ctx_rel($::res, @_);
       
    38 }
       
    39 
       
    40 # Returns pointer to context hashref as specified by ctx stack,
       
    41 # relative to the supplied ctx pointer.
       
    42 # @param ptr current ctx pointer from which ctx build starts.
       
    43 # @param ctx_path array of ctx stack.
       
    44 sub ctx_rel {
       
    45 	my $ptr = shift;
       
    46 	my @ctx_path = @_;
       
    47 	foreach my $part (@ctx_path) {
       
    48 		$ptr->{$part} = {} unless exists ($ptr->{$part});
       
    49 		$ptr = $ptr->{$part};
       
    50 	}
       
    51 	return $ptr;
       
    52 }
       
    53 
       
    54 } # end of perl code
       
    55 
       
    56 file:		<skip: qr/[^\S\n]*/>	# Ignore non-newline whitespace
       
    57 		line(s) eofile
       
    58 
       
    59 line: 		s_controller
       
    60 		| s_interface
       
    61 		| s_voice_port
       
    62 		| s_dial_peer
       
    63 		| l_vrf
       
    64 		| l_sntp
       
    65 		| l_syslog
       
    66 		| indent comment 
       
    67 		| indent cmdline 
       
    68 		| indent emptyline
       
    69 		| <error>
       
    70 
       
    71 emptyline:	eol
       
    72 
       
    73 comment: 	/!.*/ eol
       
    74 
       
    75 cmdline:	l_hostname eol
       
    76 		| l_hash eol
       
    77 		| word(s) eol
       
    78 
       
    79 word:		/\S+/  # any non-space
       
    80 		{ $item[1] }
       
    81 
       
    82 type:		/\w+/
       
    83 		{ $item[1] }
       
    84 
       
    85 num:		/\d+/
       
    86 		{ $item[1] }
       
    87 
       
    88 indent:		/\d+/
       
    89 		{ $item[1] }
       
    90 
       
    91 range:		/\d+/"-"/\d+/
       
    92 		{ { from => $item[1], to => $item[3] } } 
       
    93 		| /\d+/
       
    94 		{ { from => $item[1], to => $item[1] } } 
       
    95 
       
    96 keyword:	/[\w-]+/
       
    97 		{ $item[1] }
       
    98 
       
    99 identifier:	/[0-9a-zA-Z:_-]+/
       
   100 		{ $item[1] }
       
   101 
       
   102 quoted_text:	<perl_quotelike>
       
   103 		{ $item[1][2] }
       
   104 		| /[0-9a-zA-Z:\/_\#\"\.,-]+/
       
   105 		{ $item[1] }
       
   106 
       
   107 value:		/[0-9a-zA-Z:\/_\#\"\.,-]+/
       
   108 		{ $item[1] }
       
   109 
       
   110 eofile:		/^\Z/
       
   111 
       
   112 eol:		/\n/
       
   113 
       
   114 rest_of_line:	word(s)
       
   115 		| eol
       
   116 
       
   117 # generic attribute/value pair, handles no ... and single-param switches
       
   118 avpair: 	identifier word
       
   119 		{
       
   120 		if ($item[1] eq 'no') {
       
   121 			$arg{ctx}->{$item[2]} = 0;
       
   122 		} else {
       
   123 			$arg{ctx}->{$item[1]} = $item[2];
       
   124 		}
       
   125 		}
       
   126 		| identifier
       
   127 		{ $arg{ctx}->{$item[1]} = 1 }
       
   128 
       
   129 # section
       
   130 section:	cmdline(s) "!"
       
   131 		{ print "section\n"; }
       
   132 
       
   133 l_section:	/[1-9]/ word(s) eol
       
   134 		| /[1-9]/ "exit" eol
       
   135 		| /[1-9]/ eol
       
   136 		| <error>
       
   137 
       
   138 # Lines w/ hash (passwd, secret etc)
       
   139 l_hash:		word(s) /\S+/ word(s)
       
   140 		| word(s) /\S+/
       
   141 
       
   142 # Hostname
       
   143 l_hostname:	"hostname" identifier
       
   144 		{ $::res->{hostname} = $item{identifier} }
       
   145 
       
   146 # Description
       
   147 l_description:	"description" /[^\n]+/
       
   148 		{ $arg{ctx}->{description} = $item[2] }
       
   149 
       
   150 # controller section
       
   151 controller_num:	/\d+/
       
   152 		{ $item[1] }
       
   153 
       
   154 s_controller:	"0" "controller" type controller_num eol s_controller_l[ctx => ctx('controller', $item{controller_num}) ](s) "0" "exit" eol
       
   155 		{ $::res->{controller}->{$item{controller_num}}->{type} = $item{type} }
       
   156 
       
   157 s_controller_l:	"1" s_controller_content[ctx => $arg{ctx}] eol
       
   158 		| s_dsl_group[ctx => $arg{ctx}]
       
   159 		| l_section
       
   160 
       
   161 s_controller_content: l_description[ctx => $arg{ctx}]
       
   162 		| "framing" keyword
       
   163 		{ $arg{ctx}->{framing} = $item{keyword} }
       
   164 
       
   165 s_dsl_group:	"2" "dsl-group" num eol s_dsl_group_l[ctx => ctx_rel($arg{ctx}, 'dsl-group', $item{num})](s) "2" "exit" eol
       
   166 
       
   167 s_dsl_group_l:  indent s_dsl_group_content[ctx => $arg{ctx}] eol
       
   168 
       
   169 s_dsl_group_content:	"autoconfig"
       
   170 		{ $arg{ctx}->{autoconfig} = 1 }
       
   171 		| "execute"
       
   172 		{ $arg{ctx}->{execute} = 1 }
       
   173 		| "caplist" identifier
       
   174 		{ $arg{ctx}->{caplist} = $item{identifier} }
       
   175 		| "vendorspecoctets" num
       
   176 		{ $arg{ctx}->{vendorspecoctets} = $item{num} }
       
   177 
       
   178 # interface section
       
   179 iface_type:	/[0-9a-zA-Z:-]+/
       
   180 		{ $item[1] }
       
   181 
       
   182 iface_num:	/\d+([\.\/]\d+)*/
       
   183 		{ $item[1] }
       
   184 
       
   185 s_interface:	"0" "interface" iface_type iface_num /\S*/ eol s_interface_l[ctx => ctx("interface", $item{iface_type}.":".$item{iface_num}) ](s) "0" "exit" eol
       
   186 		{
       
   187 		my $id = $item{iface_type}.":".$item{iface_num};
       
   188 		$::res->{interface}->{$id}->{type} = $item{iface_type};
       
   189 		$::res->{interface}->{$id}->{num} = $item{iface_num}
       
   190 		}
       
   191 
       
   192 ip:		/\d+\.\d+\.\d+\.\d+/
       
   193 		{ $item[1] }
       
   194 
       
   195 s_interface_l:  "1" s_interface_content[ctx => $arg{ctx}] eol
       
   196 		| s_isdn[ctx => $arg{ctx}]
       
   197 		| s_vrrp[ctx => $arg{ctx}]
       
   198 		| l_section
       
   199 
       
   200 s_interface_content: l_description[ctx => $arg{ctx}]
       
   201 		| /(no)?/ "shutdown"
       
   202 		{ $arg{ctx}->{shutdown} = ($item[1] eq 'no') ? 0 : 1 }
       
   203 		| "ip" "address" ip ip
       
   204 		{ $arg{ctx}->{ip} = $item[3]; $arg{ctx}->{mask} = $item[4] }
       
   205 		| "encapsulation" keyword /\S*/
       
   206 		{
       
   207 		$arg{ctx}->{encap} = $item[2];
       
   208 		$arg{ctx}->{encap_param} = $item[3] if length($item[3]) > 0
       
   209 		}
       
   210 		| "bandwidth" num
       
   211 		{ $arg{ctx}->{bandwidth} = $item{num} }
       
   212 		| "speed" num
       
   213 		{ $arg{ctx}->{speed} = $item{num} }
       
   214 		| "ip" "vrf" "forwarding" word
       
   215 		{ $arg{ctx}->{"ip-vrf-fwd"} = $item{word} }
       
   216 		| "bridge-group" num
       
   217 		{ $arg{ctx}->{"bridge-group"} = $item{num} }
       
   218 		| "framing" keyword
       
   219 		{ $arg{ctx}->{framing} = $item{keyword} }
       
   220 		| "ip" "mtu" num
       
   221 		{ $arg{ctx}->{mtu} = $item{num} }
       
   222 		| "service-policy" /input|output/ identifier
       
   223 		{ $arg{ctx}->{'service-policy'}->{$item[2]} = $item{identifier} }
       
   224 		| "ip" "access-group" identifier /in|out/
       
   225 		{ $arg{ctx}->{'access-group'}->{$item[4]} = $item{identifier} }
       
   226 
       
   227 s_isdn:		"1" "isdn" eol s_isdn_l[ctx => ctx_rel($arg{ctx}, 'isdn')](s) "1" "exit" eol
       
   228 
       
   229 s_isdn_l:	"2" avpair[ctx => $arg{ctx}] eol
       
   230 
       
   231 s_vrrp:		"1" "vrrp" num eol s_vrrp_l[ctx => ctx_rel($arg{ctx}, 'vrrp', $item{num})](s) "1" "exit" eol
       
   232 
       
   233 s_vrrp_l:	"2" avpair[ctx => $arg{ctx}] eol
       
   234 		| "2" "tracking-interface" iface_type iface_num eol
       
   235 		{
       
   236 		$arg{ctx}->{$item[2]} = {
       
   237 			type => $item{iface_type},
       
   238 			num => $item{iface_num}
       
   239 		}
       
   240 		}
       
   241 		| "2" "address" ip ip eol
       
   242 		{
       
   243 		$arg{ctx}->{$item[2]} = {
       
   244 			ip => $item[3],
       
   245 			mask => $item[4]
       
   246 		}
       
   247 		}
       
   248 
       
   249 
       
   250 
       
   251 # vrf
       
   252 l_vrf:		"0" "ip" "vrf" keyword eol
       
   253 		{ $::res->{"ip-vrf"} = $item{keyword} }
       
   254 
       
   255 via_iface:	iface_type iface_num
       
   256 		{
       
   257 		$arg{ctx}->{interface} = {
       
   258 			type => $item{iface_type},
       
   259 			num => $item{iface_num}
       
   260 		};
       
   261 		}
       
   262 		| ""
       
   263 
       
   264 # sntp
       
   265 l_sntp:		"0" "sntp" "server" ip via_iface[ctx => ctx('sntp-server', $item{ip})] eol
       
   266 
       
   267 l_syslog:	"0" "syslog" "server" ip num via_iface[ctx => ctx('syslog', 'server', $item{ip})] eol
       
   268 		| "0" "logging" "syslog" /\w+/ eol
       
   269 		{ $::res->{syslog}->{level} = $item[4] }
       
   270 
       
   271 # voice ports
       
   272 s_voice_port:	"0" "voice-port" /\d+\/\d+/ eol s_voice_port_l[ctx => ctx('voice-port', $item[3])](s) "0" "exit" eol
       
   273 
       
   274 s_voice_port_l:	"1" s_voice_port_content[ctx => $arg{ctx}] eol
       
   275 		| l_section
       
   276 
       
   277 s_voice_port_content: /clock-source|tone|caller-id/ identifier
       
   278 		{ $arg{ctx}->{$item[1]} = $item{identifier} }
       
   279 		| /(no)?/ /sntp-time|power-source-one/
       
   280 		{ $arg{ctx}->{$item[2]} = ($item[1] eq 'no') ? 0 : 1 }
       
   281 		| "modify-tone" identifier /\S+/
       
   282 		{ $arg{ctx}->{$item[1]}->{$item{identifier}} = $item[3] }
       
   283 
       
   284 # dial peers
       
   285 s_dial_peer:	"0" "dial-peer" "voice" word num eol s_dial_peer_l[ctx => ctx('dial-peer', $item{word}.":".$item{num}), type => $item{word}, num => $item{num} ](s) "0" "exit" eol
       
   286 
       
   287 s_dial_peer_l:	"1" avpair[ctx => $arg{ctx}] eol
       
   288 		{
       
   289 		$arg{ctx}->{type} = $arg{type};
       
   290 		$arg{ctx}->{num} = $arg{num}
       
   291 		}
       
   292 		| l_section
       
   293