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