Sync with 5.4.2
[deliverable/titan.core.git] / compiler2 / asn1 / TokenBuf.cc
CommitLineData
970ed795 1///////////////////////////////////////////////////////////////////////////////
3abe9331 2// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
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#include "TokenBuf.hh"
9#include "../AST.hh"
10#include "Block.hh"
11
12extern void asn1_yyerror(const char *s);
13#define yyerror asn1_yyerror
14extern int asn1_yylex();
15#define yylex asn1_yylex
16extern const char *asn1_infile;
17extern int asn1_yylineno;
18#define yylineno asn1_yylineno
19extern int asn1_plineno;
20#define plineno asn1_plineno
21extern YYLTYPE asn1_yylloc;
22#define yylloc asn1_yylloc
23
24namespace Asn {
25
26 using namespace Common;
27
28 // =================================
29 // ===== Token
30 // =================================
31
32 Token::Token(const Token& p)
33 : Node(p), Location(p), token(p.token)
34 {
35 switch (p.token) {
36 case TOK_UpperIdentifier:
37 case TOK_LowerIdentifier:
38 case TOK_ampUpperIdentifier:
39 case TOK_ampLowerIdentifier:
40 semval.id = p.semval.id->clone();
41 break;
42 case TOK_Number:
43 semval.i = new int_val_t(*p.semval.i);
44 break;
45 case TOK_CString:
46 semval.str = new string(*p.semval.str);
47 break;
48 case TOK_RealNumber:
49 case TOK_BString:
50 case TOK_HString:
51 semval.value = p.semval.value->clone();
52 break;
53 case TOK_Block:
54 semval.block = p.semval.block->clone();
55 default:
56 break;
57 }
58 }
59
60 bool Token::has_semval(int p_token)
61 {
62 switch (p_token) {
63 case TOK_UpperIdentifier:
64 case TOK_LowerIdentifier:
65 case TOK_ampUpperIdentifier:
66 case TOK_ampLowerIdentifier:
67 case TOK_Number:
68 case TOK_CString:
69 case TOK_RealNumber:
70 case TOK_BString:
71 case TOK_HString:
72 case TOK_Block:
73 return true;
74 default:
75 return false;
76 }
77 }
78
79 Token::Token(int p_token, const Location& p_loc)
80 : Node(), Location(p_loc), token(p_token)
81 {
82 if (has_semval(p_token)) FATAL_ERROR("Token::Token()");
83 }
84
85 Token::Token(int p_token, const YYSTYPE& p_semval, const Location& p_loc)
86 : Node(), Location(p_loc), token(p_token)
87 {
88 switch (p_token) {
89 case TOK_UpperIdentifier:
90 case TOK_LowerIdentifier:
91 case TOK_ampUpperIdentifier:
92 case TOK_ampLowerIdentifier:
93 semval.id = p_semval.id;
94 break;
95 case TOK_Number:
96 semval.i = p_semval.i;
97 break;
98 case TOK_CString:
99 semval.str = p_semval.str;
100 break;
101 case TOK_RealNumber:
102 case TOK_BString:
103 case TOK_HString:
104 semval.value = p_semval.value;
105 break;
106 case TOK_Block:
107 semval.block = p_semval.block;
108 default:
109 break;
110 }
111 }
112
113 Token::~Token()
114 {
115 switch(token) {
116 case TOK_UpperIdentifier:
117 case TOK_LowerIdentifier:
118 case TOK_ampUpperIdentifier:
119 case TOK_ampLowerIdentifier:
120 delete semval.id;
121 break;
122 case TOK_CString:
123 delete semval.str;
124 break;
125 case TOK_RealNumber:
126 case TOK_BString:
127 case TOK_HString:
128 delete semval.value;
129 break;
130 case TOK_Block:
131 delete semval.block;
132 break;
133 case TOK_Number:
134 delete semval.i;
135 break;
136 default:
137 break;
138 } // switch
139 }
140
141 Token *Token::clone() const
142 {
143 return new Token(*this);
144 }
145
146 void Token::set_token(int new_token)
147 {
148 if (new_token != token) {
149 if (has_semval(token) || has_semval(new_token))
150 FATAL_ERROR("Token::set_token()");
151 token = new_token;
152 }
153 }
154
155 void Token::steal_semval(YYSTYPE& p_semval)
156 {
157 switch (token) {
158 case TOK_UpperIdentifier:
159 case TOK_LowerIdentifier:
160 case TOK_ampUpperIdentifier:
161 case TOK_ampLowerIdentifier:
162 p_semval.id = semval.id;
163 break;
164 case TOK_Number:
165 p_semval.i = semval.i;
166 break;
167 case TOK_CString:
168 p_semval.str = semval.str;
169 break;
170 case TOK_RealNumber:
171 case TOK_BString:
172 case TOK_HString:
173 p_semval.value = semval.value;
174 break;
175 case TOK_Block:
176 p_semval.block = semval.block;
177 default:
178 break;
179 }
180 token = '\0';
181 }
182
183 void Token::set_loc_info() const
184 {
185 asn1_infile = get_filename();
186 if(get_lineno() > 0) plineno = get_lineno();
187 }
188
189 bool Token::is_literal_id() const
190 {
191 if(token==TOK_UpperIdentifier
192 && semval.id->isvalid_asn_word())
193 return true;
194 else return false;
195 }
196
197 bool Token::is_literal_kw() const
198 {
199 switch(token) {
200 case ',':
201 case KW_ABSENT:
202 case KW_ALL:
203 case KW_ANY:
204 case KW_APPLICATION:
205 case KW_AUTOMATIC:
206 case KW_BEGIN:
207 case KW_BY:
208 case KW_CLASS:
209 case KW_COMPONENT:
210 case KW_COMPONENTS:
211 case KW_CONSTRAINED:
212 case KW_CONTAINING:
213 case KW_DEFAULT:
214 case KW_DEFINED:
215 case KW_DEFINITIONS:
216 case KW_ENCODED:
217 case KW_EXCEPT:
218 case KW_EXPLICIT:
219 case KW_EXPORTS:
220 case KW_EXTENSIBILITY:
221 case KW_FROM:
222 case KW_IDENTIFIER:
223 case KW_IMPLICIT:
224 case KW_IMPLIED:
225 case KW_IMPORTS:
226 case KW_INCLUDES:
227 case KW_MAX:
228 case KW_MIN:
229 case KW_OF:
230 case KW_OPTIONAL:
231 case KW_PATTERN:
232 case KW_PDV:
233 case KW_PRESENT:
234 case KW_PRIVATE:
235 case KW_SIZE:
236 case KW_STRING:
237 case KW_SYNTAX:
238 case KW_TAGS:
239 case KW_UNIQUE:
240 case KW_UNIVERSAL:
241 case KW_WITH:
242 return true;
243 default:
244 return false;
245 } // switch token
246 }
247
248 bool Token::is_ampId() const
249 {
250 if(token==TOK_ampUpperIdentifier
251 || token==TOK_ampLowerIdentifier)
252 return true;
253 else return false;
254 }
255
256 bool Token::is_id() const
257 {
258 switch(token) {
259 case TOK_UpperIdentifier:
260 case TOK_LowerIdentifier:
261 case TOK_ampUpperIdentifier:
262 case TOK_ampLowerIdentifier:
263 return true;
264 default:
265 return false;
266 } // switch
267 }
268
269 const char* Token::get_token_name(int p_token)
270 {
271 switch(p_token) {
272 case '\0': return "<end of file or statement>";
273 case TOK_Assignment: return "::=";
274 case TOK_RangeSeparator: return "..";
275 case TOK_Ellipsis: return "...";
276 case TOK_LeftVersionBrackets: return "[[";
277 case TOK_RightVersionBrackets: return "]]";
278 case '{': return "{";
279 case '}': return "}";
280 case '(': return "(";
281 case ')': return ")";
282 case '[': return "[";
283 case ']': return "]";
284 case ',': return ",";
285 case '.': return ".";
286 case '-': return "-";
287 case ':': return ":";
288 case ';': return ";";
289 case '@': return "@";
290 case '|': return "|";
291 case '!': return "!";
292 case '^': return "^";
293 case '<': return "<";
294 case '>': return ">";
295 case '\'': return "'";
296 case '"': return "\"";
297 case KW_ABSENT: return "ABSENT";
298 case KW_ALL: return "ALL";
299 case KW_ANY: return "ANY";
300 case KW_APPLICATION: return "APPLICATION";
301 case KW_AUTOMATIC: return "AUTOMATIC";
302 case KW_BEGIN: return "BEGIN";
303 case KW_BIT: return "BIT";
304 case KW_BMPString: return "BMPString";
305 case KW_BOOLEAN: return "BOOLEAN";
306 case KW_BY: return "BY";
307 case KW_CHARACTER: return "CHARACTER";
308 case KW_CHOICE: return "CHOICE";
309 case KW_CLASS: return "CLASS";
310 case KW_COMPONENT: return "COMPONENT";
311 case KW_COMPONENTS: return "COMPONENTS";
312 case KW_CONSTRAINED: return "CONSTRAINED";
313 case KW_CONTAINING: return "CONTAINING";
314 case KW_DEFAULT: return "DEFAULT";
315 case KW_DEFINED: return "DEFINED";
316 case KW_DEFINITIONS: return "DEFINITIONS";
317 case KW_EMBEDDED: return "EMBEDDED";
318 case KW_ENCODED: return "ENCODED";
319 case KW_END: return "END";
320 case KW_ENUMERATED: return "ENUMERATED";
321 case KW_EXCEPT: return "EXCEPT";
322 case KW_EXPLICIT: return "EXPLICIT";
323 case KW_EXPORTS: return "EXPORTS";
324 case KW_EXTENSIBILITY: return "EXTENSIBILITY";
325 case KW_EXTERNAL: return "EXTERNAL";
326 case KW_FALSE: return "FALSE";
327 case KW_GeneralizedTime: return "GeneralizedTime";
328 case KW_GeneralString: return "GeneralString";
329 case KW_GraphicString: return "GraphicString";
330 case KW_IA5String: return "IA5String";
331 case KW_FROM: return "FROM";
332 case KW_IDENTIFIER: return "IDENTIFIER";
333 case KW_IMPLICIT: return "IMPLICIT";
334 case KW_IMPLIED: return "IMPLIED";
335 case KW_IMPORTS: return "IMPORTS";
336 case KW_INCLUDES: return "INCLUDES";
337 case KW_INSTANCE: return "INSTANCE";
338 case KW_INTEGER: return "INTEGER";
339 case KW_INTERSECTION: return "INTERSECTION";
340 case KW_ISO646String: return "ISO646String";
341 case KW_MAX: return "MAX";
342 case KW_MIN: return "MIN";
343 case KW_MINUS_INFINITY: return "MINUS-INFINITY";
344 case KW_NULL: return "NULL";
345 case KW_NumericString: return "NumericString";
346 case KW_OBJECT: return "OBJECT";
347 case KW_ObjectDescriptor: return "ObjectDescriptor";
348 case KW_OCTET: return "OCTET";
349 case KW_OF: return "OF";
350 case KW_OPTIONAL: return "OPTIONAL";
351 case KW_PATTERN: return "PATTERN";
352 case KW_PDV: return "PDV";
353 case KW_PLUS_INFINITY: return "PLUS-INFINITY";
354 case KW_PRESENT: return "PRESENT";
355 case KW_PrintableString: return "PrintableString";
356 case KW_PRIVATE: return "PRIVATE";
357 case KW_REAL: return "REAL";
358 case KW_RELATIVE_OID: return "RELATIVE-OID";
359 case KW_SEQUENCE: return "SEQUENCE";
360 case KW_SET: return "SET";
361 case KW_SIZE: return "SIZE";
362 case KW_STRING: return "STRING";
363 case KW_SYNTAX: return "SYNTAX";
364 case KW_T61String: return "T61String";
365 case KW_TAGS: return "TAGS";
366 case KW_TeletexString: return "TeletexString";
367 case KW_TRUE: return "TRUE";
368 case KW_UNION: return "UNION";
369 case KW_UNIQUE: return "UNIQUE";
370 case KW_UNIVERSAL: return "UNIVERSAL";
371 case KW_UniversalString: return "UniversalString";
372 case KW_UTCTime: return "UTCTime";
373 case KW_UTF8String: return "UTF8String";
374 case KW_VideotexString: return "VideotexString";
375 case KW_VisibleString: return "VisibleString";
376 case KW_WITH: return "WITH";
377 case TOK_UpperIdentifier: return "<upperidentifier>";
378 case TOK_LowerIdentifier: return "<loweridentifier>";
379 case TOK_ampUpperIdentifier: return "<&upperidentifier>";
380 case TOK_ampLowerIdentifier: return "<&loweridentifier>";
381 case TOK_Number: return "<number>";
382 case TOK_RealNumber: return "<realnumber>";
383 case TOK_BString: return "<bstring>";
384 case TOK_CString: return "<cstring>";
385 case TOK_HString: return "<hstring>";
386 case TOK_Block: return "<{block}>";
387 /* special stuff */
388 case KW_Block_NamedNumberList: return "<NamedNumberList:>";
389 case KW_Block_Enumerations: return "<Enumerations:>";
390 case KW_Block_Assignment: return "<Assignment:>";
391 case KW_Block_NamedBitList: return "<NamedBitList:>";
392 case KW_Block_IdentifierList: return "<IdentifierList:>";
393 case KW_Block_FieldSpecList: return "<FieldSpecList:>";
394 case KW_Block_ComponentTypeLists: return "<ComponentTypeLists:>";
395 case KW_Block_AlternativeTypeLists: return "<AlternativeTypeLists:>";
396 case KW_Block_Type: return "<Type:>";
397 case KW_Block_Value: return "<Value:>";
398 case KW_Block_ValueSet: return "<ValueSet:>";
399 case KW_Block_Object: return "<Object:>";
400 case KW_Block_ObjectSet: return "<ObjectSet:>";
401 case KW_Block_SeqOfValue: return "<SeqOfValue:>";
402 case KW_Block_SetOfValue: return "<SetOfValue:>";
403 case KW_Block_SequenceValue: return "<SequenceValue:>";
404 case KW_Block_SetValue: return "<SetValue:>";
405 case KW_Block_ObjectSetSpec: return "<ObjectSetSpec:>";
406 case KW_Block_DefinedObjectSetBlock: return "<DefinedObjectSetBlock:>";
407 case KW_Block_AtNotationList: return "<AtNotationList:>";
408 case KW_Block_OIDValue: return "<OIDValue:>";
409 case KW_Block_ROIDValue: return "<ROIDValue:>";
410 case KW_Block_CharStringValue: return "<CharStringValue:>";
411 case KW_Block_QuadrupleOrTuple: return "<QuadrupleOrTuple:>";
412 default:
413 return "<Error! Not a keyword.>";
414 } // switch token
415 }
416
417 const Identifier& Token::get_semval_id() const
418 {
419 switch(token) {
420 case TOK_UpperIdentifier:
421 case TOK_LowerIdentifier:
422 case TOK_ampUpperIdentifier:
423 case TOK_ampLowerIdentifier:
424 return *semval.id;
425 default:
426 FATAL_ERROR("Token::get_semval_id()");
427 } // switch
428 }
429
430 void Token::create_block(TokenBuf *tb)
431 {
432 if (token != '{' || !tb) FATAL_ERROR("Token::create_block()");
433 token = TOK_Block;
434 /** \todo set the correct end line/column info */
435 semval.block = new Block(tb);
436 semval.block->set_location(*this);
437 }
438
439 void Token::dump(unsigned level) const
440 {
441 switch(token) {
442 case TOK_UpperIdentifier:
443 case TOK_LowerIdentifier:
444 case TOK_ampUpperIdentifier:
445 case TOK_ampLowerIdentifier:
446 semval.id->dump(level);
447 break;
448 case TOK_Number:
449 DEBUG(level, "token: number (%s)", semval.i->t_str().c_str());
450 break;
451 case TOK_CString:
452 DEBUG(level, "token: cstring (\"%s\")", semval.str->c_str());
453 break;
454 case TOK_RealNumber:
455 case TOK_BString:
456 case TOK_HString:
457 semval.value->dump(level);
458 break;
459 case TOK_Block:
460 semval.block->dump(level);
461 break;
462 default:
463 DEBUG(level, "%s", get_token_name());
464 }
465 }
466
467 // =================================
468 // ===== TokenBuf
469 // =================================
470
471 TokenBuf::TokenBuf()
472 : Node(), filename("<undef>")
473 {
474 tokens=new tokens_t();
475 }
476
477 TokenBuf::TokenBuf(tokens_t *p_tokens)
478 : Node(), tokens(p_tokens), filename("<undef>")
479 {
480 if(!p_tokens)
481 FATAL_ERROR("NULL parameter: Asn::TokenBuf::TokenBuf(tokens_t*)");
482 }
483
484 TokenBuf::TokenBuf(const TokenBuf& p)
485 : Node(), filename(p.filename)
486 {
487 tokens=new tokens_t();
488 for(size_t i=0; i<p.tokens->size(); i++)
489 tokens->add((*p.tokens)[i]->clone());
490 }
491
492 TokenBuf::~TokenBuf()
493 {
494 delete_tokens();
495 delete tokens;
496 }
497
498 void TokenBuf::delete_tokens()
499 {
500 for(size_t i=0; i<tokens->size(); i++)
501 delete (*tokens)[i];
502 tokens->clear();
503 }
504
505 void TokenBuf::reset(const char *p_filename)
506 {
507 delete_tokens();
508 filename=p_filename;
509 }
510
511 bool TokenBuf::read_next()
512 {
513 /* if there was an EOF, don't try to read another token */
514 if(!tokens->empty() && (*tokens)[tokens->size()-1]->get_token()=='\0')
515 return false;
516 int token=yylex();
517 tokens->add(new Token(token, yylval, Location(filename, yylineno)));
518 return true;
519 }
520
521 Token*& TokenBuf::get_at(size_t pos)
522 {
523 while(tokens->size()<=pos && read_next()) ;
524 if(pos<tokens->size()) {
525 return (*tokens)[pos];
526 }
527 else {
528 if(tokens->empty())
529 FATAL_ERROR("Asn::TokenBuf::get_at()");
530 return (*tokens)[tokens->size()-1];
531 }
532 }
533
534 void TokenBuf::push_front_token(Token *p_token)
535 {
536 if(!p_token)
537 FATAL_ERROR("Asn::TokenBuf::push_front_token()");
538 tokens->add_front(p_token);
539 }
540
541 void TokenBuf::push_front_kw_token(int kw)
542 {
543 if(tokens->empty())
544 FATAL_ERROR("Asn::TokenBuf::push_front_kw_token()");
545 tokens->add_front(new Token(kw, *(*tokens)[0]));
546 }
547
548 void TokenBuf::push_back_token(Token *p_token)
549 {
550 if(!p_token)
551 FATAL_ERROR("NULL parameter: Asn::TokenBuf::push_back_token()");
552 tokens->add(p_token);
553 }
554
555 void TokenBuf::push_back_kw_token(int kw)
556 {
557 if(tokens->empty())
558 FATAL_ERROR("Asn::TokenBuf::push_back_kw_token()");
559 tokens->add(new Token(kw, *(*tokens)[tokens->size() - 1]));
560 }
561
562 void TokenBuf::move_tokens_from(TokenBuf *tb)
563 {
564 if(!tb)
565 FATAL_ERROR("NULL parameter: Asn::TokenBuf::move_tokens_from()");
566 size_t insert_pos=tokens->size();
567 if(!tokens->empty() && (*tokens)[tokens->size()-1]->get_token()=='\0')
568 insert_pos--;
569 size_t num_of_toks=tb->tokens->size();
570 if(!tb->tokens->empty() &&
571 (*tb->tokens)[tb->tokens->size()-1]->get_token()=='\0')
572 num_of_toks--;
573 tokens_t *tmp_tokens=tb->tokens->subvector(0, num_of_toks);
574 tb->tokens->replace(0, num_of_toks);
575 tokens->replace(insert_pos, 0, tmp_tokens);
576 tmp_tokens->clear(); delete tmp_tokens;
577 }
578
579 Token* TokenBuf::pop_front_token()
580 {
581 Token *token=get_at(0);
582 if(token->get_token()=='{') {
583 token->set_loc_info(); /* report this line if unmatch_error */
584 /* search the matching '}' */
585 int blocklevel=1;
586 size_t i;
587 bool unmatch_error=false;
588 for(i=1; blocklevel>0 && !unmatch_error; i++) {
589 switch(get_at(i)->get_token()) {
590 case '{':
591 blocklevel++;
592 break;
593 case '}':
594 blocklevel--;
595 break;
596 case 0:
597 yyerror("Unmatched '{'");
598 unmatch_error=true;
599 i--; /* EOF is not part of the block */
600 break;
601 }
602 }
603 /* copy the tokens of the block to a new vector */
604 tokens_t *tokens_block=tokens->subvector(1, i-1);
605 if(!unmatch_error) /* replace '}' to EOF */
606 (*tokens_block)[tokens_block->size()-1]->set_token('\0');
607 else /* clone EOF and add to block */
608 tokens_block->add(get_at(i)->clone());
609 /* remove the tokens from their original vector */
610 tokens->replace(0, i);
611 /* create the new tokenbuf from the tokens of the block */
612 TokenBuf *tb=new TokenBuf(tokens_block);
613 tb->filename=filename;
614 /* transform the opening '{' to a block-token */
615 token->create_block(tb);
616 }
617 else {
618 /* remove the first token */
619 tokens->replace(0, 1);
620 }
621 return token;
622 }
623
624 int TokenBuf::lex()
625 {
626 Token *token=pop_front_token();
627 int tmp_tok = token->get_token();
628 token->set_loc_info();
629 token->steal_semval(yylval);
630 yylloc.first_line=yylloc.last_line=token->get_lineno();
631 yylloc.first_column=yylloc.last_column=0;
632 delete token;
633 return tmp_tok;
634 }
635
636 void TokenBuf::dump(unsigned level) const
637 {
638 DEBUG(level, "Tokens: (%lu pcs.)", (unsigned long) tokens->size());
639 level++;
640 for(size_t i=0; i<tokens->size(); i++)
641 (*tokens)[i]->dump(level);
642 }
643
644} // namespace Asn
This page took 0.046886 seconds and 5 git commands to generate.