Merge github.com:eclipse/titan.core
[deliverable/titan.core.git] / compiler2 / asn1 / OCSV.cc
CommitLineData
d44e3c4f 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
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Cserveni, Akos
11 * Forstner, Matyas
12 * Raduly, Csaba
13 * Szabados, Kristof
14 * Szabo, Janos Zoltan – initial implementation
15 *
16 ******************************************************************************/
970ed795
EL
17#include "OCSV.hh"
18#include "Block.hh"
19#include "TokenBuf.hh"
20#include "../Type.hh"
21#include "../Value.hh"
22
23namespace Asn {
24
25 // =================================
26 // ===== OCSV_Builder
27 // =================================
28
29 OCSV_Builder::OCSV_Builder(TokenBuf *p_tb, FieldSpecs *p_fss)
30 : OCS_Visitor(), fss(p_fss)
31 {
32 if(!p_fss)
33 FATAL_ERROR("NULL parameter: Asn::OCSV_Builder::OCSV_Builder()");
34 if(!p_tb) { // default syntax
35 tb=0;
36 }
37 else {
38 tb=new TokenBuf();
39 tb->reset(p_tb->get_filename());
40 bool ok=false;
41 while(!ok) {
42 Token *token=p_tb->pop_front_token();
43 switch(token->get_token()) {
44 case TOK_LeftVersionBrackets:
45 token->set_token('[');
46 tb->push_back_token(token);
47 tb->push_back_token(token->clone());
48 break;
49 case TOK_RightVersionBrackets:
50 token->set_token(']');
51 tb->push_back_token(token);
52 tb->push_back_token(token->clone());
53 break;
54 case '\0':
55 ok=true;
56 default:
57 tb->push_back_token(token);
58 } // switch token
59 } // while !ok
60 }
61 }
62
63 OCSV_Builder::~OCSV_Builder()
64 {
65 delete tb;
66 }
67
68 void OCSV_Builder::visit0(OCS_Node& p)
69 {
70 if(p.get_is_builded())
71 FATAL_ERROR("Asn::OCSV_Builder::visit0()");
72 }
73
74 void OCSV_Builder::visit_root(OCS_root& p)
75 {
76 visit0(p);
77 if(tb) {
78 p.get_seq().accept(*this);
79 }
80 else {
81 OCS_seq& seq=p.get_seq();
82 for(size_t i=0; i<fss->get_nof_fss(); i++) {
83 FieldSpec *t_fs=fss->get_fs_byIndex(i)->get_last();
84 OCS_setting::settingtype_t t_st=OCS_setting::S_UNDEF;
85 switch(t_fs->get_fstype()) {
86 case FieldSpec::FS_T:
87 t_st=OCS_setting::S_T;
88 break;
89 case FieldSpec::FS_V_FT:
90 case FieldSpec::FS_V_VT:
91 t_st=OCS_setting::S_V;
92 break;
93 case FieldSpec::FS_VS_FT:
94 case FieldSpec::FS_VS_VT:
95 t_st=OCS_setting::S_VS;
96 break;
97 case FieldSpec::FS_O:
98 t_st=OCS_setting::S_O;
99 break;
100 case FieldSpec::FS_OS:
101 t_st=OCS_setting::S_OS;
102 break;
103 case FieldSpec::FS_ERROR:
104 continue;
105 break;
106 default:
107 FATAL_ERROR("Asn::OCSV_Builder::visit_root()");
108 } // switch
109 OCS_seq *t_seq=new OCS_seq
110 (t_fs->get_is_optional() || t_fs->has_default(), true);
111 t_seq->add_node(new OCS_literal(t_fs->get_id().clone()));
112 t_seq->add_node(new OCS_setting(t_st, t_fs->get_id().clone()));
113 for(size_t j=0; j<2; j++)
114 t_seq->get_nth_node(j)->set_location(*t_fs);
115 seq.add_node(t_seq);
116 } // for i
117 }
118 p.set_is_builded();
119 }
120
121 void OCSV_Builder::visit_seq(OCS_seq& p)
122 {
123 visit0(p);
124
125 bool ok=false;
126 Token *token;
127 while(!ok) {
128 token=tb->pop_front_token();
129 token->set_loc_info();
130 if(token->get_token()=='\0') {
131 ok=true;
132 delete token;
133 }
134 else if(token->get_token()=='[') {
135 delete token;
136 int blocklevel=1;
137 TokenBuf *new_tb=new TokenBuf();
138 while(blocklevel>0) {
139 token=tb->pop_front_token();
140 switch(token->get_token()) {
141 case '[':
142 blocklevel++;
143 new_tb->push_back_token(token);
144 break;
145 case ']':
146 blocklevel--;
147 if(!blocklevel) token->set_token('\0');
148 new_tb->push_back_token(token);
149 break;
150 case 0:
151 token->set_loc_info();
152 token->error("Unmatched `['");
153 break;
154 default:
155 new_tb->push_back_token(token);
156 break;
157 } // switch
158 } // while
159 OCSV_Builder *new_OCSV_Builder=new OCSV_Builder(new_tb, fss);
160 delete new_tb;
161 OCS_seq *new_OCS_seq=new OCS_seq(true);
162 p.add_node(new_OCS_seq);
163 new_OCS_seq->accept(*new_OCSV_Builder);
164 delete new_OCSV_Builder;
165 }
166 else if(token->is_literal_kw()) {
167 p.add_node(new OCS_literal(token->get_token()));
168 delete token;
169 }
170 else if(token->is_literal_id()) {
171 p.add_node(new OCS_literal(token->get_semval_id().clone()));
172 delete token;
173 }
174 else if(token->is_ampId()) {
175 OCS_setting::settingtype_t st=OCS_setting::S_UNDEF;
176 FieldSpec *fs=0;
177 const Identifier& id = token->get_semval_id();
178 if(!fss->has_fs_withId(id)) {
179 token->error("No field with name `%s'", id.get_dispname().c_str());
180 goto afteradding;
181 }
182 fs=fss->get_fs_byId(id)->get_last();
183 switch(fs->get_fstype()) {
184 case FieldSpec::FS_UNDEF:
185 FATAL_ERROR("Asn::OCSV_Builder::visit_seq()");
186 break;
187 case FieldSpec::FS_T:
188 st=OCS_setting::S_T;
189 break;
190 case FieldSpec::FS_V_FT:
191 case FieldSpec::FS_V_VT:
192 st=OCS_setting::S_V;
193 break;
194 case FieldSpec::FS_VS_FT:
195 case FieldSpec::FS_VS_VT:
196 st=OCS_setting::S_VS;
197 break;
198 case FieldSpec::FS_O:
199 st=OCS_setting::S_O;
200 break;
201 case FieldSpec::FS_OS:
202 st=OCS_setting::S_OS;
203 break;
204 case FieldSpec::FS_ERROR:
205 goto afteradding;
206 default:
207 FATAL_ERROR("Asn::OCSV_Builder::visit_seq()");
208 } // switch
209 p.add_node(new OCS_setting(st, id.clone()));
210 afteradding:
211 delete token;
212 }
213 else {
214 token->set_loc_info();
215 token->error("Unexpected `%s'", token->get_token_name());
216 delete token;
217 }
218 } // while !ok
219 if(p.get_is_opt() && p.get_nof_nodes()==0)
220 token->error("Empty optional group is not allowed");
221 p.set_is_builded();
222 }
223
224 void OCSV_Builder::visit_literal(OCS_literal&)
225 {
226 FATAL_ERROR("Asn::OCSV_Builder::visit_literal()");
227 }
228
229 void OCSV_Builder::visit_setting(OCS_setting&)
230 {
231 FATAL_ERROR("Asn::OCSV_Builder::visit_setting()");
232 }
233
234 // =================================
235 // ===== OCSV_Parser
236 // =================================
237
238 OCSV_Parser::OCSV_Parser(TokenBuf *p_tb, Obj_defn *p_my_obj)
239 : OCS_Visitor(), my_obj(p_my_obj), success(true)
240 {
241 if(!p_tb || !my_obj)
242 FATAL_ERROR("NULL parameter: Asn::OCSV_Parser::OCSV_Parser()");
243 tb=new TokenBuf();
244 tb->reset(p_tb->get_filename());
245 bool ok=false;
246 while(!ok) {
247 Token *token=p_tb->pop_front_token();
248 switch(token->get_token()) {
249 case '\0':
250 ok=true;
251 default:
252 tb->push_back_token(token);
253 } // switch token
254 } // while !ok
255 }
256
257 OCSV_Parser::~OCSV_Parser()
258 {
259 delete tb;
260 }
261
262 void OCSV_Parser::visit_root(OCS_root& p)
263 {
264 if(!p.get_is_builded() || !success)
265 FATAL_ERROR("Asn::OCSV_Parser::visit_root()");
266 prev_success=false;
267 my_obj->set_location(*tb->get_at(0));
268 Error_Context ec(my_obj, "While parsing object `%s'",
269 my_obj->get_fullname().c_str());
270 p.get_seq().accept(*this);
271 if(success && tb->get_at(0)->get_token()!='\0') {
272 success=false;
273 tb->get_at(0)->error("Unexpected `%s'",
274 tb->get_at(0)->get_token_name());
275 tb->get_at(0)->error("Superfluous part detected");
276 }
277 if(!success) {
278 DEBUG(1, "Erroneous object definition detected.");
279 DEBUG(1, "The correct syntax is:");
280 p.dump(1);
281 my_obj->error("Check the syntax of objectclass"
282 " (consider using debug messages)");
283 my_obj->set_is_erroneous();
284 }
285 }
286
287 void OCSV_Parser::visit_seq(OCS_seq& p)
288 {
289 size_t i;
290 if(p.get_opt_first_comma() && my_obj->get_nof_fss()>0) {
291 if(tb->get_at(0)->get_token()==',') {
292 delete tb->pop_front_token();
293 }
294 else {
295 if(!p.get_is_opt()) {
296 success=false;
297 tb->get_at(0)->error("Unexpected `%s'",
298 tb->get_at(0)->get_token_name());
299 tb->get_at(0)->error("Expecting `,'");
300 }
301 else prev_success=true;
302 return;
303 }
304 i=0;
305 }
306 else {
307 /* This can be only if each of the fieldspecs were erroneous */
308 if(p.get_nof_nodes()==0) return;
309 p.get_nth_node(0)->accept(*this);
310 if(!success) return;
311 if(!prev_success) {
312 if(!p.get_is_opt()) {
313 success=false;
314 tb->get_at(0)->error("Unexpected `%s'",
315 tb->get_at(0)->get_token_name());
316 tb->get_at(0)->error("Expecting %s",
317 p.get_dispname().c_str());
318 }
319 else prev_success=true;
320 return;
321 }
322 i=1;
323 }
324 for(; i<p.get_nof_nodes(); i++) {
325 p.get_nth_node(i)->accept(*this);
326 if(!prev_success) {
327 if(p.get_is_opt()){
328 prev_success = true;
329 tb->push_front_kw_token(',');
330 return;
331 }
332 success=false;
333 tb->get_at(0)->error("Unexpected `%s'",
334 tb->get_at(0)->get_token_name());
335 tb->get_at(0)->error("Expecting %s",
336 p.get_dispname().c_str());
337 }
338 if(!success) return;
339 }
340 }
341
342 void OCSV_Parser::visit_literal(OCS_literal& p)
343 {
344 prev_success=false;
345 if(p.is_keyword()) {
346 if(p.get_keyword()==tb->get_at(0)->get_token()) {
347 delete tb->pop_front_token();
348 prev_success=true;
349 }
350 }
351 else {
352 Token *token=tb->get_at(0);
353 if(token->is_id()
354 && (token->get_semval_id().get_dispname()
355 == p.get_word()->get_dispname())) {
356 delete tb->pop_front_token();
357 prev_success=true;
358 }
359 }
360 }
361
362 void OCSV_Parser::visit_setting(OCS_setting& p)
363 {
364 Error_Context cntxt(&p, "While parsing setting for this field: `%s'",
365 p.get_id()->get_dispname().c_str());
366 FieldSetting *fs=0;
367 switch(p.get_st()) {
368 case OCS_setting::S_T: {
369 Type *setting=parse_type();
370 if(setting) {
371 fs=new FieldSetting_Type(p.get_id()->clone(), setting);
372 fs->set_location(*setting);
373 }
374 break;}
375 case OCS_setting::S_V: {
376 Value *setting=parse_value();
377 if(setting) {
378 fs=new FieldSetting_Value(p.get_id()->clone(), setting);
379 fs->set_location(*setting);
380 }
381 break;}
382 case OCS_setting::S_VS:
383 NOTSUPP("ValueSet settings");
384 prev_success=false;
385 return;
386 break;
387 case OCS_setting::S_O: {
388 Object *setting=parse_object();
389 if(setting) {
390 fs=new FieldSetting_O(p.get_id()->clone(), setting);
391 fs->set_location(*setting);
392 }
393 break;}
394 case OCS_setting::S_OS: {
395 ObjectSet *setting=parse_objectset();
396 if(setting) {
397 fs=new FieldSetting_OS(p.get_id()->clone(), setting);
398 fs->set_location(*setting);
399 }
400 break;}
401 case OCS_setting::S_UNDEF:
402 FATAL_ERROR("Undefined setting");
403 break;
404 } // switch
405 if(!fs) {
406 prev_success=false;
407 return;
408 }
409 prev_success=true;
410 my_obj->add_fs(fs);
411 }
412
413 size_t OCSV_Parser::is_ref(size_t pos)
414 {
415 if(!(tb->get_at(pos)->get_token()==TOK_UpperIdentifier
416 || tb->get_at(pos)->get_token()==TOK_LowerIdentifier))
417 return 0;
418 size_t pos2=pos+1;
419 while(tb->get_at(pos2)->get_token()=='.'
420 && tb->get_at(pos2+1)->is_id())
421 pos2+=2;
422 if(tb->get_at(pos2)->get_token()==TOK_Block)
423 pos2++;
424 return pos2-pos;
425 }
426
427 size_t OCSV_Parser::is_tag(size_t pos)
428 {
429 size_t pos2=pos;
430 if(tb->get_at(pos2)->get_token()!='[')
431 return 0;
432 do pos2++;
433 while(tb->get_at(pos2)->get_token()!=']'
434 && tb->get_at(pos2)->get_token()!='\0');
435 if(tb->get_at(pos2)->get_token()==']') pos2++;
436 switch(tb->get_at(pos2)->get_token()) {
437 case KW_IMPLICIT:
438 case KW_EXPLICIT:
439 pos2++;
440 } //switch
441 return pos2-pos;
442 }
443
444 size_t OCSV_Parser::is_constraint(size_t pos)
445 {
446 size_t pos2=pos;
447 if(tb->get_at(pos2)->get_token()!='(')
448 return 0;
449 unsigned blocklevel=1;
450 for(pos2=pos+1; blocklevel>0; pos2++) {
451 switch(tb->get_at(pos2)->get_token()) {
452 case '(':
453 blocklevel++;
454 break;
455 case ')':
456 blocklevel--;
457 break;
458 case '\0':
459 blocklevel=0;
460 break;
461 } // switch
462 } // for pos2
463 if(tb->get_at(pos2)->get_token()==')') pos2++;
464 return pos2-pos;
465 }
466
467 size_t OCSV_Parser::is_constraints(size_t pos)
468 {
469 size_t pos2=pos, pos3;
470 while((pos3=is_constraint(pos2)))
471 pos2+=pos3;
472 return pos2-pos;
473 }
474
475 size_t OCSV_Parser::is_nakedtype(size_t pos)
476 {
477 size_t pos2=pos;
478 switch(tb->get_at(pos2)->get_token()) {
479 case KW_NULL:
480 case KW_BOOLEAN:
481 case KW_GeneralString:
482 case KW_BMPString:
483 case KW_GraphicString:
484 case KW_IA5String:
485 case KW_NumericString:
486 case KW_PrintableString:
487 case KW_TeletexString:
488 case KW_T61String:
489 case KW_UniversalString:
490 case KW_UTF8String:
491 case KW_VideotexString:
492 case KW_VisibleString:
493 case KW_ISO646String:
494 case KW_RELATIVE_OID:
495 case KW_REAL:
496 case KW_EXTERNAL:
497 case KW_GeneralizedTime:
498 case KW_UTCTime:
499 case KW_ObjectDescriptor:
500 pos2++;
501 break;
502 case KW_BIT:
503 pos2++;
504 if(tb->get_at(pos2)->get_token()==KW_STRING) {
505 pos2++;
506 if(tb->get_at(pos2)->get_token()==TOK_Block)
507 pos2++;
508 }
509 break;
510 case KW_CHARACTER:
511 pos2++;
512 if(tb->get_at(pos2)->get_token()==KW_STRING)
513 pos2++;
514 break;
515 case KW_CHOICE:
516 case KW_ENUMERATED:
517 case KW_INTEGER:
518 pos2++;
519 if(tb->get_at(pos2)->get_token()==TOK_Block)
520 pos2++;
521 break;
522 case KW_SEQUENCE:
523 case KW_SET:
524 pos2++;
525 if(tb->get_at(pos2)->get_token()==TOK_Block)
526 pos2++;
527 else { // SeOf
528 if(tb->get_at(pos2)->get_token()==KW_SIZE)
529 pos2++;
530 pos2+=is_constraint(pos2);
531 if(tb->get_at(pos2)->get_token()==KW_OF) {
532 pos2+=tb->get_at(pos2+1)->get_token()==TOK_LowerIdentifier?2:1;
533 pos2+=is_type(pos2);
534 }
535 }
536 break;
537 case KW_OBJECT:
538 pos2++;
539 if(tb->get_at(pos2)->get_token()==KW_IDENTIFIER)
540 pos2++;
541 break;
542 case KW_OCTET:
543 pos2++;
544 if(tb->get_at(pos2)->get_token()==KW_STRING)
545 pos2++;
546 break;
547 case KW_EMBEDDED:
548 pos2++;
549 if(tb->get_at(pos2)->get_token()==KW_PDV)
550 pos2++;
551 break;
552 case KW_ANY:
553 pos2++;
554 if(tb->get_at(pos2)->get_token()==KW_DEFINED
555 && tb->get_at(pos2+1)->get_token()==KW_BY
556 && tb->get_at(pos2+2)->get_token()==TOK_LowerIdentifier
557 )
558 pos2+=3;
559 break;
560 } // switch
561 if(pos2==pos)
562 pos2=is_ref(pos)+pos2;
563 return pos2-pos;
564 }
565
566 size_t OCSV_Parser::is_type(size_t pos)
567 {
568 size_t pos2=pos, pos3;
569 while((pos3=is_tag(pos2)))
570 pos2+=pos3;
571 pos2+=is_nakedtype(pos2);
572 pos2+=is_constraints(pos2);
573 return pos2-pos;
574 }
575
576 size_t OCSV_Parser::is_value(size_t pos)
577 {
578 size_t pos2=pos;
579 switch(tb->get_at(pos2)->get_token()) {
580 case TOK_Block:
581 case TOK_BString:
582 case TOK_HString:
583 case TOK_CString:
584 case KW_NULL:
585 case KW_TRUE:
586 case KW_FALSE:
587 case TOK_Number:
588 case TOK_RealNumber:
589 case KW_PLUS_INFINITY:
590 case KW_MINUS_INFINITY:
591 pos2++;
592 break;
593 case '-':
594 pos2++;
595 if(tb->get_at(pos2)->get_token()==TOK_Number
596 || tb->get_at(pos2)->get_token()==TOK_RealNumber)
597 pos2++;
598 break;
599 case TOK_LowerIdentifier:
600 if(tb->get_at(pos2+1)->get_token()==':') {
601 pos2=is_value(pos2+2);
602 if(pos2) pos2+=pos+2;
603 else pos2=pos;
604 } else pos2=pos;
605 break;
606 } // switch
607 if(pos2==pos)
608 pos2=is_ref(pos)+pos;
609 return pos2-pos;
610 }
611
612 size_t OCSV_Parser::is_object(size_t pos)
613 {
614 size_t pos2=pos;
615 if(tb->get_at(pos2)->get_token()==TOK_Block)
616 pos2++;
617 if(pos2==pos)
618 pos2=is_ref(pos)+pos;
619 return pos2-pos;
620 }
621
622 size_t OCSV_Parser::is_objectset(size_t pos)
623 {
624 size_t pos2=pos;
625 if(tb->get_at(pos2)->get_token()==TOK_Block)
626 pos2++;
627 return pos2-pos;
628 }
629
630 Block* OCSV_Parser::get_first_n(size_t n)
631 {
632 TokenBuf *new_tb=new TokenBuf();
633 new_tb->reset(tb->get_filename());
634 for(size_t i=0; i<n; i++)
635 new_tb->push_back_token(tb->pop_front_token());
636 new_tb->push_back_token(new Token(0, Location(tb->get_filename())));
637 return new Block(new_tb);
638 }
639
640 Type* OCSV_Parser::parse_type()
641 {
642 size_t n;
643 n=is_type(0);
644 if(!n) return 0;
645 Block *block=get_first_n(n);
646 Node *node=block->parse(KW_Block_Type);
647 delete block;
648 Type *new_type=dynamic_cast<Type*>(node);
649 if(!new_type)
650 new_type=new Type(Type::T_ERROR);
651 return new_type;
652 }
653
654 Value* OCSV_Parser::parse_value()
655 {
656 size_t n;
657 n=is_value(0);
658 if(!n) return 0;
659 Block *block=get_first_n(n);
660 Node *node=block->parse(KW_Block_Value);
661 delete block;
662 Value *new_value=dynamic_cast<Value*>(node);
663 if(!new_value)
664 new_value=new Value(Value::V_ERROR);
665 return new_value;
666 }
667
668 Object* OCSV_Parser::parse_object()
669 {
670 size_t n;
671 n=is_object(0);
672 if(!n) return 0;
673 Block *block=get_first_n(n);
674 Node *node=block->parse(KW_Block_Object);
675 delete block;
676 Object *new_object=dynamic_cast<Object*>(node);
677 if(!new_object)
678 new_object=new Obj_defn();
679 return new_object;
680 }
681
682 ObjectSet* OCSV_Parser::parse_objectset()
683 {
684 size_t n;
685 n=is_objectset(0);
686 if(!n) return 0;
687 Block *block=get_first_n(n);
688 Node *node=block->parse(KW_Block_ObjectSet);
689 delete block;
690 ObjectSet *new_objectset=dynamic_cast<ObjectSet*>(node);
691 if(!new_objectset)
692 new_objectset=new OS_defn();
693 return new_objectset;
694 }
695
696} // namespace Asn
This page took 0.050805 seconds and 5 git commands to generate.