source: trunk/server/source4/build/pasn1/asn1.yp

Last change on this file was 414, checked in by Herwig Bauernfeind, 16 years ago

Samba 3.5.0: Initial import

File size: 5.2 KB
Line 
1########################
2# ASN.1 Parse::Yapp parser
3# Copyright (C) Stefan (metze) Metzmacher <metze@samba.org>
4# released under the GNU GPL version 3 or later
5
6
7
8# the precedence actually doesn't matter at all for this grammer, but
9# by providing a precedence we reduce the number of conflicts
10# enormously
11%left '-' '+' '&' '|' '*' '>' '.' '/' '(' ')' '[' ']' ':' ',' ';'
12
13
14################
15# grammer
16%%
17
18asn1:
19 identifier asn1_definitions asn1_delimitter asn1_begin asn1_decls asn1_end
20 {{
21 "OBJECT" => "ASN1_DEFINITION",
22 "IDENTIFIER" => $_[1],
23 "DATA" => $_[5]
24 }}
25;
26
27asn1_delimitter:
28 delimitter
29;
30
31asn1_definitions:
32 'DEFINITIONS'
33;
34
35asn1_begin:
36 'BEGIN'
37;
38
39asn1_end:
40 'END'
41;
42
43asn1_decls:
44 asn1_def
45 { [ $_[1] ] }
46 | asn1_decls asn1_def
47 { push(@{$_[1]}, $_[2]); $_[1] }
48;
49
50
51
52asn1_def:
53 asn1_target asn1_delimitter asn1_application asn1_type
54 {{
55 "OBJECT" => "ASN1_DEF",
56 "IDENTIFIER" => $_[1],
57 "APPLICATION" => $_[3],
58 "STRUCTURE" => $_[4]
59 }}
60;
61
62asn1_target:
63 identifier
64;
65
66asn1_application:
67 #empty
68 | '[' 'APPLICATION' constant ']'
69 { $_[3] }
70;
71
72asn1_type:
73 asn1_boolean
74 | asn1_integer
75 | asn1_bit_string
76 | asn1_octet_string
77 | asn1_null
78 | asn1_object_identifier
79 | asn1_real
80 | asn1_enumerated
81 | asn1_sequence
82 | identifier
83;
84
85asn1_boolean:
86 'BOOLEAN'
87 {{
88 "TYPE" => "BOOLEAN",
89 "TAG" => 1
90 }}
91;
92
93asn1_integer:
94 'INTEGER'
95 {{
96 "TYPE" => "INTEGER",
97 "TAG" => 2
98 }}
99 | 'INTEGER' '(' constant '.' '.' constant ')'
100 {{
101 "TYPE" => "INTEGER",
102 "TAG" => 2,
103 "RANGE_LOW" => $_[3],
104 "RENAGE_HIGH" => $_[6]
105 }}
106;
107
108asn1_bit_string:
109 'BIT' 'STRING'
110 {{
111 "TYPE" => "BIT STRING",
112 "TAG" => 3
113 }}
114;
115
116asn1_octet_string:
117 'OCTET' 'STRING'
118 {{
119 "TYPE" => "OCTET STRING",
120 "TAG" => 4
121 }}
122;
123
124asn1_null:
125 'NULL'
126 {{
127 "TYPE" => "NULL",
128 "TAG" => 5
129 }}
130;
131
132asn1_object_identifier:
133 'OBJECT' 'IDENTIFIER'
134 {{
135 "TYPE" => "OBJECT IDENTIFIER",
136 "TAG" => 6
137 }}
138;
139
140asn1_real:
141 'REAL'
142 {{
143 "TYPE" => "REAL",
144 "TAG" => 9
145 }}
146;
147
148asn1_enumerated:
149 'ENUMERATED'
150 {{
151 "TYPE" => "ENUMERATED",
152 "TAG" => 10
153 }}
154;
155
156asn1_sequence:
157 'SEQUENCE' '{' asn1_var_dec_list '}'
158 {{
159 "TYPE" => "SEQUENCE",
160 "TAG" => 16,
161 "STRUCTURE" => $_[3]
162 }}
163;
164
165asn1_var_dec_list:
166 asn1_var_dec
167 { [ $_[1] ] }
168 | asn1_var_dec_list ',' asn1_var_dec
169 { push(@{$_[1]}, $_[3]); $_[1] }
170;
171
172asn1_var_dec:
173 identifier asn1_type
174 {{
175 "NAME" => $_[1],
176 "TYPE" => $_[2]
177 }}
178;
179
180anytext: #empty { "" }
181 | identifier | constant | text
182 | anytext '-' anytext { "$_[1]$_[2]$_[3]" }
183 | anytext '.' anytext { "$_[1]$_[2]$_[3]" }
184 | anytext '*' anytext { "$_[1]$_[2]$_[3]" }
185 | anytext '>' anytext { "$_[1]$_[2]$_[3]" }
186 | anytext '|' anytext { "$_[1]$_[2]$_[3]" }
187 | anytext '&' anytext { "$_[1]$_[2]$_[3]" }
188 | anytext '/' anytext { "$_[1]$_[2]$_[3]" }
189 | anytext '+' anytext { "$_[1]$_[2]$_[3]" }
190 | anytext '(' anytext ')' anytext { "$_[1]$_[2]$_[3]$_[4]$_[5]" }
191;
192
193delimitter: DELIMITTER
194;
195
196identifier: IDENTIFIER
197;
198
199constant: CONSTANT
200;
201
202text: TEXT { "\"$_[1]\"" }
203;
204
205#####################################
206# start code
207%%
208
209use util;
210
211sub _ASN1_Error {
212 if (exists $_[0]->YYData->{ERRMSG}) {
213 print $_[0]->YYData->{ERRMSG};
214 delete $_[0]->YYData->{ERRMSG};
215 return;
216 };
217 my $line = $_[0]->YYData->{LINE};
218 my $last_token = $_[0]->YYData->{LAST_TOKEN};
219 my $file = $_[0]->YYData->{INPUT_FILENAME};
220
221 print "$file:$line: Syntax error near '$last_token'\n";
222}
223
224sub _ASN1_Lexer($)
225{
226 my($parser)=shift;
227
228 $parser->YYData->{INPUT}
229 or return('',undef);
230
231again:
232 $parser->YYData->{INPUT} =~ s/^[ \t]*//;
233
234 for ($parser->YYData->{INPUT}) {
235 if (/^\#/) {
236 if (s/^\# (\d+) \"(.*?)\"( \d+|)//) {
237 $parser->YYData->{LINE} = $1-1;
238 $parser->YYData->{INPUT_FILENAME} = $2;
239 goto again;
240 }
241 if (s/^\#line (\d+) \"(.*?)\"( \d+|)//) {
242 $parser->YYData->{LINE} = $1-1;
243 $parser->YYData->{INPUT_FILENAME} = $2;
244 goto again;
245 }
246 if (s/^(\#.*)$//m) {
247 goto again;
248 }
249 }
250 if (s/^(\n)//) {
251 $parser->YYData->{LINE}++;
252 goto again;
253 }
254 if (s/^(--.*\n)//) {
255 $parser->YYData->{LINE}++;
256 goto again;
257 }
258 if (s/^(::=)//) {
259 $parser->YYData->{LAST_TOKEN} = $1;
260 return('DELIMITTER',$1);
261 }
262 if (s/^\"(.*?)\"//) {
263 $parser->YYData->{LAST_TOKEN} = $1;
264 return('TEXT',$1);
265 }
266 if (s/^(\d+)(\W|$)/$2/) {
267 $parser->YYData->{LAST_TOKEN} = $1;
268 return('CONSTANT',$1);
269 }
270 if (s/^([\w_-]+)//) {
271 $parser->YYData->{LAST_TOKEN} = $1;
272 if ($1 =~
273 /^(SEQUENCE|INTEGER|OCTET|STRING|
274 APPLICATION|OPTIONAL|NULL|COMPONENTS|OF|
275 BOOLEAN|ENUMERATED|CHOISE|REAL|BIT|OBJECT|IDENTIFIER|
276 DEFAULT|FALSE|TRUE|SET|DEFINITIONS|BEGIN|END)$/x) {
277 return $1;
278 }
279 return('IDENTIFIER',$1);
280 }
281 if (s/^(.)//s) {
282 $parser->YYData->{LAST_TOKEN} = $1;
283 return($1,$1);
284 }
285 }
286}
287
288sub parse_asn1($$)
289{
290 my $self = shift;
291 my $filename = shift;
292
293 my $saved_delim = $/;
294 undef $/;
295 my $cpp = $ENV{CPP};
296 if (! defined $cpp) {
297 $cpp = "cpp"
298 }
299 my $data = `$cpp -xc $filename`;
300 $/ = $saved_delim;
301
302 $self->YYData->{INPUT} = $data;
303 $self->YYData->{LINE} = 0;
304 $self->YYData->{LAST_TOKEN} = "NONE";
305 return $self->YYParse( yylex => \&_ASN1_Lexer, yyerror => \&_ASN1_Error );
306}
Note: See TracBrowser for help on using the repository browser.