r5475: Move some existing and new type information functions to typelist.pm
[samba.git] / source4 / build / pasn1 / asn1.yp
1 ########################
2 # ASN.1 Parse::Yapp parser
3 # Copyright (C) Stefan (metze) Metzmacher <metze@samba.org>
4 # released under the GNU GPL version 2 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
18 asn1: 
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
27 asn1_delimitter: 
28         delimitter
29 ;
30
31 asn1_definitions:
32         'DEFINITIONS'
33 ;
34
35 asn1_begin:
36         'BEGIN'
37 ;
38
39 asn1_end:
40         'END'
41 ;
42
43 asn1_decls:
44         asn1_def
45                 { [ $_[1] ] }
46         | asn1_decls asn1_def 
47                 { push(@{$_[1]}, $_[2]); $_[1] }
48 ;
49
50
51
52 asn1_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
62 asn1_target:
63         identifier
64 ;
65
66 asn1_application:
67         #empty
68         | '[' 'APPLICATION' constant ']'
69                 { $_[3] }
70 ;
71
72 asn1_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
85 asn1_boolean:
86         'BOOLEAN'
87                 {{
88                         "TYPE"          => "BOOLEAN",
89                         "TAG"           => 1
90                 }}
91 ;
92
93 asn1_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
108 asn1_bit_string:
109         'BIT' 'STRING'
110                 {{
111                         "TYPE"          => "BIT STRING",
112                         "TAG"           => 3
113                 }}
114 ;
115
116 asn1_octet_string:
117         'OCTET' 'STRING'
118                 {{
119                         "TYPE"          => "OCTET STRING",
120                         "TAG"           => 4
121                 }}
122 ;
123
124 asn1_null:
125         'NULL'
126                 {{
127                         "TYPE"          => "NULL",
128                         "TAG"           => 5
129                 }}
130 ;
131
132 asn1_object_identifier:
133         'OBJECT' 'IDENTIFIER'
134                 {{
135                         "TYPE"          => "OBJECT IDENTIFIER",
136                         "TAG"           => 6
137                 }}
138 ;
139
140 asn1_real:
141         'REAL'
142                 {{
143                         "TYPE"          => "REAL",
144                         "TAG"           => 9
145                 }}
146 ;
147
148 asn1_enumerated:
149         'ENUMERATED'
150                 {{
151                         "TYPE"          => "ENUMERATED",
152                         "TAG"           => 10
153                 }}
154 ;
155
156 asn1_sequence:
157         'SEQUENCE' '{' asn1_var_dec_list '}'
158                 {{
159                         "TYPE"          => "SEQUENCE",
160                         "TAG"           => 16,
161                         "STRUCTURE"     => $_[3]
162                 }}
163 ;
164
165 asn1_var_dec_list:
166         asn1_var_dec
167                 { [ $_[1] ] }
168         | asn1_var_dec_list ',' asn1_var_dec 
169                 { push(@{$_[1]}, $_[3]); $_[1]  }
170 ;
171
172 asn1_var_dec: 
173         identifier asn1_type
174         {{
175                 "NAME" => $_[1],
176                 "TYPE" => $_[2]
177         }}
178 ;
179
180 anytext:  #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
193 delimitter: DELIMITTER
194 ;
195
196 identifier: IDENTIFIER
197 ;
198
199 constant: CONSTANT
200 ;
201
202 text: TEXT { "\"$_[1]\"" }
203 ;
204
205 #####################################
206 # start code
207 %%
208
209 use util;
210
211 sub _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
224 sub _ASN1_Lexer($)
225 {
226         my($parser)=shift;
227
228         $parser->YYData->{INPUT}
229         or  return('',undef);
230
231 again:
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
288 sub 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 }