blob: 04a550469c1084889f98684ec4833d24a8f7a1a3 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001%{
2
3#include <string.h>
4#include <errno.h>
5#include <assert.h>
6
7#include "asn1parser.h"
8#include "asn1p_y.h"
9
10int asn1p_lex(void);
11void asn1p_lexer_hack_push_opaque_state(void); /* Used in .y */
12void asn1p_lexer_hack_enable_with_syntax(void); /* Used in .y */
vlm9283dbe2004-08-18 04:59:12 +000013void asn1p_lexer_hack_push_encoding_control(void); /* Used in .y */
vlmfa67ddc2004-06-03 03:38:44 +000014
15#define YY_FATAL_ERROR(msg) do { \
16 fprintf(stderr, \
17 "lexer error at line %d, " \
18 "text \"%s\"\n", \
19 yylineno, yytext); \
20 exit(1); \
21 } while(0)
22
23int asn1p_lexer_pedantic_1990 = 0;
24int asn1p_lexer_types_year = 0;
25int asn1p_lexer_constructs_year = 0;
vlm2728a8d2005-01-23 09:51:44 +000026static asn1c_integer_t asn1p_atoi(char *ptr); /* errno is either 0 or ERANGE */
vlmfa67ddc2004-06-03 03:38:44 +000027
28/*
29 * Check that the type is defined in the year of the standard choosen.
30 */
31#define TYPE_LIFETIME(fyr, lyr) \
32 (!asn1p_lexer_types_year \
33 || (fyr && fyr <= asn1p_lexer_types_year) \
34 || (lyr && lyr > asn1p_lexer_types_year))
35
36/*
37 * Check the the construction (or concept, i.e. CLASS) is defined in
38 * a given year.
39 */
40#define CONSTRUCT_LIFETIME(fyr, lyr) \
41 (!asn1p_lexer_constructs_year \
42 || (fyr && fyr <= asn1p_lexer_constructs_year) \
43 || (lyr && lyr > asn1p_lexer_constructs_year))
44
45/*
vlmfa67ddc2004-06-03 03:38:44 +000046 * Append quoted string.
47 */
48#define QAPPEND(text, tlen) do { \
49 char *prev_text = asn1p_lval.tv_opaque.buf; \
50 int prev_len = asn1p_lval.tv_opaque.len; \
51 char *p; \
52 \
53 p = malloc((tlen) + prev_len + 1); \
54 if(p == NULL) return -1; \
55 \
56 if(prev_text) memcpy(p, prev_text, prev_len); \
57 memcpy(p + prev_len, text, tlen); \
58 p[prev_len + (tlen)] = '\0'; \
59 \
60 free(asn1p_lval.tv_opaque.buf); \
61 asn1p_lval.tv_opaque.buf = p; \
62 asn1p_lval.tv_opaque.len = (tlen) + prev_len; \
63 } while(0)
64
65%}
66
67%option never-interactive
vlm9283dbe2004-08-18 04:59:12 +000068%option noinput
vlmfa67ddc2004-06-03 03:38:44 +000069%option noyywrap stack
70/* Performance penalty is OK */
71%option yylineno
72/* Controlled from within application */
73%option debug
74
75%pointer
76
77%x dash_comment
vlmb5abdc92005-07-02 21:42:40 +000078%x idash_comment
vlmfa67ddc2004-06-03 03:38:44 +000079%x cpp_comment
80%x quoted
81%x opaque
vlm9283dbe2004-08-18 04:59:12 +000082%x encoding_control
vlmfa67ddc2004-06-03 03:38:44 +000083%x with_syntax
84
85/* Newline */
86NL [\r\v\f\n]
87/* White-space */
88WSP [\t\r\v\f\n ]
89
90%%
91
vlmb5abdc92005-07-02 21:42:40 +000092-{3,}/[\r\n] /* Immediately terminated long comment */
93-{3,}/[^-\r\n] yy_push_state(idash_comment); /* Incorrect, but acceptable */
94<idash_comment>{
95 -{3,} yy_pop_state(); /* Acceptable end of comment */
96}
97
98-- yy_push_state(dash_comment);
99<dash_comment,idash_comment>{
vlmfa67ddc2004-06-03 03:38:44 +0000100
101 {NL} yy_pop_state();
102
103 -- yy_pop_state(); /* End of comment */
104 - /* Eat single dash */
105 [^\r\v\f\n-]+ /* Eat */
vlmfa67ddc2004-06-03 03:38:44 +0000106}
vlmb5abdc92005-07-02 21:42:40 +0000107
vlmfa67ddc2004-06-03 03:38:44 +0000108<INITIAL,cpp_comment>"/*" yy_push_state(cpp_comment);
109<cpp_comment>{
110 [^*/] /* Eat */
111 "*/" yy_pop_state();
112 . /* Eat */
113}
114
115
116 /*
117 * This is state is being set from corresponding .y module when
118 * higher-level data is necessary to make proper parsing of the
119 * underlying data. Thus, we enter the <opaque> state and save
120 * everything for later processing.
121 */
122<opaque>{
123
124 "{" {
125 yy_push_state(opaque);
126 asn1p_lval.tv_opaque.buf = strdup(yytext);
127 asn1p_lval.tv_opaque.len = yyleng;
128 return TOK_opaque;
129 }
130
131 "}" {
132 yy_pop_state();
133 asn1p_lval.tv_opaque.buf = strdup(yytext);
134 asn1p_lval.tv_opaque.len = yyleng;
135 return TOK_opaque;
136 }
137
138 [^{}:=]+ {
139 asn1p_lval.tv_opaque.buf = strdup(yytext);
140 asn1p_lval.tv_opaque.len = yyleng;
141 return TOK_opaque;
142 }
143
144 "::=" {
145 fprintf(stderr,
146 "ASN.1 Parser syncronization failure: "
147 "\"%s\" at line %d must not appear "
148 "inside value definition\n",
149 yytext, yylineno);
150 return -1;
151 }
152
153 [:=] {
154 asn1p_lval.tv_opaque.buf = strdup(yytext);
155 asn1p_lval.tv_opaque.len = yyleng;
156 return TOK_opaque;
157 }
158
159 }
160
161\"[^\"]* {
162 asn1p_lval.tv_opaque.buf = 0;
163 asn1p_lval.tv_opaque.len = 0;
164 QAPPEND(yytext+1, yyleng-1);
165 yy_push_state(quoted);
166 }
167<quoted>{
168
169 \"\" { QAPPEND(yytext, yyleng-1); } /* Add a single quote */
170 [^\"]+ { QAPPEND(yytext, yyleng); }
171
172 \" {
173 yy_pop_state();
174 /* Do not append last quote:
175 // QAPPEND(yytext, yyleng); */
176
177 if(asn1p_lexer_pedantic_1990
178 && strchr(yytext, '\n')) {
179 fprintf(stderr, "%s: "
180 "Newlines are prohibited by ASN.1:1990\n",
181 asn1p_lval.tv_opaque.buf);
182 return -1;
183 }
184
185 return TOK_cstring;
186 }
187
188 }
189
vlm9283dbe2004-08-18 04:59:12 +0000190<encoding_control>{
191 ENCODING-CONTROL {
192 const char *s = "ENCODING-CONTROL";
193 const char *p = s + sizeof("ENCODING-CONTROL") - 2;
194 for(; p >= s; p--) unput(*p);
195 yy_pop_state();
196 }
197 END unput('D'); unput('N'); unput('E'); yy_pop_state();
198 [^{} \t\r\v\f\n]+
199 [[:alnum:]]+
200 . /* Eat everything else */
201 "\n"
202 }
vlmfa67ddc2004-06-03 03:38:44 +0000203
204'[0-9A-F \t\r\v\f\n]+'H {
205 /* " \t\r\n" weren't allowed in ASN.1:1990. */
206 asn1p_lval.tv_str = yytext;
207 return TOK_hstring;
208 }
209
210'[01 \t\r\v\f\n]+'B {
211 /* " \t\r\n" weren't allowed in ASN.1:1990. */
212 asn1p_lval.tv_str = strdup(yytext);
213 return TOK_bstring;
214 }
215
216
217-[1-9][0-9]* {
218 asn1p_lval.a_int = asn1p_atoi(yytext);
219 if(errno == ERANGE)
220 return -1;
221 return TOK_number_negative;
222 }
223
224[1-9][0-9]* {
225 asn1p_lval.a_int = asn1p_atoi(yytext);
226 if(errno == ERANGE)
227 return -1;
228 return TOK_number;
229 }
230
231"0" {
232 asn1p_lval.a_int = asn1p_atoi(yytext);
233 if(errno == ERANGE)
234 return -1;
235 return TOK_number;
236 }
237
vlmfa67ddc2004-06-03 03:38:44 +0000238ABSENT return TOK_ABSENT;
vlmc94e28f2004-09-15 11:59:51 +0000239 /*
vlmfa67ddc2004-06-03 03:38:44 +0000240ABSTRACT-SYNTAX return TOK_ABSTRACT_SYNTAX;
vlmc94e28f2004-09-15 11:59:51 +0000241 */
vlmfa67ddc2004-06-03 03:38:44 +0000242ALL return TOK_ALL;
243ANY {
244 /* Appeared in 1990, removed in 1997 */
245 if(TYPE_LIFETIME(1990, 1997))
246 return TOK_ANY;
247 fprintf(stderr, "Keyword \"%s\" at line %d "
248 "is obsolete\n", yytext, yylineno);
249 REJECT;
250 }
251APPLICATION return TOK_APPLICATION;
252AUTOMATIC return TOK_AUTOMATIC;
253BEGIN return TOK_BEGIN;
254BIT return TOK_BIT;
255BMPString {
256 if(TYPE_LIFETIME(1994, 0))
257 return TOK_BMPString;
258 REJECT;
259 }
260BOOLEAN return TOK_BOOLEAN;
261BY return TOK_BY;
262CHARACTER return TOK_CHARACTER;
263CHOICE return TOK_CHOICE;
264CLASS return TOK_CLASS;
265COMPONENT return TOK_COMPONENT;
266COMPONENTS return TOK_COMPONENTS;
vlm6611add2005-03-20 14:28:32 +0000267CONSTRAINED return TOK_CONSTRAINED;
vlmfa67ddc2004-06-03 03:38:44 +0000268CONTAINING return TOK_CONTAINING;
269DEFAULT return TOK_DEFAULT;
270DEFINED {
271 /* Appeared in 1990, removed in 1997 */
272 if(TYPE_LIFETIME(1990, 1997))
273 return TOK_DEFINED;
274 fprintf(stderr, "Keyword \"%s\" at line %d "
275 "is obsolete\n", yytext, yylineno);
276 /* Deprecated since */
277 REJECT;
278 }
279DEFINITIONS return TOK_DEFINITIONS;
280EMBEDDED return TOK_EMBEDDED;
281ENCODED return TOK_ENCODED;
vlm9283dbe2004-08-18 04:59:12 +0000282ENCODING-CONTROL return TOK_ENCODING_CONTROL;
vlmfa67ddc2004-06-03 03:38:44 +0000283END return TOK_END;
284ENUMERATED return TOK_ENUMERATED;
285EXCEPT return TOK_EXCEPT;
286EXPLICIT return TOK_EXPLICIT;
287EXPORTS return TOK_EXPORTS;
288EXTENSIBILITY return TOK_EXTENSIBILITY;
289EXTERNAL return TOK_EXTERNAL;
290FALSE return TOK_FALSE;
291FROM return TOK_FROM;
292GeneralizedTime return TOK_GeneralizedTime;
293GeneralString return TOK_GeneralString;
294GraphicString return TOK_GraphicString;
295IA5String return TOK_IA5String;
296IDENTIFIER return TOK_IDENTIFIER;
297IMPLICIT return TOK_IMPLICIT;
298IMPLIED return TOK_IMPLIED;
299IMPORTS return TOK_IMPORTS;
300INCLUDES return TOK_INCLUDES;
301INSTANCE return TOK_INSTANCE;
vlm9283dbe2004-08-18 04:59:12 +0000302INSTRUCTIONS return TOK_INSTRUCTIONS;
vlmfa67ddc2004-06-03 03:38:44 +0000303INTEGER return TOK_INTEGER;
304INTERSECTION return TOK_INTERSECTION;
305ISO646String return TOK_ISO646String;
306MAX return TOK_MAX;
307MIN return TOK_MIN;
308MINUS-INFINITY return TOK_MINUS_INFINITY;
309NULL return TOK_NULL;
310NumericString return TOK_NumericString;
311OBJECT return TOK_OBJECT;
312ObjectDescriptor return TOK_ObjectDescriptor;
313OCTET return TOK_OCTET;
314OF return TOK_OF;
315OPTIONAL return TOK_OPTIONAL;
316PATTERN return TOK_PATTERN;
317PDV return TOK_PDV;
318PLUS-INFINITY return TOK_PLUS_INFINITY;
319PRESENT return TOK_PRESENT;
320PrintableString return TOK_PrintableString;
321PRIVATE return TOK_PRIVATE;
322REAL return TOK_REAL;
323RELATIVE-OID return TOK_RELATIVE_OID;
324SEQUENCE return TOK_SEQUENCE;
325SET return TOK_SET;
326SIZE return TOK_SIZE;
327STRING return TOK_STRING;
328SYNTAX return TOK_SYNTAX;
329T61String return TOK_T61String;
330TAGS return TOK_TAGS;
331TeletexString return TOK_TeletexString;
332TRUE return TOK_TRUE;
333TYPE-IDENTIFIER return TOK_TYPE_IDENTIFIER;
334UNION return TOK_UNION;
335UNIQUE return TOK_UNIQUE;
336UNIVERSAL return TOK_UNIVERSAL;
337UniversalString {
338 if(TYPE_LIFETIME(1994, 0))
339 return TOK_UniversalString;
340 REJECT;
341 }
342UTCTime return TOK_UTCTime;
343UTF8String {
344 if(TYPE_LIFETIME(1994, 0))
345 return TOK_UTF8String;
346 REJECT;
347 }
348VideotexString return TOK_VideotexString;
349VisibleString return TOK_VisibleString;
350WITH return TOK_WITH;
351
352
vlmb5abdc92005-07-02 21:42:40 +0000353<INITIAL,with_syntax>&[A-Z][A-Za-z0-9]*([-][A-Za-z0-9]+)* {
vlmfa67ddc2004-06-03 03:38:44 +0000354 asn1p_lval.tv_str = strdup(yytext);
355 return TOK_typefieldreference;
356 }
357
vlmb5abdc92005-07-02 21:42:40 +0000358<INITIAL,with_syntax>&[a-z][a-zA-Z0-9]*([-][a-zA-Z0-9]+)* {
vlmfa67ddc2004-06-03 03:38:44 +0000359 asn1p_lval.tv_str = strdup(yytext);
360 return TOK_valuefieldreference;
361 }
362
363
vlmb5abdc92005-07-02 21:42:40 +0000364[a-z][a-zA-Z0-9]*([-][a-zA-Z0-9]+)* {
vlmfa67ddc2004-06-03 03:38:44 +0000365 asn1p_lval.tv_str = strdup(yytext);
366 return TOK_identifier;
367 }
368
369 /*
370 * objectclassreference
371 */
vlmb5abdc92005-07-02 21:42:40 +0000372[A-Z][A-Z0-9]*([-][A-Z0-9]+)* {
vlmfa67ddc2004-06-03 03:38:44 +0000373 asn1p_lval.tv_str = strdup(yytext);
vlm9283dbe2004-08-18 04:59:12 +0000374 return TOK_capitalreference;
vlmfa67ddc2004-06-03 03:38:44 +0000375 }
376
377 /*
378 * typereference, modulereference
379 * NOTE: TOK_objectclassreference must be combined
380 * with this token to produce true typereference.
381 */
vlmb5abdc92005-07-02 21:42:40 +0000382[A-Z][A-Za-z0-9]*([-][A-Za-z0-9]+)* {
vlmfa67ddc2004-06-03 03:38:44 +0000383 asn1p_lval.tv_str = strdup(yytext);
384 return TOK_typereference;
385 }
386
387"::=" return TOK_PPEQ;
388
389"..." return TOK_ThreeDots;
390".." return TOK_TwoDots;
391
vlmfa67ddc2004-06-03 03:38:44 +0000392<with_syntax>{
393
394 [^&{} \t\r\v\f\n]+ {
395 asn1p_lval.tv_opaque.buf = strdup(yytext);
396 asn1p_lval.tv_opaque.len = yyleng;
397 return TOK_opaque;
398 }
399
400 {WSP}+ {
401 asn1p_lval.tv_opaque.buf = strdup(yytext);
402 asn1p_lval.tv_opaque.len = yyleng;
403 return TOK_opaque;
404 }
405
406 "}" {
407 yy_pop_state();
408 return '}';
409 }
410
411}
412
vlm2c8c44d2005-03-24 16:22:35 +0000413
414{WSP}+ /* Ignore whitespace */
415
416
417[{][\t\r\v\f\n ]*[0-7][,][\t\r\v\f\n ]*[0-9]+[\t\r\v\f\n ]*[}] {
418 asn1c_integer_t v1 = -1, v2 = -1;
419 char *p;
420 for(p = yytext; *p; p++)
421 if(*p >= '0' && *p <= '9')
422 { v1 = asn1p_atoi(p); break; }
423 while(*p >= '0' && *p <= '9') p++; /* Skip digits */
424 for(; *p; p++) if(*p >= '0' && *p <= '9')
425 { v2 = asn1p_atoi(p); break; }
426 if(v1 < 0 || v1 > 7) {
427 fprintf(stderr, "%s at line %d: X.680:2003, #37.14 "
428 "mandates 0..7 range for Tuple's TableColumn\n",
429 yytext, yylineno);
430 return -1;
431 }
432 if(v2 < 0 || v2 > 15) {
433 fprintf(stderr, "%s at line %d: X.680:2003, #37.14 "
434 "mandates 0..15 range for Tuple's TableRow\n",
435 yytext, yylineno);
436 return -1;
437 }
438 asn1p_lval.a_int = (v1 << 4) + v2;
439 return TOK_tuple;
440 }
441
442[{][\t\r\v\f\n ]*[0-9]+[,][\t\r\v\f\n ]*[0-9]+[,][\t\r\v\f\n ]*[0-9]+[,][\t\r\v\f\n ]*[0-9]+[\t\r\v\f\n ]*[}] {
443 asn1c_integer_t v1 = -1, v2 = -1, v3 = -1, v4 = -1;
444 char *p;
445 for(p = yytext; *p; p++)
446 if(*p >= '0' && *p <= '9')
447 { v1 = asn1p_atoi(p); break; }
448 while(*p >= '0' && *p <= '9') p++; /* Skip digits */
449 for(; *p; p++) if(*p >= '0' && *p <= '9')
450 { v2 = asn1p_atoi(p); break; }
451 while(*p >= '0' && *p <= '9') p++;
452 for(; *p; p++) if(*p >= '0' && *p <= '9')
453 { v3 = asn1p_atoi(p); break; }
454 while(*p >= '0' && *p <= '9') p++;
455 for(; *p; p++) if(*p >= '0' && *p <= '9')
456 { v4 = asn1p_atoi(p); break; }
457 if(v1 < 0 || v1 > 127) {
458 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
459 "mandates 0..127 range for Quadruple's Group\n",
460 yytext, yylineno);
461 return -1;
462 }
463 if(v2 < 0 || v2 > 255) {
464 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
465 "mandates 0..255 range for Quadruple's Plane\n",
466 yytext, yylineno);
467 return -1;
468 }
469 if(v3 < 0 || v3 > 255) {
470 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
471 "mandates 0..255 range for Quadruple's Row\n",
472 yytext, yylineno);
473 return -1;
474 }
475 if(v4 < 0 || v4 > 255) {
476 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
477 "mandates 0..255 range for Quadruple's Cell\n",
478 yytext, yylineno);
479 return -1;
480 }
481 asn1p_lval.a_int = (v1 << 24) | (v2 << 16) | (v3 << 8) | v4;
482 return TOK_quadruple;
483 }
484
485
486[(){},;:|!.&@\[\]^] return yytext[0];
487
488[^A-Za-z0-9:=,{}<.@()[]'\"|&^*;!-] {
489 if(TYPE_LIFETIME(1994, 0))
490 fprintf(stderr, "ERROR: ");
491 fprintf(stderr,
492 "Symbol '%c' at line %d is prohibited "
493 "by ASN.1:1994 and ASN.1:1997\n",
494 yytext[0], yylineno);
495 if(TYPE_LIFETIME(1994, 0))
496 return -1;
497 }
vlmfa67ddc2004-06-03 03:38:44 +0000498
499<*>. {
500 fprintf(stderr,
501 "Unexpected token at line %d: \"%s\"\n",
502 yylineno, yytext);
503 while(YYSTATE != INITIAL)
504 yy_pop_state();
vlmc94e28f2004-09-15 11:59:51 +0000505 if(0) {
506 yy_top_state(); /* Just to use this function. */
507 yy_fatal_error("Parse error");
508 }
vlmfa67ddc2004-06-03 03:38:44 +0000509 return -1;
510}
511
512<*><<EOF>> {
513 while(YYSTATE != INITIAL)
514 yy_pop_state();
515 yyterminate();
516 }
517
518
519%%
520
521/*
522 * Very dirty but wonderful hack allowing to rule states from within .y file.
523 */
vlm9283dbe2004-08-18 04:59:12 +0000524void asn1p_lexer_hack_push_opaque_state() { yy_push_state(opaque); }
vlmfa67ddc2004-06-03 03:38:44 +0000525
526/*
527 * Another hack which disables recognizing some tokens when inside WITH SYNTAX.
528 */
vlm9283dbe2004-08-18 04:59:12 +0000529void asn1p_lexer_hack_enable_with_syntax() { yy_push_state(with_syntax); }
530
531/* Yet another */
532void asn1p_lexer_hack_push_encoding_control() {
533 yy_push_state(encoding_control);
vlmfa67ddc2004-06-03 03:38:44 +0000534}
535
vlm2728a8d2005-01-23 09:51:44 +0000536static asn1c_integer_t
vlmfa67ddc2004-06-03 03:38:44 +0000537asn1p_atoi(char *ptr) {
vlm2728a8d2005-01-23 09:51:44 +0000538 asn1c_integer_t value;
vlmfa67ddc2004-06-03 03:38:44 +0000539 errno = 0; /* Clear the error code */
540
541 if(sizeof(value) <= sizeof(int)) {
542 value = strtol(ptr, 0, 10);
543 } else {
544#ifdef HAVE_STRTOIMAX
545 value = strtoimax(ptr, 0, 10);
546#elif HAVE_STRTOLL
547 value = strtoll(ptr, 0, 10);
548#else
549 value = strtol(ptr, 0, 10);
550#endif
551 }
552
553 if(errno == ERANGE) {
554 fprintf(stderr,
555 "Value \"%s\" at line %d is too large "
vlm86912f02005-04-05 08:46:22 +0000556 "for this compiler! Please contact the asn1c author.\n",
vlmfa67ddc2004-06-03 03:38:44 +0000557 ptr, yylineno);
558 errno = ERANGE; /* Restore potentially clobbered errno */
559 }
560
561 return value;
562}
563