blob: c7bb18ecd3ca8d70dfe18a1aedec39dc344c5b30 [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
vlm066dc102005-08-22 12:23:54 +000028int asn1p_as_pointer;
29
vlmfa67ddc2004-06-03 03:38:44 +000030/*
31 * Check that the type is defined in the year of the standard choosen.
32 */
33#define TYPE_LIFETIME(fyr, lyr) \
34 (!asn1p_lexer_types_year \
35 || (fyr && fyr <= asn1p_lexer_types_year) \
36 || (lyr && lyr > asn1p_lexer_types_year))
37
38/*
39 * Check the the construction (or concept, i.e. CLASS) is defined in
40 * a given year.
41 */
42#define CONSTRUCT_LIFETIME(fyr, lyr) \
43 (!asn1p_lexer_constructs_year \
44 || (fyr && fyr <= asn1p_lexer_constructs_year) \
45 || (lyr && lyr > asn1p_lexer_constructs_year))
46
47/*
vlmfa67ddc2004-06-03 03:38:44 +000048 * Append quoted string.
49 */
50#define QAPPEND(text, tlen) do { \
51 char *prev_text = asn1p_lval.tv_opaque.buf; \
52 int prev_len = asn1p_lval.tv_opaque.len; \
53 char *p; \
54 \
55 p = malloc((tlen) + prev_len + 1); \
56 if(p == NULL) return -1; \
57 \
58 if(prev_text) memcpy(p, prev_text, prev_len); \
59 memcpy(p + prev_len, text, tlen); \
60 p[prev_len + (tlen)] = '\0'; \
61 \
62 free(asn1p_lval.tv_opaque.buf); \
63 asn1p_lval.tv_opaque.buf = p; \
64 asn1p_lval.tv_opaque.len = (tlen) + prev_len; \
65 } while(0)
66
67%}
68
69%option never-interactive
vlm9283dbe2004-08-18 04:59:12 +000070%option noinput
vlmfa67ddc2004-06-03 03:38:44 +000071%option noyywrap stack
72/* Performance penalty is OK */
73%option yylineno
74/* Controlled from within application */
75%option debug
76
77%pointer
78
79%x dash_comment
vlmb5abdc92005-07-02 21:42:40 +000080%x idash_comment
vlmfa67ddc2004-06-03 03:38:44 +000081%x cpp_comment
82%x quoted
83%x opaque
vlm9283dbe2004-08-18 04:59:12 +000084%x encoding_control
vlmfa67ddc2004-06-03 03:38:44 +000085%x with_syntax
86
87/* Newline */
88NL [\r\v\f\n]
89/* White-space */
90WSP [\t\r\v\f\n ]
91
92%%
93
vlmb5abdc92005-07-02 21:42:40 +000094-{3,}/[\r\n] /* Immediately terminated long comment */
95-{3,}/[^-\r\n] yy_push_state(idash_comment); /* Incorrect, but acceptable */
96<idash_comment>{
97 -{3,} yy_pop_state(); /* Acceptable end of comment */
98}
99
vlm177a5b62005-09-05 05:17:57 +0000100--<[ \t]*ASN1C.RepresentAsPointer[ \t]*>-- asn1p_as_pointer = 1;
101
vlmb5abdc92005-07-02 21:42:40 +0000102-- yy_push_state(dash_comment);
103<dash_comment,idash_comment>{
vlmfa67ddc2004-06-03 03:38:44 +0000104
105 {NL} yy_pop_state();
106
107 -- yy_pop_state(); /* End of comment */
108 - /* Eat single dash */
vlm177a5b62005-09-05 05:17:57 +0000109 [^\r\v\f\n-]+ /* Eat */
vlmfa67ddc2004-06-03 03:38:44 +0000110}
vlmb5abdc92005-07-02 21:42:40 +0000111
vlmfa67ddc2004-06-03 03:38:44 +0000112<INITIAL,cpp_comment>"/*" yy_push_state(cpp_comment);
113<cpp_comment>{
vlm066dc102005-08-22 12:23:54 +0000114 [^*/<] /* Eat */
vlmfa67ddc2004-06-03 03:38:44 +0000115 "*/" yy_pop_state();
116 . /* Eat */
117}
118
119
120 /*
121 * This is state is being set from corresponding .y module when
122 * higher-level data is necessary to make proper parsing of the
123 * underlying data. Thus, we enter the <opaque> state and save
124 * everything for later processing.
125 */
126<opaque>{
127
128 "{" {
129 yy_push_state(opaque);
130 asn1p_lval.tv_opaque.buf = strdup(yytext);
131 asn1p_lval.tv_opaque.len = yyleng;
132 return TOK_opaque;
133 }
134
135 "}" {
136 yy_pop_state();
137 asn1p_lval.tv_opaque.buf = strdup(yytext);
138 asn1p_lval.tv_opaque.len = yyleng;
139 return TOK_opaque;
140 }
141
142 [^{}:=]+ {
143 asn1p_lval.tv_opaque.buf = strdup(yytext);
144 asn1p_lval.tv_opaque.len = yyleng;
145 return TOK_opaque;
146 }
147
148 "::=" {
149 fprintf(stderr,
150 "ASN.1 Parser syncronization failure: "
151 "\"%s\" at line %d must not appear "
152 "inside value definition\n",
153 yytext, yylineno);
154 return -1;
155 }
156
157 [:=] {
158 asn1p_lval.tv_opaque.buf = strdup(yytext);
159 asn1p_lval.tv_opaque.len = yyleng;
160 return TOK_opaque;
161 }
162
163 }
164
165\"[^\"]* {
166 asn1p_lval.tv_opaque.buf = 0;
167 asn1p_lval.tv_opaque.len = 0;
168 QAPPEND(yytext+1, yyleng-1);
169 yy_push_state(quoted);
170 }
171<quoted>{
172
173 \"\" { QAPPEND(yytext, yyleng-1); } /* Add a single quote */
174 [^\"]+ { QAPPEND(yytext, yyleng); }
175
176 \" {
177 yy_pop_state();
178 /* Do not append last quote:
179 // QAPPEND(yytext, yyleng); */
180
181 if(asn1p_lexer_pedantic_1990
182 && strchr(yytext, '\n')) {
183 fprintf(stderr, "%s: "
184 "Newlines are prohibited by ASN.1:1990\n",
185 asn1p_lval.tv_opaque.buf);
186 return -1;
187 }
188
189 return TOK_cstring;
190 }
191
192 }
193
vlm9283dbe2004-08-18 04:59:12 +0000194<encoding_control>{
195 ENCODING-CONTROL {
196 const char *s = "ENCODING-CONTROL";
197 const char *p = s + sizeof("ENCODING-CONTROL") - 2;
198 for(; p >= s; p--) unput(*p);
199 yy_pop_state();
200 }
201 END unput('D'); unput('N'); unput('E'); yy_pop_state();
202 [^{} \t\r\v\f\n]+
203 [[:alnum:]]+
204 . /* Eat everything else */
205 "\n"
206 }
vlmfa67ddc2004-06-03 03:38:44 +0000207
208'[0-9A-F \t\r\v\f\n]+'H {
209 /* " \t\r\n" weren't allowed in ASN.1:1990. */
210 asn1p_lval.tv_str = yytext;
211 return TOK_hstring;
212 }
213
214'[01 \t\r\v\f\n]+'B {
215 /* " \t\r\n" weren't allowed in ASN.1:1990. */
216 asn1p_lval.tv_str = strdup(yytext);
217 return TOK_bstring;
218 }
219
220
221-[1-9][0-9]* {
222 asn1p_lval.a_int = asn1p_atoi(yytext);
223 if(errno == ERANGE)
224 return -1;
225 return TOK_number_negative;
226 }
227
228[1-9][0-9]* {
229 asn1p_lval.a_int = asn1p_atoi(yytext);
230 if(errno == ERANGE)
231 return -1;
232 return TOK_number;
233 }
234
235"0" {
236 asn1p_lval.a_int = asn1p_atoi(yytext);
237 if(errno == ERANGE)
238 return -1;
239 return TOK_number;
240 }
241
vlmfa67ddc2004-06-03 03:38:44 +0000242ABSENT return TOK_ABSENT;
vlmfa67ddc2004-06-03 03:38:44 +0000243ALL return TOK_ALL;
244ANY {
245 /* Appeared in 1990, removed in 1997 */
246 if(TYPE_LIFETIME(1990, 1997))
247 return TOK_ANY;
248 fprintf(stderr, "Keyword \"%s\" at line %d "
249 "is obsolete\n", yytext, yylineno);
250 REJECT;
251 }
252APPLICATION return TOK_APPLICATION;
253AUTOMATIC return TOK_AUTOMATIC;
254BEGIN return TOK_BEGIN;
255BIT return TOK_BIT;
256BMPString {
257 if(TYPE_LIFETIME(1994, 0))
258 return TOK_BMPString;
259 REJECT;
260 }
261BOOLEAN return TOK_BOOLEAN;
262BY return TOK_BY;
263CHARACTER return TOK_CHARACTER;
264CHOICE return TOK_CHOICE;
265CLASS return TOK_CLASS;
266COMPONENT return TOK_COMPONENT;
267COMPONENTS return TOK_COMPONENTS;
vlm6611add2005-03-20 14:28:32 +0000268CONSTRAINED return TOK_CONSTRAINED;
vlmfa67ddc2004-06-03 03:38:44 +0000269CONTAINING return TOK_CONTAINING;
270DEFAULT return TOK_DEFAULT;
271DEFINED {
272 /* Appeared in 1990, removed in 1997 */
273 if(TYPE_LIFETIME(1990, 1997))
274 return TOK_DEFINED;
275 fprintf(stderr, "Keyword \"%s\" at line %d "
276 "is obsolete\n", yytext, yylineno);
277 /* Deprecated since */
278 REJECT;
279 }
280DEFINITIONS return TOK_DEFINITIONS;
281EMBEDDED return TOK_EMBEDDED;
282ENCODED return TOK_ENCODED;
vlm9283dbe2004-08-18 04:59:12 +0000283ENCODING-CONTROL return TOK_ENCODING_CONTROL;
vlmfa67ddc2004-06-03 03:38:44 +0000284END return TOK_END;
285ENUMERATED return TOK_ENUMERATED;
286EXCEPT return TOK_EXCEPT;
287EXPLICIT return TOK_EXPLICIT;
288EXPORTS return TOK_EXPORTS;
289EXTENSIBILITY return TOK_EXTENSIBILITY;
290EXTERNAL return TOK_EXTERNAL;
291FALSE return TOK_FALSE;
292FROM return TOK_FROM;
293GeneralizedTime return TOK_GeneralizedTime;
294GeneralString return TOK_GeneralString;
295GraphicString return TOK_GraphicString;
296IA5String return TOK_IA5String;
297IDENTIFIER return TOK_IDENTIFIER;
298IMPLICIT return TOK_IMPLICIT;
299IMPLIED return TOK_IMPLIED;
300IMPORTS return TOK_IMPORTS;
301INCLUDES return TOK_INCLUDES;
302INSTANCE return TOK_INSTANCE;
vlm9283dbe2004-08-18 04:59:12 +0000303INSTRUCTIONS return TOK_INSTRUCTIONS;
vlmfa67ddc2004-06-03 03:38:44 +0000304INTEGER return TOK_INTEGER;
305INTERSECTION return TOK_INTERSECTION;
306ISO646String return TOK_ISO646String;
307MAX return TOK_MAX;
308MIN return TOK_MIN;
309MINUS-INFINITY return TOK_MINUS_INFINITY;
310NULL return TOK_NULL;
311NumericString return TOK_NumericString;
312OBJECT return TOK_OBJECT;
313ObjectDescriptor return TOK_ObjectDescriptor;
314OCTET return TOK_OCTET;
315OF return TOK_OF;
316OPTIONAL return TOK_OPTIONAL;
317PATTERN return TOK_PATTERN;
318PDV return TOK_PDV;
319PLUS-INFINITY return TOK_PLUS_INFINITY;
320PRESENT return TOK_PRESENT;
321PrintableString return TOK_PrintableString;
322PRIVATE return TOK_PRIVATE;
323REAL return TOK_REAL;
324RELATIVE-OID return TOK_RELATIVE_OID;
325SEQUENCE return TOK_SEQUENCE;
326SET return TOK_SET;
327SIZE return TOK_SIZE;
328STRING return TOK_STRING;
329SYNTAX return TOK_SYNTAX;
330T61String return TOK_T61String;
331TAGS return TOK_TAGS;
332TeletexString return TOK_TeletexString;
333TRUE return TOK_TRUE;
vlmfa67ddc2004-06-03 03:38:44 +0000334UNION 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