blob: a327277f06f8319c21ba468544d24ea7e0e337f8 [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
vlm808411d2006-03-14 16:31:37 +0000102<INITIAL,with_syntax>-- yy_push_state(dash_comment);
vlmb5abdc92005-07-02 21:42:40 +0000103<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
vlm808411d2006-03-14 16:31:37 +0000112<INITIAL,cpp_comment,with_syntax>"/*" yy_push_state(cpp_comment);
vlmfa67ddc2004-06-03 03:38:44 +0000113<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
vlm808411d2006-03-14 16:31:37 +0000394 [A-Z][A-Za-z0-9]*([-][A-Za-z0-9]+)* {
395 asn1p_lval.tv_str = strdup(yytext);
396 return TOK_Literal;
vlmfa67ddc2004-06-03 03:38:44 +0000397 }
398
vlm808411d2006-03-14 16:31:37 +0000399 "," {
400 asn1p_lval.tv_str = strdup(yytext);
401 return TOK_Literal;
402 }
403
404 "{" {
405 yy_push_state(with_syntax);
406 asn1p_lval.tv_str = strdup(yytext);
407 return TOK_Literal;
408 }
409
410 "[" return '[';
411 "]" return ']';
412
vlmfa67ddc2004-06-03 03:38:44 +0000413 {WSP}+ {
414 asn1p_lval.tv_opaque.buf = strdup(yytext);
415 asn1p_lval.tv_opaque.len = yyleng;
416 return TOK_opaque;
417 }
418
419 "}" {
420 yy_pop_state();
vlm808411d2006-03-14 16:31:37 +0000421 if(YYSTATE == with_syntax) {
422 asn1p_lval.tv_str = strdup(yytext);
423 return TOK_Literal;
424 } else {
425 return '}';
426 }
vlmfa67ddc2004-06-03 03:38:44 +0000427 }
428
429}
430
vlm2c8c44d2005-03-24 16:22:35 +0000431
432{WSP}+ /* Ignore whitespace */
433
434
435[{][\t\r\v\f\n ]*[0-7][,][\t\r\v\f\n ]*[0-9]+[\t\r\v\f\n ]*[}] {
436 asn1c_integer_t v1 = -1, v2 = -1;
437 char *p;
438 for(p = yytext; *p; p++)
439 if(*p >= '0' && *p <= '9')
440 { v1 = asn1p_atoi(p); break; }
441 while(*p >= '0' && *p <= '9') p++; /* Skip digits */
442 for(; *p; p++) if(*p >= '0' && *p <= '9')
443 { v2 = asn1p_atoi(p); break; }
444 if(v1 < 0 || v1 > 7) {
445 fprintf(stderr, "%s at line %d: X.680:2003, #37.14 "
446 "mandates 0..7 range for Tuple's TableColumn\n",
447 yytext, yylineno);
448 return -1;
449 }
450 if(v2 < 0 || v2 > 15) {
451 fprintf(stderr, "%s at line %d: X.680:2003, #37.14 "
452 "mandates 0..15 range for Tuple's TableRow\n",
453 yytext, yylineno);
454 return -1;
455 }
456 asn1p_lval.a_int = (v1 << 4) + v2;
457 return TOK_tuple;
458 }
459
460[{][\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 ]*[}] {
461 asn1c_integer_t v1 = -1, v2 = -1, v3 = -1, v4 = -1;
462 char *p;
463 for(p = yytext; *p; p++)
464 if(*p >= '0' && *p <= '9')
465 { v1 = asn1p_atoi(p); break; }
466 while(*p >= '0' && *p <= '9') p++; /* Skip digits */
467 for(; *p; p++) if(*p >= '0' && *p <= '9')
468 { v2 = asn1p_atoi(p); break; }
469 while(*p >= '0' && *p <= '9') p++;
470 for(; *p; p++) if(*p >= '0' && *p <= '9')
471 { v3 = asn1p_atoi(p); break; }
472 while(*p >= '0' && *p <= '9') p++;
473 for(; *p; p++) if(*p >= '0' && *p <= '9')
474 { v4 = asn1p_atoi(p); break; }
475 if(v1 < 0 || v1 > 127) {
476 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
477 "mandates 0..127 range for Quadruple's Group\n",
478 yytext, yylineno);
479 return -1;
480 }
481 if(v2 < 0 || v2 > 255) {
482 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
483 "mandates 0..255 range for Quadruple's Plane\n",
484 yytext, yylineno);
485 return -1;
486 }
487 if(v3 < 0 || v3 > 255) {
488 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
489 "mandates 0..255 range for Quadruple's Row\n",
490 yytext, yylineno);
491 return -1;
492 }
493 if(v4 < 0 || v4 > 255) {
494 fprintf(stderr, "%s at line %d: X.680:2003, #37.12 "
495 "mandates 0..255 range for Quadruple's Cell\n",
496 yytext, yylineno);
497 return -1;
498 }
499 asn1p_lval.a_int = (v1 << 24) | (v2 << 16) | (v3 << 8) | v4;
500 return TOK_quadruple;
501 }
502
503
504[(){},;:|!.&@\[\]^] return yytext[0];
505
506[^A-Za-z0-9:=,{}<.@()[]'\"|&^*;!-] {
507 if(TYPE_LIFETIME(1994, 0))
508 fprintf(stderr, "ERROR: ");
509 fprintf(stderr,
510 "Symbol '%c' at line %d is prohibited "
511 "by ASN.1:1994 and ASN.1:1997\n",
512 yytext[0], yylineno);
513 if(TYPE_LIFETIME(1994, 0))
514 return -1;
515 }
vlmfa67ddc2004-06-03 03:38:44 +0000516
517<*>. {
518 fprintf(stderr,
519 "Unexpected token at line %d: \"%s\"\n",
520 yylineno, yytext);
521 while(YYSTATE != INITIAL)
522 yy_pop_state();
vlmc94e28f2004-09-15 11:59:51 +0000523 if(0) {
524 yy_top_state(); /* Just to use this function. */
525 yy_fatal_error("Parse error");
526 }
vlmfa67ddc2004-06-03 03:38:44 +0000527 return -1;
528}
529
530<*><<EOF>> {
531 while(YYSTATE != INITIAL)
532 yy_pop_state();
533 yyterminate();
534 }
535
536
537%%
538
539/*
540 * Very dirty but wonderful hack allowing to rule states from within .y file.
541 */
vlm9283dbe2004-08-18 04:59:12 +0000542void asn1p_lexer_hack_push_opaque_state() { yy_push_state(opaque); }
vlmfa67ddc2004-06-03 03:38:44 +0000543
544/*
545 * Another hack which disables recognizing some tokens when inside WITH SYNTAX.
546 */
vlm9283dbe2004-08-18 04:59:12 +0000547void asn1p_lexer_hack_enable_with_syntax() { yy_push_state(with_syntax); }
548
549/* Yet another */
550void asn1p_lexer_hack_push_encoding_control() {
551 yy_push_state(encoding_control);
vlmfa67ddc2004-06-03 03:38:44 +0000552}
553
vlm2728a8d2005-01-23 09:51:44 +0000554static asn1c_integer_t
vlmfa67ddc2004-06-03 03:38:44 +0000555asn1p_atoi(char *ptr) {
vlm2728a8d2005-01-23 09:51:44 +0000556 asn1c_integer_t value;
vlmfa67ddc2004-06-03 03:38:44 +0000557 errno = 0; /* Clear the error code */
558
559 if(sizeof(value) <= sizeof(int)) {
560 value = strtol(ptr, 0, 10);
561 } else {
562#ifdef HAVE_STRTOIMAX
563 value = strtoimax(ptr, 0, 10);
564#elif HAVE_STRTOLL
565 value = strtoll(ptr, 0, 10);
566#else
567 value = strtol(ptr, 0, 10);
568#endif
569 }
570
571 if(errno == ERANGE) {
572 fprintf(stderr,
573 "Value \"%s\" at line %d is too large "
vlm86912f02005-04-05 08:46:22 +0000574 "for this compiler! Please contact the asn1c author.\n",
vlmfa67ddc2004-06-03 03:38:44 +0000575 ptr, yylineno);
576 errno = ERANGE; /* Restore potentially clobbered errno */
577 }
578
579 return value;
580}
581