1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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 ///////////////////////////////////////////////////////////////////////////////
12 extern void asn1_yyerror(const char *s
);
13 #define yyerror asn1_yyerror
14 extern int asn1_yylex();
15 #define yylex asn1_yylex
16 extern const char *asn1_infile
;
17 extern int asn1_yylineno
;
18 #define yylineno asn1_yylineno
19 extern int asn1_plineno
;
20 #define plineno asn1_plineno
21 extern YYLTYPE asn1_yylloc
;
22 #define yylloc asn1_yylloc
26 using namespace Common
;
28 // =================================
30 // =================================
32 Token::Token(const Token
& p
)
33 : Node(p
), Location(p
), token(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();
43 semval
.i
= new int_val_t(*p
.semval
.i
);
46 semval
.str
= new string(*p
.semval
.str
);
51 semval
.value
= p
.semval
.value
->clone();
54 semval
.block
= p
.semval
.block
->clone();
60 bool Token::has_semval(int p_token
)
63 case TOK_UpperIdentifier
:
64 case TOK_LowerIdentifier
:
65 case TOK_ampUpperIdentifier
:
66 case TOK_ampLowerIdentifier
:
79 Token::Token(int p_token
, const Location
& p_loc
)
80 : Node(), Location(p_loc
), token(p_token
)
82 if (has_semval(p_token
)) FATAL_ERROR("Token::Token()");
85 Token::Token(int p_token
, const YYSTYPE
& p_semval
, const Location
& p_loc
)
86 : Node(), Location(p_loc
), token(p_token
)
89 case TOK_UpperIdentifier
:
90 case TOK_LowerIdentifier
:
91 case TOK_ampUpperIdentifier
:
92 case TOK_ampLowerIdentifier
:
93 semval
.id
= p_semval
.id
;
96 semval
.i
= p_semval
.i
;
99 semval
.str
= p_semval
.str
;
104 semval
.value
= p_semval
.value
;
107 semval
.block
= p_semval
.block
;
116 case TOK_UpperIdentifier
:
117 case TOK_LowerIdentifier
:
118 case TOK_ampUpperIdentifier
:
119 case TOK_ampLowerIdentifier
:
141 Token
*Token::clone() const
143 return new Token(*this);
146 void Token::set_token(int new_token
)
148 if (new_token
!= token
) {
149 if (has_semval(token
) || has_semval(new_token
))
150 FATAL_ERROR("Token::set_token()");
155 void Token::steal_semval(YYSTYPE
& p_semval
)
158 case TOK_UpperIdentifier
:
159 case TOK_LowerIdentifier
:
160 case TOK_ampUpperIdentifier
:
161 case TOK_ampLowerIdentifier
:
162 p_semval
.id
= semval
.id
;
165 p_semval
.i
= semval
.i
;
168 p_semval
.str
= semval
.str
;
173 p_semval
.value
= semval
.value
;
176 p_semval
.block
= semval
.block
;
183 void Token::set_loc_info() const
185 asn1_infile
= get_filename();
186 if(get_lineno() > 0) plineno
= get_lineno();
189 bool Token::is_literal_id() const
191 if(token
==TOK_UpperIdentifier
192 && semval
.id
->isvalid_asn_word())
197 bool Token::is_literal_kw() const
220 case KW_EXTENSIBILITY
:
248 bool Token::is_ampId() const
250 if(token
==TOK_ampUpperIdentifier
251 || token
==TOK_ampLowerIdentifier
)
256 bool Token::is_id() const
259 case TOK_UpperIdentifier
:
260 case TOK_LowerIdentifier
:
261 case TOK_ampUpperIdentifier
:
262 case TOK_ampLowerIdentifier
:
269 const char* Token::get_token_name(int 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}>";
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:>";
413 return "<Error! Not a keyword.>";
417 const Identifier
& Token::get_semval_id() const
420 case TOK_UpperIdentifier
:
421 case TOK_LowerIdentifier
:
422 case TOK_ampUpperIdentifier
:
423 case TOK_ampLowerIdentifier
:
426 FATAL_ERROR("Token::get_semval_id()");
430 void Token::create_block(TokenBuf
*tb
)
432 if (token
!= '{' || !tb
) FATAL_ERROR("Token::create_block()");
434 /** \todo set the correct end line/column info */
435 semval
.block
= new Block(tb
);
436 semval
.block
->set_location(*this);
439 void Token::dump(unsigned level
) const
442 case TOK_UpperIdentifier
:
443 case TOK_LowerIdentifier
:
444 case TOK_ampUpperIdentifier
:
445 case TOK_ampLowerIdentifier
:
446 semval
.id
->dump(level
);
449 DEBUG(level
, "token: number (%s)", semval
.i
->t_str().c_str());
452 DEBUG(level
, "token: cstring (\"%s\")", semval
.str
->c_str());
457 semval
.value
->dump(level
);
460 semval
.block
->dump(level
);
463 DEBUG(level
, "%s", get_token_name());
467 // =================================
469 // =================================
472 : Node(), filename("<undef>")
474 tokens
=new tokens_t();
477 TokenBuf::TokenBuf(tokens_t
*p_tokens
)
478 : Node(), tokens(p_tokens
), filename("<undef>")
481 FATAL_ERROR("NULL parameter: Asn::TokenBuf::TokenBuf(tokens_t*)");
484 TokenBuf::TokenBuf(const TokenBuf
& p
)
485 : Node(), filename(p
.filename
)
487 tokens
=new tokens_t();
488 for(size_t i
=0; i
<p
.tokens
->size(); i
++)
489 tokens
->add((*p
.tokens
)[i
]->clone());
492 TokenBuf::~TokenBuf()
498 void TokenBuf::delete_tokens()
500 for(size_t i
=0; i
<tokens
->size(); i
++)
505 void TokenBuf::reset(const char *p_filename
)
511 bool TokenBuf::read_next()
513 /* if there was an EOF, don't try to read another token */
514 if(!tokens
->empty() && (*tokens
)[tokens
->size()-1]->get_token()=='\0')
517 tokens
->add(new Token(token
, yylval
, Location(filename
, yylineno
)));
521 Token
*& TokenBuf::get_at(size_t pos
)
523 while(tokens
->size()<=pos
&& read_next()) ;
524 if(pos
<tokens
->size()) {
525 return (*tokens
)[pos
];
529 FATAL_ERROR("Asn::TokenBuf::get_at()");
530 return (*tokens
)[tokens
->size()-1];
534 void TokenBuf::push_front_token(Token
*p_token
)
537 FATAL_ERROR("Asn::TokenBuf::push_front_token()");
538 tokens
->add_front(p_token
);
541 void TokenBuf::push_front_kw_token(int kw
)
544 FATAL_ERROR("Asn::TokenBuf::push_front_kw_token()");
545 tokens
->add_front(new Token(kw
, *(*tokens
)[0]));
548 void TokenBuf::push_back_token(Token
*p_token
)
551 FATAL_ERROR("NULL parameter: Asn::TokenBuf::push_back_token()");
552 tokens
->add(p_token
);
555 void TokenBuf::push_back_kw_token(int kw
)
558 FATAL_ERROR("Asn::TokenBuf::push_back_kw_token()");
559 tokens
->add(new Token(kw
, *(*tokens
)[tokens
->size() - 1]));
562 void TokenBuf::move_tokens_from(TokenBuf
*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')
569 size_t num_of_toks
=tb
->tokens
->size();
570 if(!tb
->tokens
->empty() &&
571 (*tb
->tokens
)[tb
->tokens
->size()-1]->get_token()=='\0')
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
;
579 Token
* TokenBuf::pop_front_token()
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 '}' */
587 bool unmatch_error
=false;
588 for(i
=1; blocklevel
>0 && !unmatch_error
; i
++) {
589 switch(get_at(i
)->get_token()) {
597 yyerror("Unmatched '{'");
599 i
--; /* EOF is not part of the block */
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
);
618 /* remove the first token */
619 tokens
->replace(0, 1);
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;
636 void TokenBuf::dump(unsigned level
) const
638 DEBUG(level
, "Tokens: (%lu pcs.)", (unsigned long) tokens
->size());
640 for(size_t i
=0; i
<tokens
->size(); i
++)
641 (*tokens
)[i
]->dump(level
);