Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / asn1 / asn1la.l
1 /******************************************************************************
2 * Copyright (c) 2000-2015 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 ******************************************************************************/
8 /*
9 * ASN1:1997 lexical analyzer
10 * Written by Matyas Forstner
11 * 20021115
12 */
13
14 %option stack
15 %option yylineno
16 %option noyywrap
17 %option nounput
18 %option never-interactive
19 %option prefix="asn1_yy"
20
21 %{ /* ****************** C declarations ***************** */
22
23 #include "../error.h"
24 #include "../string.hh"
25 #include "../Identifier.hh"
26 #include "../Setting.hh"
27 #include "../Value.hh"
28 #include "TokenBuf.hh"
29
30 using namespace Common;
31 using namespace Asn;
32
33 /**
34 * The name of the file which is under parsing.
35 */
36 const char *asn1_infile;
37 /**
38 * When this flag is set, then the special internal TITAN-tokens are
39 * handled.
40 */
41 bool asn1_yy_parse_internal=false;
42
43 void asn1_init();
44 void asn1_free();
45 void asn1la_newfile(const char *filename);
46 void asn1la_newtokenbuf(TokenBuf *tb);
47 int asn1_yylex_my();
48
49 static int commentlevel=0;
50 static int commentbeginlineno=0;
51 static TokenBuf *asn1_tokenbuf=0;
52 static TokenBuf *asn1_tokenbuf_curr=0;
53
54 static void id_replace_underscores(char *s);
55 static void bhstring_remove_whitespaces(char *s);
56 static void cstring_remove_newlines(char *s);
57
58 %} /* ***************** definitions ***************** */
59
60 /* start conditions */
61 %x SC_LINECOMMENT SC_COMMENT SC_COMMENT_END
62 %s SC_TITAN
63
64 /* 11.1.6 */
65 WHITESPACE [ \t\x0A\x0B\x0C\x0D]+
66 NEWLINE [\x0A\x0B\x0C\x0D]
67
68 /* 11.2 */
69 UPPERIDENTIFIER [A-Z]([\-_]?[A-Za-z0-9]+)*
70 /* 11.3 */
71 LOWERIDENTIFIER [a-z]([\-_]?[A-Za-z0-9]+)*
72
73 /* X.681, 7.1 */
74 ampUPPERIDENTIFIER \&{UPPERIDENTIFIER}
75 ampLOWERIDENTIFIER \&{LOWERIDENTIFIER}
76
77 /* 11.8 */
78 NUMBER ([1-9][0-9]*)|0
79 /* 11.9 */
80 REALNUMBER {NUMBER}(\.[0-9]+)?([eE][+\-]?{NUMBER})?
81 /* 11.10 */
82 BSTRING '([01]|{WHITESPACE})*'B
83 BSTRING_BAD '[^']*'B
84 /* 11.12 */
85 HSTRING '([0-9A-F]|{WHITESPACE})*'H
86 HSTRING_BAD '[^']*'H
87 HSTRING_BAD_OSTRING '([0-9A-F]|{WHITESPACE})*'O
88
89 /* 11.14 */
90 CSTRING \"([^"]|(\"\"))*\"
91 CSTRING_BAD '[^']*'
92
93 SEPARATOR ({WHITESPACE}|{COMMENT})
94
95 PERPERCOMMENT "//"[^\x0A\x0B\x0C\x0D]*{NEWLINE}
96
97 TITAN "$#&&&(#TITAN$#&&^#% "
98 TITAN_ID [A-Za-z0-9 \-_]+
99
100 %% /* ***************** rules ************************* */
101
102 {TITAN} {
103 if(asn1_yy_parse_internal)
104 yy_push_state(SC_TITAN);
105 else {
106 Location loc(asn1_infile, yylineno);
107 loc.error("Unexpected `%s'.", yytext);
108 }
109 }
110
111 <SC_TITAN> /* -------- SC_TITAN scope -------------- */
112 {
113
114 "Assignments" {
115 yy_pop_state();
116 return KW_TITAN_Assignments;
117 }
118
119 "UpperIdentifier\""{TITAN_ID}"\"" {
120 yy_pop_state();
121 yytext[strlen(yytext)-1]='\0';
122 yylval.id=new Identifier(Identifier::ID_ASN, string(yytext+16));
123 return TOK_UpperIdentifier;
124 }
125
126 } /* ------------------- End of SC_TITAN scope -------- */
127
128 {WHITESPACE}
129
130 "--" {
131 yy_push_state(SC_LINECOMMENT);
132 }
133
134 "/*" {
135 commentlevel=1;
136 commentbeginlineno=yylineno;
137 yy_push_state(SC_COMMENT);
138 }
139
140 {PERPERCOMMENT} {
141 Location loc(asn1_infile, yylineno-1);
142 loc.error("This style of comment is not permitted in ASN.1");
143 }
144
145
146 "::=" {return TOK_Assignment;}
147 ":=" {
148 Location loc(asn1_infile, yylineno);
149 loc.error("`:=' is not valid in ASN.1. Did you mean `::='?");
150 return TOK_Assignment;
151 }
152 "..." {return TOK_Ellipsis;}
153 ".." {return TOK_RangeSeparator;}
154 "[[" {return TOK_LeftVersionBrackets;}
155 "]]" {return TOK_RightVersionBrackets;}
156 "{" {return '{';}
157 "}" {return '}';}
158 "(" {return '(';}
159 ")" {return ')';}
160 "[" {return '[';}
161 "]" {return ']';}
162 "," {return ',';}
163 "." {return '.';}
164 "-" {return '-';}
165 ":" {return ':';}
166 ";" {return ';';}
167 "@" {return '@';}
168 "|" {return '|';}
169 "!" {return '!';}
170 "^" {return '^';}
171 "<" {return '<';}
172 ">" {return '>';}
173
174 "ABSENT" {return KW_ABSENT;}
175 /*
176 "ABSTRACT-SYNTAX" {return KW_ABSTRACT_SYNTAX;}
177 */
178 "ALL" {return KW_ALL;}
179 "ANY" {return KW_ANY;}
180 "APPLICATION" {return KW_APPLICATION;}
181 "AUTOMATIC" {return KW_AUTOMATIC;}
182 "BEGIN" {return KW_BEGIN;}
183 "BIT" {return KW_BIT;}
184 "BMPString" {return KW_BMPString;}
185 "BOOLEAN" {return KW_BOOLEAN;}
186 "BY" {return KW_BY;}
187 "CHARACTER" {return KW_CHARACTER;}
188 "CHOICE" {return KW_CHOICE;}
189 "CLASS" {return KW_CLASS;}
190 "COMPONENT" {return KW_COMPONENT;}
191 "COMPONENTS" {return KW_COMPONENTS;}
192 "CONSTRAINED" {return KW_CONSTRAINED;}
193 "CONTAINING" {return KW_CONTAINING;}
194 "DEFAULT" {return KW_DEFAULT;}
195 "DEFINED" {return KW_DEFINED;}
196 "DEFINITIONS" {return KW_DEFINITIONS;}
197 "EMBEDDED" {return KW_EMBEDDED;}
198 "ENCODED" {return KW_ENCODED;}
199 "END" {return KW_END;}
200 "ENUMERATED" {return KW_ENUMERATED;}
201 "EXCEPT" {return KW_EXCEPT;}
202 "EXPLICIT" {return KW_EXPLICIT;}
203 "EXPORTS" {return KW_EXPORTS;}
204 "EXTENSIBILITY" {return KW_EXTENSIBILITY;}
205 "EXTERNAL" {return KW_EXTERNAL;}
206 "FALSE" {return KW_FALSE;}
207 "FROM" {return KW_FROM;}
208 "GeneralizedTime" {return KW_GeneralizedTime;}
209 "GeneralString" {return KW_GeneralString;}
210 "GraphicString" {return KW_GraphicString;}
211 "IA5String" {return KW_IA5String;}
212 "IDENTIFIER" {return KW_IDENTIFIER;}
213 "IMPLICIT" {return KW_IMPLICIT;}
214 "IMPLIED" {return KW_IMPLIED;}
215 "IMPORTS" {return KW_IMPORTS;}
216 "INCLUDES" {return KW_INCLUDES;}
217 "INSTANCE" {return KW_INSTANCE;}
218 "INTEGER" {return KW_INTEGER;}
219 "INTERSECTION" {return KW_INTERSECTION;}
220 "ISO646String" {return KW_ISO646String;}
221 "MAX" {return KW_MAX;}
222 "MIN" {return KW_MIN;}
223 "MINUS-INFINITY" {return KW_MINUS_INFINITY;}
224 "NOT-A-NUMBER" {return KW_NOT_A_NUMBER;}
225 "NULL" {return KW_NULL;}
226 "NumericString" {return KW_NumericString;}
227 "OBJECT" {return KW_OBJECT;}
228 "ObjectDescriptor" {return KW_ObjectDescriptor;}
229 "OCTET" {return KW_OCTET;}
230 "OF" {return KW_OF;}
231 "OPTIONAL" {return KW_OPTIONAL;}
232 "PATTERN" {return KW_PATTERN;}
233 "PDV" {return KW_PDV;}
234 "PLUS-INFINITY" {return KW_PLUS_INFINITY;}
235 "PRESENT" {return KW_PRESENT;}
236 "PrintableString" {return KW_PrintableString;}
237 "PRIVATE" {return KW_PRIVATE;}
238 "REAL" {return KW_REAL;}
239 "RELATIVE-OID" {return KW_RELATIVE_OID;}
240 "SEQUENCE" {return KW_SEQUENCE;}
241 "SET" {return KW_SET;}
242 "SIZE" {return KW_SIZE;}
243 "STRING" {return KW_STRING;}
244 "SYNTAX" {return KW_SYNTAX;}
245 "T61String" {return KW_T61String;}
246 "TAGS" {return KW_TAGS;}
247 "TeletexString" {return KW_TeletexString;}
248 "TRUE" {return KW_TRUE;}
249 /*
250 "TYPE-IDENTIFIER" {return KW_TYPE_IDENTIFIER;}
251 */
252 "UNION" {return KW_UNION;}
253 "UNIQUE" {return KW_UNIQUE;}
254 "UNIVERSAL" {return KW_UNIVERSAL;}
255 "UniversalString" {return KW_UniversalString;}
256 "UTCTime" {return KW_UTCTime;}
257 "UTF8String" {return KW_UTF8String;}
258 "VideotexString" {return KW_VideotexString;}
259 "VisibleString" {return KW_VisibleString;}
260 "WITH" {return KW_WITH;}
261
262 {LOWERIDENTIFIER} {
263 id_replace_underscores(yytext);
264 yylval.id=new Identifier(Identifier::ID_ASN, string(yytext));
265 return TOK_LowerIdentifier;
266 }
267
268 {UPPERIDENTIFIER} {
269 id_replace_underscores(yytext);
270 yylval.id=new Identifier(Identifier::ID_ASN, string(yytext));
271 return TOK_UpperIdentifier;
272 }
273
274 {ampUPPERIDENTIFIER} {
275 id_replace_underscores(yytext);
276 yylval.id=new Identifier(Identifier::ID_ASN, string(yytext));
277 return TOK_ampUpperIdentifier;
278 }
279
280 {ampLOWERIDENTIFIER} {
281 id_replace_underscores(yytext);
282 yylval.id=new Identifier(Identifier::ID_ASN, string(yytext));
283 return TOK_ampLowerIdentifier;
284 }
285
286 {NUMBER} {
287 Location loc(asn1_infile, yylineno);
288 yylval.i = new int_val_t(yytext, loc);
289 return TOK_Number;
290 }
291
292 {REALNUMBER} {
293 Location loc(asn1_infile, yylineno);
294 yylval.value = new Value(Value::V_REAL, string2Real(yytext, loc));
295 return TOK_RealNumber;
296 }
297
298 {BSTRING} {
299 bhstring_remove_whitespaces(yytext);
300 yytext[strlen(yytext)-2]='\0';
301 yylval.value=new Value(Value::V_BSTR, new string(yytext+1));
302 return TOK_BString;
303 }
304
305 {BSTRING_BAD} {
306 Location loc(asn1_infile, yylineno);
307 loc.error("Invalid bstring: %s.", yytext);
308 yylval.value=new Value(Value::V_BSTR, new string());
309 return TOK_HString;
310 }
311
312 {HSTRING} {
313 bhstring_remove_whitespaces(yytext);
314 yytext[strlen(yytext)-2]='\0';
315 yylval.value=new Value(Value::V_HSTR, new string(yytext+1));
316 return TOK_HString;
317 }
318
319 {HSTRING_BAD} {
320 Location loc(asn1_infile, yylineno);
321 loc.error("Invalid hstring: %s.", yytext);
322 yylval.value=new Value(Value::V_HSTR, new string());
323 return TOK_HString;
324 }
325
326 {HSTRING_BAD_OSTRING} {
327 string ostr(yytext);
328 ostr[ostr.size()-1]='H';
329 Location loc(asn1_infile, yylineno);
330 loc.error("Invalid suffix `O' in %s. Did you mean the hstring %s?",
331 yytext, ostr.c_str());
332 bhstring_remove_whitespaces(yytext);
333 yytext[strlen(yytext)-2]='\0';
334 yylval.value=new Value(Value::V_HSTR, new string(yytext+1));
335 return TOK_HString;
336 }
337
338 {CSTRING} {
339 yytext[strlen(yytext)-1]='\0';
340 cstring_remove_newlines(yytext+1);
341 yylval.str=new string(yytext+1);
342 return TOK_CString;
343 }
344
345 {CSTRING_BAD} {
346 Location loc(asn1_infile, yylineno);
347 loc.error("Invalid cstring: %s. Perhaps you wanted to use quotation"
348 " marks (\") instead of apostrophes (')?", yytext);
349 yytext[strlen(yytext)-1]='\0';
350 yylval.str=new string(yytext+1);
351 return TOK_CString;
352 }
353
354 "'" {return '\'';}
355 "\"" {return '"';}
356
357 "*/" {
358 Location loc(asn1_infile, yylineno);
359 loc.error("Unmatched `*/'");
360 }
361
362 . {
363 Location loc(asn1_infile, yylineno);
364 loc.error("`%c' (0x%02X) character is not used in ASN.1",
365 (unsigned char)yytext[0]>31?(unsigned char)yytext[0]:'?',
366 (unsigned char)yytext[0]);
367 }
368
369 <INITIAL><<EOF>> {
370 return 0;
371 }
372
373 <SC_LINECOMMENT> /* -------- SC_LINECOMMENT scope -------------- */
374 {
375
376 "--"|{NEWLINE} {
377 yy_pop_state();
378 }
379
380 <<EOF>> {
381 yy_pop_state();
382 return 0;
383 }
384
385 .
386
387 } /* ------------------- End of SC_LINECOMMENT scope --------*/
388
389 <SC_COMMENT,SC_COMMENT_END><<EOF>> {
390 Location loc(asn1_infile, commentbeginlineno);
391 loc.error("Unmatched `/*'");
392 while(yy_top_state()!=INITIAL) yy_pop_state();
393 yy_pop_state();
394 return 0;
395 }
396
397 <SC_COMMENT> /* -------- SC_COMMENT scope -------------- */
398 {
399
400 "/*" {
401 commentlevel++;
402 }
403
404 "*" {yy_push_state(SC_COMMENT_END);}
405
406 [^*]
407
408 } /* ------------------- End of SC_COMMENT scope --------*/
409
410 <SC_COMMENT_END> /* ----- SC_COMMENT_END scope -------------- */
411 {
412
413 "*"
414
415 "/" {
416 yy_pop_state();
417 commentlevel--;
418 if(!commentlevel) yy_pop_state();
419 }
420
421 [^*/] {yy_pop_state();}
422
423 } /* ------------------- End of SC_COMMENT_END scope --------*/
424
425 %%
426
427 void asn1_init()
428 {
429 asn1_infile=0;
430 asn1_tokenbuf=new TokenBuf();
431 Asn::Assignments::create_spec_asss();
432 }
433
434 void asn1_free()
435 {
436 Asn::Assignments::destroy_spec_asss();
437 delete asn1_tokenbuf;
438 }
439
440 void asn1la_newfile(const char *filename)
441 {
442 asn1_tokenbuf->reset(filename);
443 asn1la_newtokenbuf(asn1_tokenbuf);
444 }
445
446 void asn1la_newtokenbuf(TokenBuf *tb)
447 {
448 if(!tb)
449 FATAL_ERROR("asn1la_newtokenbuf(): tb is NULL");
450 asn1_tokenbuf_curr=tb;
451 asn1_infile=asn1_tokenbuf_curr->get_filename();
452 yylineno=1;
453 }
454
455 void id_replace_underscores(char *s)
456 {
457 char *origid=0;
458 char *p=s;
459 while(*p!='\0') {
460 if(*p=='_') {
461 if(!origid) origid=mputstr(origid, s);
462 *p='-';
463 }
464 p++;
465 }
466 if(origid) {
467 Location loc(asn1_infile, yylineno);
468 loc.error("`%s' is not a valid ASN.1 identifier. Did you mean `%s'?",
469 origid, s);
470 Free(origid);
471 }
472 }
473
474 void bhstring_remove_whitespaces(char *s) {
475 char *p1, *p2;
476 for(p1=p2=s; *p2; p2++) {
477 switch(*p2) {
478 case ' ': // whitespace, no newline chars
479 case '\t':
480 case 0x0A: // newline chars
481 case 0x0B:
482 case 0x0C:
483 case 0x0D:
484 break;
485 default:
486 *p1++=*p2;
487 } // switch *p2
488 } // for
489 *p1='\0';
490 }
491
492 void cstring_remove_newlines(char *s) {
493 /* also "" -> " */
494 char *p_r, *p_w, *p_b;
495 enum {NO_WS, /**< no whitespace */
496 WS, /**< whitespace, but not newline */
497 NL /**< newline */
498 } state=NO_WS;
499 /*
500 p_r reads the string s;
501 p_w writes into the string s;
502 p_b is a bookmark for writing; shows the last non-whitespace character+1,
503 if the state is WS;
504 if state is NL, then the next whitespaces must be eaten up;
505 */
506 for(p_w=p_b=p_r=s; *p_r; p_w++, p_r++) {
507 switch(*p_r) {
508 case ' ': // whitespace, no newline chars
509 case '\t':
510 if(state==NO_WS) {p_b=p_w; state=WS;}
511 break;
512 case 0x0A: // newline chars (LF,VT,FF,CR)
513 case 0x0B:
514 case 0x0C:
515 case 0x0D:
516 switch(state) {
517 case NO_WS:
518 p_b=p_w;
519 /* no break */
520 case WS:
521 case NL:
522 state=NL;
523 } // switch state
524 break;
525 default: // not whitespace chars
526 if(state==NL) p_w=p_b;
527 state=NO_WS;
528 } // switch *p_r
529 *p_w = *p_r;
530 if (*p_r=='"' && *(p_r+1)=='"') { // On the first of two QUOTATION MARKs.
531 p_w--; // Back up writing pos. The next " will overwrite this one.
532 }
533 } // for
534 *p_w='\0';
535 }
536
537 int asn1_yylex_my()
538 {
539 return asn1_tokenbuf_curr->lex();
540 }
This page took 0.042523 seconds and 5 git commands to generate.