|
1 # Grammar for Cisco devices |
|
2 |
|
3 <autotree> |
|
4 { # perl code follows |
|
5 |
|
6 $::res = {}; |
|
7 |
|
8 # Returns pointer to context hasref as specified by ctx stack. |
|
9 # @param ctx_path array of ctx stack. |
|
10 sub ctx { |
|
11 my @ctx_path = @_; |
|
12 my $ptr = $::res; |
|
13 foreach my $part (@ctx_path) { |
|
14 $ptr->{$part} = {} unless exists ($ptr->{$part}); |
|
15 $ptr = $ptr->{$part}; |
|
16 } |
|
17 return $ptr; |
|
18 } |
|
19 |
|
20 } # end of perl code |
|
21 |
|
22 file: <skip: qr/[^\S\n]*/> # Ignore non-newline whitespace |
|
23 line(s) eofile |
|
24 |
|
25 line: emptyline |
|
26 | s_controller |
|
27 | s_interface |
|
28 | comment |
|
29 | cmdline |
|
30 | <error> |
|
31 |
|
32 emptyline: eol |
|
33 |
|
34 comment: /^\!.*/ eol |
|
35 |
|
36 cmdline: l_hostname eol |
|
37 | l_hash eol |
|
38 | word(s) eol |
|
39 |
|
40 word: /[0-9a-zA-Z:\/_\#\"\.,+<>-]+/ |
|
41 { $item[1] } |
|
42 |
|
43 type: /\w+/ |
|
44 { $item[1] } |
|
45 |
|
46 num: /\d+/ |
|
47 { $item[1] } |
|
48 |
|
49 range: /\d+/"-"/\d+/ |
|
50 { { from => $item[1], to => $item[3] } } |
|
51 |
|
52 keyword: /[\w-]+/ |
|
53 { $item[1] } |
|
54 |
|
55 identifier: /[0-9a-zA-Z:_-]+/ |
|
56 { $item[1] } |
|
57 |
|
58 quoted_text: <perl_quotelike> |
|
59 { $item[1][2] } |
|
60 | /[0-9a-zA-Z:\/_\#\"\.,-]+/ |
|
61 { $item[1] } |
|
62 |
|
63 value: /[0-9a-zA-Z:\/_\#\"\.,-]+/ |
|
64 { $item[1] } |
|
65 |
|
66 eofile: /^\Z/ |
|
67 |
|
68 eol: /\n/ |
|
69 |
|
70 rest_of_line: word(s) |
|
71 | eol |
|
72 |
|
73 # section |
|
74 section: cmdline(s) "!" |
|
75 { print "section\n"; } |
|
76 |
|
77 # Lines w/ hash (passwd, secret etc) |
|
78 l_hash: word(s) /\S+/ words(s) |
|
79 | word(s) /\S+/ |
|
80 |
|
81 # Hostname |
|
82 l_hostname: "hostname" identifier |
|
83 { $::res->{hostname} = $item{identifier} } |
|
84 |
|
85 # Description |
|
86 l_description: "description" /[^\n]+/ |
|
87 { $arg{ctx}->{description} = $item[2] } |
|
88 |
|
89 # controller section |
|
90 controller_num: /\d+\/\d+/ |
|
91 { $item[1] } |
|
92 |
|
93 s_controller: "controller" type controller_num s_controller_l[ctx => ctx('controller', $item{controller_num}) ](s) "!" eol |
|
94 { $::res->{controller}->{$item{controller_num}}->{type} = $item{type} } |
|
95 |
|
96 s_controller_l: l_description[ctx => $arg{ctx}] |
|
97 | "channel-group" num "timeslots" range |
|
98 { $arg{ctx}->{"channel-group"}->{$item{num}}->{ts} = $item{range} } |
|
99 | "channel-group" num "unframed" |
|
100 { $arg{ctx}->{"channel-group"}->{$item{num}}->{unframed} = 1 } |
|
101 | cmdline |
|
102 | emptyline |
|
103 | <error> |
|
104 |
|
105 # interface section |
|
106 iface_name: /\w+\d+(\/\d+)?(:\d+(\.\d+)?)?/ |
|
107 { $item[1] } |
|
108 |
|
109 s_interface: "interface" iface_name /\S*/ eol s_interface_l[ctx => ctx("interface", $item{iface_name}) ](s) "!" eol |
|
110 { |
|
111 print "interface $item{iface_name}\n"; |
|
112 $::res->{interface}->{$item{iface_name}}->{type} = $item[3] |
|
113 if length($item[3]) > 0 |
|
114 } |
|
115 |
|
116 ip: /\d+\.\d+\.\d+\.\d+/ |
|
117 { $item[1] } |
|
118 |
|
119 s_interface_l: l_description |
|
120 | /(no)?/ "shutdown" eol |
|
121 { $arg{ctx}->{shutdown} = ($item[1] eq 'no') ? 0 : 1 } |
|
122 | "ip" "address" ip ip eol |
|
123 { $arg{ctx}->{ip} = $item[3]; $arg{ctx}->{mask} = $item[4] } |
|
124 | "encapsulation" keyword /\S*/ eol |
|
125 { |
|
126 $arg{ctx}->{encap} = $item[2]; |
|
127 $arg{ctx}->{encap_param} = $item[3] if length($item[3]) > 0 |
|
128 } |
|
129 | "frame-relay" keyword keyword |
|
130 { $arg{ctx}->{"frame-relay"} = {type => $item[2], value => $item[3]} } |
|
131 | "bandwidth" num |
|
132 { $arg{ctx}->{bandwidth} = $item{num}; } |
|
133 |cmdline |
|
134 | emptyline |
|
135 | <error> |