Ciena grammar: parse ports, sub-ports, pbt, hostname, pm
author"Tomas Zeman <tzeman@volny.cz>"
Sun, 01 Nov 2009 23:33:46 +0100
changeset 1 7e38ef20071f
parent 0 b93558664b93
child 2 7b9f165f3a45
Ciena grammar: parse ports, sub-ports, pbt, hostname, pm
README
ciena.grammar
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Sun Nov 01 23:33:46 2009 +0100
@@ -0,0 +1,2 @@
+This repository contains grammar definition as developed while extracting
+information from network device configuration files of various vendors.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ciena.grammar	Sun Nov 01 23:33:46 2009 +0100
@@ -0,0 +1,145 @@
+# Grammar for Ciena devices
+
+<autotree>
+{ # perl code follows
+
+$::res = {};
+$::res->{port} ={};
+$::res->{sub_port} ={};
+$::res->{pm} = {
+	instance => {},
+	service => {},
+	'sub-port' => {},
+};
+$::res->{pbt} = {
+	reserved => {},	# reserved bvids
+	'bridge-mac' => {},
+};
+$::res->{'pbt-service'} = {};
+$::res->{'pbt-tunnel-group'} = {};
+
+
+# local (current line) attribute-value-list, ie. property value
+my $avl = {};
+
+# Consumes attribute value list.
+# @param type Type (port/sub_port/etc).
+# @param id Identifier, eg. port number.
+sub consume_avl {
+	my ($type, $id) = (@_);
+	$::res->{$type}->{$id} = {} unless exists $::res->{$type}->{$id};
+	foreach my $k (keys %$avl) {
+		$::res->{$type}->{$id}->{$k} = $avl->{$k};
+	}
+	$avl = {};
+}
+
+# Consumes attribute value list into supplied pointer (into hash).
+# @param ptr Pointer where AVL will be stored.
+# @param id Identifier, eg. port number.
+sub consume_avl_ptr {
+	my ($ptr, $id) = (@_);
+	$ptr->{$id} = {} unless exists $ptr->{$id};
+	foreach my $k (keys %$avl) {
+		$ptr->{$id}->{$k} = $avl->{$k};
+	}
+	$avl = {};
+}
+
+} # end of perl code
+
+file:		<skip: qr/[^\S\n]*/>	# Ignore non-newline whitespace
+		line(s) eofile
+
+line: 		emptyline
+		| comment
+		| cmdline 
+		| <error>
+
+emptyline:	eol
+
+comment: 	/^\!.*/ eol
+
+cmdline:	l_hostname
+		| l_port
+		| l_sub_port
+		| l_pm
+		| l_pbt
+		| word(s) eol
+
+word:		/[0-9a-zA-Z:\/_\#\"\.,-]+/
+		{ $item[1] }
+
+identifier:	/[0-9a-zA-Z:_-]+/
+		{ $item[1] }
+
+quoted_text:	<perl_quotelike>
+		{ $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
+
+# Hostname
+l_hostname:	"system" "set" "host-name" identifier
+		{ $::res->{hostname} = $item{identifier} }
+
+# Port
+l_port:		"port" /disable|set/ "port" port_num avls
+		{
+		$avl->{action} = $item[2];
+		consume_avl("port", $item{port_num}); 
+		}
+
+port_num:	/\d+(\/\d+)?/
+		{ $item[1] }
+
+avls:		avl(s)
+		| eol
+
+avl:		"description" quoted_text
+		{ $avl->{description} = $item{quoted_text}; }
+		| word value
+		{ $avl->{$item{word}} = $item{value}; }
+# Sub-port
+l_sub_port:	"sub-port" /add|create/ "sub-port" identifier avls
+		{
+		$avl->{action} = $item[2];
+		consume_avl("sub_port", $item{identifier}); 
+		}
+
+# PM
+l_pm:		"pm" "enable" "pm-instance" identifier
+		{ $::res->{pm}->{instance}->{$item{identifier}} = "enabled" }
+		| "pm" "create" /service|sub-port/ identifier avls
+		{
+		$::res->{pm}->{$item[3]}->{$item{identifier}} = {};
+		consume_avl_ptr($::res->{pm}->{$item[3]}, $item{identifier});
+		}
+
+# PBT
+bvid:		/\d+/
+		{ $item[1] }
+
+mac:		/\d{12}|(\d\d:){5}\d\d/
+		{ $item[1] }
+
+l_pbt:		"pbt" "reserve" "bvid" bvid
+		{ $::res->{pbt}->{reserved}->{$item{bvid}} = 1 }
+		| "pbt" "set" "bridge-mac" mac avls
+		{
+		$::res->{pbt}->{'bridge-mac'}->{$item{mac}} = {};
+		consume_avl_ptr($::res->{pbt}->{'bridge-mac'}, $item{mac})
+		}
+		| "pbt" "service" "create" "service" identifier avls
+		{ consume_avl("pbt-service", $item{identifier}) }
+		| "pbt" "tunnel-group" "create" "group" identifier avls
+		{ consume_avl("pbt-tunnel-group", $item{identifier}) }