ciena.grammar
author "Tomas Zeman <tzeman@volny.cz>"
Sun, 01 Nov 2009 23:33:46 +0100
changeset 1 7e38ef20071f
child 2 7b9f165f3a45
permissions -rw-r--r--
Ciena grammar: parse ports, sub-ports, pbt, hostname, pm

# 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}) }