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