1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
16 * Szabo, Janos Zoltan – initial implementation
18 ******************************************************************************/
19 #include "TokenBuf.hh"
23 extern void asn1_yyerror(const char *s
);
24 #define yyerror asn1_yyerror
25 extern int asn1_yylex();
26 #define yylex asn1_yylex
27 extern const char *asn1_infile
;
28 extern int asn1_yylineno
;
29 #define yylineno asn1_yylineno
30 extern int asn1_plineno
;
31 #define plineno asn1_plineno
32 extern YYLTYPE asn1_yylloc
;
33 #define yylloc asn1_yylloc
37 using namespace Common
;
39 // =================================
41 // =================================
43 Token::Token(const Token
& p
)
44 : Node(p
), Location(p
), token(p
.token
)
47 case TOK_UpperIdentifier
:
48 case TOK_LowerIdentifier
:
49 case TOK_ampUpperIdentifier
:
50 case TOK_ampLowerIdentifier
:
51 semval
.id
= p
.semval
.id
->clone();
54 semval
.i
= new int_val_t(*p
.semval
.i
);
57 semval
.str
= new string(*p
.semval
.str
);
62 semval
.value
= p
.semval
.value
->clone();
65 semval
.block
= p
.semval
.block
->clone();
71 bool Token::has_semval(int p_token
)
74 case TOK_UpperIdentifier
:
75 case TOK_LowerIdentifier
:
76 case TOK_ampUpperIdentifier
:
77 case TOK_ampLowerIdentifier
:
90 Token::Token(int p_token
, const Location
& p_loc
)
91 : Node(), Location(p_loc
), token(p_token
)
93 if (has_semval(p_token
)) FATAL_ERROR("Token::Token()");
96 Token::Token(int p_token
, const YYSTYPE
& p_semval
, const Location
& p_loc
)
97 : Node(), Location(p_loc
), token(p_token
)
100 case TOK_UpperIdentifier
:
101 case TOK_LowerIdentifier
:
102 case TOK_ampUpperIdentifier
:
103 case TOK_ampLowerIdentifier
:
104 semval
.id
= p_semval
.id
;
107 semval
.i
= p_semval
.i
;
110 semval
.str
= p_semval
.str
;
115 semval
.value
= p_semval
.value
;
118 semval
.block
= p_semval
.block
;
127 case TOK_UpperIdentifier
:
128 case TOK_LowerIdentifier
:
129 case TOK_ampUpperIdentifier
:
130 case TOK_ampLowerIdentifier
:
152 Token
*Token::clone() const
154 return new Token(*this);
157 void Token::set_token(int new_token
)
159 if (new_token
!= token
) {
160 if (has_semval(token
) || has_semval(new_token
))
161 FATAL_ERROR("Token::set_token()");
166 void Token::steal_semval(YYSTYPE
& p_semval
)
169 case TOK_UpperIdentifier
:
170 case TOK_LowerIdentifier
:
171 case TOK_ampUpperIdentifier
:
172 case TOK_ampLowerIdentifier
:
173 p_semval
.id
= semval
.id
;
176 p_semval
.i
= semval
.i
;
179 p_semval
.str
= semval
.str
;
184 p_semval
.value
= semval
.value
;
187 p_semval
.block
= semval
.block
;
194 void Token::set_loc_info() const
196 asn1_infile
= get_filename();
197 if(get_lineno() > 0) plineno
= get_lineno();
200 bool Token::is_literal_id() const
202 if(token
==TOK_UpperIdentifier
203 && semval
.id
->isvalid_asn_word())
208 bool Token::is_literal_kw() const
231 case KW_EXTENSIBILITY
:
259 bool Token::is_ampId() const
261 if(token
==TOK_ampUpperIdentifier
262 || token
==TOK_ampLowerIdentifier
)
267 bool Token::is_id() const
270 case TOK_UpperIdentifier
:
271 case TOK_LowerIdentifier
:
272 case TOK_ampUpperIdentifier
:
273 case TOK_ampLowerIdentifier
:
280 const char* Token::get_token_name(int p_token
)
283 case '\0': return "<end of file or statement>";
284 case TOK_Assignment
: return "::=";
285 case TOK_RangeSeparator
: return "..";
286 case TOK_Ellipsis
: return "...";
287 case TOK_LeftVersionBrackets
: return "[[";
288 case TOK_RightVersionBrackets
: 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 '-': return "-";
298 case ':': return ":";
299 case ';': return ";";
300 case '@': return "@";
301 case '|': return "|";
302 case '!': return "!";
303 case '^': return "^";
304 case '<': return "<";
305 case '>': return ">";
306 case '\'': return "'";
307 case '"': return "\"";
308 case KW_ABSENT
: return "ABSENT";
309 case KW_ALL
: return "ALL";
310 case KW_ANY
: return "ANY";
311 case KW_APPLICATION
: return "APPLICATION";
312 case KW_AUTOMATIC
: return "AUTOMATIC";
313 case KW_BEGIN
: return "BEGIN";
314 case KW_BIT
: return "BIT";
315 case KW_BMPString
: return "BMPString";
316 case KW_BOOLEAN
: return "BOOLEAN";
317 case KW_BY
: return "BY";
318 case KW_CHARACTER
: return "CHARACTER";
319 case KW_CHOICE
: return "CHOICE";
320 case KW_CLASS
: return "CLASS";
321 case KW_COMPONENT
: return "COMPONENT";
322 case KW_COMPONENTS
: return "COMPONENTS";
323 case KW_CONSTRAINED
: return "CONSTRAINED";
324 case KW_CONTAINING
: return "CONTAINING";
325 case KW_DEFAULT
: return "DEFAULT";
326 case KW_DEFINED
: return "DEFINED";
327 case KW_DEFINITIONS
: return "DEFINITIONS";
328 case KW_EMBEDDED
: return "EMBEDDED";
329 case KW_ENCODED
: return "ENCODED";
330 case KW_END
: return "END";
331 case KW_ENUMERATED
: return "ENUMERATED";
332 case KW_EXCEPT
: return "EXCEPT";
333 case KW_EXPLICIT
: return "EXPLICIT";
334 case KW_EXPORTS
: return "EXPORTS";
335 case KW_EXTENSIBILITY
: return "EXTENSIBILITY";
336 case KW_EXTERNAL
: return "EXTERNAL";
337 case KW_FALSE
: return "FALSE";
338 case KW_GeneralizedTime
: return "GeneralizedTime";
339 case KW_GeneralString
: return "GeneralString";
340 case KW_GraphicString
: return "GraphicString";
341 case KW_IA5String
: return "IA5String";
342 case KW_FROM
: return "FROM";
343 case KW_IDENTIFIER
: return "IDENTIFIER";
344 case KW_IMPLICIT
: return "IMPLICIT";
345 case KW_IMPLIED
: return "IMPLIED";
346 case KW_IMPORTS
: return "IMPORTS";
347 case KW_INCLUDES
: return "INCLUDES";
348 case KW_INSTANCE
: return "INSTANCE";
349 case KW_INTEGER
: return "INTEGER";
350 case KW_INTERSECTION
: return "INTERSECTION";
351 case KW_ISO646String
: return "ISO646String";
352 case KW_MAX
: return "MAX";
353 case KW_MIN
: return "MIN";
354 case KW_MINUS_INFINITY
: return "MINUS-INFINITY";
355 case KW_NULL
: return "NULL";
356 case KW_NumericString
: return "NumericString";
357 case KW_OBJECT
: return "OBJECT";
358 case KW_ObjectDescriptor
: return "ObjectDescriptor";
359 case KW_OCTET
: return "OCTET";
360 case KW_OF
: return "OF";
361 case KW_OPTIONAL
: return "OPTIONAL";
362 case KW_PATTERN
: return "PATTERN";
363 case KW_PDV
: return "PDV";
364 case KW_PLUS_INFINITY
: return "PLUS-INFINITY";
365 case KW_PRESENT
: return "PRESENT";
366 case KW_PrintableString
: return "PrintableString";
367 case KW_PRIVATE
: return "PRIVATE";
368 case KW_REAL
: return "REAL";
369 case KW_RELATIVE_OID
: return "RELATIVE-OID";
370 case KW_SEQUENCE
: return "SEQUENCE";
371 case KW_SET
: return "SET";
372 case KW_SIZE
: return "SIZE";
373 case KW_STRING
: return "STRING";
374 case KW_SYNTAX
: return "SYNTAX";
375 case KW_T61String
: return "T61String";
376 case KW_TAGS
: return "TAGS";
377 case KW_TeletexString
: return "TeletexString";
378 case KW_TRUE
: return "TRUE";
379 case KW_UNION
: return "UNION";
380 case KW_UNIQUE
: return "UNIQUE";
381 case KW_UNIVERSAL
: return "UNIVERSAL";
382 case KW_UniversalString
: return "UniversalString";
383 case KW_UTCTime
: return "UTCTime";
384 case KW_UTF8String
: return "UTF8String";
385 case KW_VideotexString
: return "VideotexString";
386 case KW_VisibleString
: return "VisibleString";
387 case KW_WITH
: return "WITH";
388 case TOK_UpperIdentifier
: return "<upperidentifier>";
389 case TOK_LowerIdentifier
: return "<loweridentifier>";
390 case TOK_ampUpperIdentifier
: return "<&upperidentifier>";
391 case TOK_ampLowerIdentifier
: return "<&loweridentifier>";
392 case TOK_Number
: return "<number>";
393 case TOK_RealNumber
: return "<realnumber>";
394 case TOK_BString
: return "<bstring>";
395 case TOK_CString
: return "<cstring>";
396 case TOK_HString
: return "<hstring>";
397 case TOK_Block
: return "<{block}>";
399 case KW_Block_NamedNumberList
: return "<NamedNumberList:>";
400 case KW_Block_Enumerations
: return "<Enumerations:>";
401 case KW_Block_Assignment
: return "<Assignment:>";
402 case KW_Block_NamedBitList
: return "<NamedBitList:>";
403 case KW_Block_IdentifierList
: return "<IdentifierList:>";
404 case KW_Block_FieldSpecList
: return "<FieldSpecList:>";
405 case KW_Block_ComponentTypeLists
: return "<ComponentTypeLists:>";
406 case KW_Block_AlternativeTypeLists
: return "<AlternativeTypeLists:>";
407 case KW_Block_Type
: return "<Type:>";
408 case KW_Block_Value
: return "<Value:>";
409 case KW_Block_ValueSet
: return "<ValueSet:>";
410 case KW_Block_Object
: return "<Object:>";
411 case KW_Block_ObjectSet
: return "<ObjectSet:>";
412 case KW_Block_SeqOfValue
: return "<SeqOfValue:>";
413 case KW_Block_SetOfValue
: return "<SetOfValue:>";
414 case KW_Block_SequenceValue
: return "<SequenceValue:>";
415 case KW_Block_SetValue
: return "<SetValue:>";
416 case KW_Block_ObjectSetSpec
: return "<ObjectSetSpec:>";
417 case KW_Block_DefinedObjectSetBlock
: return "<DefinedObjectSetBlock:>";
418 case KW_Block_AtNotationList
: return "<AtNotationList:>";
419 case KW_Block_OIDValue
: return "<OIDValue:>";
420 case KW_Block_ROIDValue
: return "<ROIDValue:>";
421 case KW_Block_CharStringValue
: return "<CharStringValue:>";
422 case KW_Block_QuadrupleOrTuple
: return "<QuadrupleOrTuple:>";
424 return "<Error! Not a keyword.>";
428 const Identifier
& Token::get_semval_id() const
431 case TOK_UpperIdentifier
:
432 case TOK_LowerIdentifier
:
433 case TOK_ampUpperIdentifier
:
434 case TOK_ampLowerIdentifier
:
437 FATAL_ERROR("Token::get_semval_id()");
441 void Token::create_block(TokenBuf
*tb
)
443 if (token
!= '{' || !tb
) FATAL_ERROR("Token::create_block()");
445 /** \todo set the correct end line/column info */
446 semval
.block
= new Block(tb
);
447 semval
.block
->set_location(*this);
450 void Token::dump(unsigned level
) const
453 case TOK_UpperIdentifier
:
454 case TOK_LowerIdentifier
:
455 case TOK_ampUpperIdentifier
:
456 case TOK_ampLowerIdentifier
:
457 semval
.id
->dump(level
);
460 DEBUG(level
, "token: number (%s)", semval
.i
->t_str().c_str());
463 DEBUG(level
, "token: cstring (\"%s\")", semval
.str
->c_str());
468 semval
.value
->dump(level
);
471 semval
.block
->dump(level
);
474 DEBUG(level
, "%s", get_token_name());
478 // =================================
480 // =================================
483 : Node(), filename("<undef>")
485 tokens
=new tokens_t();
488 TokenBuf::TokenBuf(tokens_t
*p_tokens
)
489 : Node(), tokens(p_tokens
), filename("<undef>")
492 FATAL_ERROR("NULL parameter: Asn::TokenBuf::TokenBuf(tokens_t*)");
495 TokenBuf::TokenBuf(const TokenBuf
& p
)
496 : Node(), filename(p
.filename
)
498 tokens
=new tokens_t();
499 for(size_t i
=0; i
<p
.tokens
->size(); i
++)
500 tokens
->add((*p
.tokens
)[i
]->clone());
503 TokenBuf::~TokenBuf()
509 void TokenBuf::delete_tokens()
511 for(size_t i
=0; i
<tokens
->size(); i
++)
516 void TokenBuf::reset(const char *p_filename
)
522 bool TokenBuf::read_next()
524 /* if there was an EOF, don't try to read another token */
525 if(!tokens
->empty() && (*tokens
)[tokens
->size()-1]->get_token()=='\0')
528 tokens
->add(new Token(token
, yylval
, Location(filename
, yylineno
)));
532 Token
*& TokenBuf::get_at(size_t pos
)
534 while(tokens
->size()<=pos
&& read_next()) ;
535 if(pos
<tokens
->size()) {
536 return (*tokens
)[pos
];
540 FATAL_ERROR("Asn::TokenBuf::get_at()");
541 return (*tokens
)[tokens
->size()-1];
545 void TokenBuf::push_front_token(Token
*p_token
)
548 FATAL_ERROR("Asn::TokenBuf::push_front_token()");
549 tokens
->add_front(p_token
);
552 void TokenBuf::push_front_kw_token(int kw
)
555 FATAL_ERROR("Asn::TokenBuf::push_front_kw_token()");
556 tokens
->add_front(new Token(kw
, *(*tokens
)[0]));
559 void TokenBuf::push_back_token(Token
*p_token
)
562 FATAL_ERROR("NULL parameter: Asn::TokenBuf::push_back_token()");
563 tokens
->add(p_token
);
566 void TokenBuf::push_back_kw_token(int kw
)
569 FATAL_ERROR("Asn::TokenBuf::push_back_kw_token()");
570 tokens
->add(new Token(kw
, *(*tokens
)[tokens
->size() - 1]));
573 void TokenBuf::move_tokens_from(TokenBuf
*tb
)
576 FATAL_ERROR("NULL parameter: Asn::TokenBuf::move_tokens_from()");
577 size_t insert_pos
=tokens
->size();
578 if(!tokens
->empty() && (*tokens
)[tokens
->size()-1]->get_token()=='\0')
580 size_t num_of_toks
=tb
->tokens
->size();
581 if(!tb
->tokens
->empty() &&
582 (*tb
->tokens
)[tb
->tokens
->size()-1]->get_token()=='\0')
584 tokens_t
*tmp_tokens
=tb
->tokens
->subvector(0, num_of_toks
);
585 tb
->tokens
->replace(0, num_of_toks
);
586 tokens
->replace(insert_pos
, 0, tmp_tokens
);
587 tmp_tokens
->clear(); delete tmp_tokens
;
590 Token
* TokenBuf::pop_front_token()
592 Token
*token
=get_at(0);
593 if(token
->get_token()=='{') {
594 token
->set_loc_info(); /* report this line if unmatch_error */
595 /* search the matching '}' */
598 bool unmatch_error
=false;
599 for(i
=1; blocklevel
>0 && !unmatch_error
; i
++) {
600 switch(get_at(i
)->get_token()) {
608 yyerror("Unmatched '{'");
610 i
--; /* EOF is not part of the block */
614 /* copy the tokens of the block to a new vector */
615 tokens_t
*tokens_block
=tokens
->subvector(1, i
-1);
616 if(!unmatch_error
) /* replace '}' to EOF */
617 (*tokens_block
)[tokens_block
->size()-1]->set_token('\0');
618 else /* clone EOF and add to block */
619 tokens_block
->add(get_at(i
)->clone());
620 /* remove the tokens from their original vector */
621 tokens
->replace(0, i
);
622 /* create the new tokenbuf from the tokens of the block */
623 TokenBuf
*tb
=new TokenBuf(tokens_block
);
624 tb
->filename
=filename
;
625 /* transform the opening '{' to a block-token */
626 token
->create_block(tb
);
629 /* remove the first token */
630 tokens
->replace(0, 1);
637 Token
*token
=pop_front_token();
638 int tmp_tok
= token
->get_token();
639 token
->set_loc_info();
640 token
->steal_semval(yylval
);
641 yylloc
.first_line
=yylloc
.last_line
=token
->get_lineno();
642 yylloc
.first_column
=yylloc
.last_column
=0;
647 void TokenBuf::dump(unsigned level
) const
649 DEBUG(level
, "Tokens: (%lu pcs.)", (unsigned long) tokens
->size());
651 for(size_t i
=0; i
<tokens
->size(); i
++)
652 (*tokens
)[i
]->dump(level
);