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
14 * Szabo, Janos Zoltan – initial implementation
16 ******************************************************************************/
19 #include "TokenBuf.hh"
21 #include "../Value.hh"
25 // =================================
27 // =================================
29 OCSV_Builder::OCSV_Builder(TokenBuf
*p_tb
, FieldSpecs
*p_fss
)
30 : OCS_Visitor(), fss(p_fss
)
33 FATAL_ERROR("NULL parameter: Asn::OCSV_Builder::OCSV_Builder()");
34 if(!p_tb
) { // default syntax
39 tb
->reset(p_tb
->get_filename());
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());
49 case TOK_RightVersionBrackets
:
50 token
->set_token(']');
51 tb
->push_back_token(token
);
52 tb
->push_back_token(token
->clone());
57 tb
->push_back_token(token
);
63 OCSV_Builder::~OCSV_Builder()
68 void OCSV_Builder::visit0(OCS_Node
& p
)
70 if(p
.get_is_builded())
71 FATAL_ERROR("Asn::OCSV_Builder::visit0()");
74 void OCSV_Builder::visit_root(OCS_root
& p
)
78 p
.get_seq().accept(*this);
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()) {
87 t_st
=OCS_setting::S_T
;
89 case FieldSpec::FS_V_FT
:
90 case FieldSpec::FS_V_VT
:
91 t_st
=OCS_setting::S_V
;
93 case FieldSpec::FS_VS_FT
:
94 case FieldSpec::FS_VS_VT
:
95 t_st
=OCS_setting::S_VS
;
98 t_st
=OCS_setting::S_O
;
100 case FieldSpec::FS_OS
:
101 t_st
=OCS_setting::S_OS
;
103 case FieldSpec::FS_ERROR
:
107 FATAL_ERROR("Asn::OCSV_Builder::visit_root()");
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
);
121 void OCSV_Builder::visit_seq(OCS_seq
& p
)
128 token
=tb
->pop_front_token();
129 token
->set_loc_info();
130 if(token
->get_token()=='\0') {
134 else if(token
->get_token()=='[') {
137 TokenBuf
*new_tb
=new TokenBuf();
138 while(blocklevel
>0) {
139 token
=tb
->pop_front_token();
140 switch(token
->get_token()) {
143 new_tb
->push_back_token(token
);
147 if(!blocklevel
) token
->set_token('\0');
148 new_tb
->push_back_token(token
);
151 token
->set_loc_info();
152 token
->error("Unmatched `['");
155 new_tb
->push_back_token(token
);
159 OCSV_Builder
*new_OCSV_Builder
=new OCSV_Builder(new_tb
, fss
);
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
;
166 else if(token
->is_literal_kw()) {
167 p
.add_node(new OCS_literal(token
->get_token()));
170 else if(token
->is_literal_id()) {
171 p
.add_node(new OCS_literal(token
->get_semval_id().clone()));
174 else if(token
->is_ampId()) {
175 OCS_setting::settingtype_t st
=OCS_setting::S_UNDEF
;
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());
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()");
187 case FieldSpec::FS_T
:
190 case FieldSpec::FS_V_FT
:
191 case FieldSpec::FS_V_VT
:
194 case FieldSpec::FS_VS_FT
:
195 case FieldSpec::FS_VS_VT
:
196 st
=OCS_setting::S_VS
;
198 case FieldSpec::FS_O
:
201 case FieldSpec::FS_OS
:
202 st
=OCS_setting::S_OS
;
204 case FieldSpec::FS_ERROR
:
207 FATAL_ERROR("Asn::OCSV_Builder::visit_seq()");
209 p
.add_node(new OCS_setting(st
, id
.clone()));
214 token
->set_loc_info();
215 token
->error("Unexpected `%s'", token
->get_token_name());
219 if(p
.get_is_opt() && p
.get_nof_nodes()==0)
220 token
->error("Empty optional group is not allowed");
224 void OCSV_Builder::visit_literal(OCS_literal
&)
226 FATAL_ERROR("Asn::OCSV_Builder::visit_literal()");
229 void OCSV_Builder::visit_setting(OCS_setting
&)
231 FATAL_ERROR("Asn::OCSV_Builder::visit_setting()");
234 // =================================
236 // =================================
238 OCSV_Parser::OCSV_Parser(TokenBuf
*p_tb
, Obj_defn
*p_my_obj
)
239 : OCS_Visitor(), my_obj(p_my_obj
), success(true)
242 FATAL_ERROR("NULL parameter: Asn::OCSV_Parser::OCSV_Parser()");
244 tb
->reset(p_tb
->get_filename());
247 Token
*token
=p_tb
->pop_front_token();
248 switch(token
->get_token()) {
252 tb
->push_back_token(token
);
257 OCSV_Parser::~OCSV_Parser()
262 void OCSV_Parser::visit_root(OCS_root
& p
)
264 if(!p
.get_is_builded() || !success
)
265 FATAL_ERROR("Asn::OCSV_Parser::visit_root()");
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') {
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");
278 DEBUG(1, "Erroneous object definition detected.");
279 DEBUG(1, "The correct syntax is:");
281 my_obj
->error("Check the syntax of objectclass"
282 " (consider using debug messages)");
283 my_obj
->set_is_erroneous();
287 void OCSV_Parser::visit_seq(OCS_seq
& p
)
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();
295 if(!p
.get_is_opt()) {
297 tb
->get_at(0)->error("Unexpected `%s'",
298 tb
->get_at(0)->get_token_name());
299 tb
->get_at(0)->error("Expecting `,'");
301 else prev_success
=true;
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);
312 if(!p
.get_is_opt()) {
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());
319 else prev_success
=true;
324 for(; i
<p
.get_nof_nodes(); i
++) {
325 p
.get_nth_node(i
)->accept(*this);
329 tb
->push_front_kw_token(',');
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());
342 void OCSV_Parser::visit_literal(OCS_literal
& p
)
346 if(p
.get_keyword()==tb
->get_at(0)->get_token()) {
347 delete tb
->pop_front_token();
352 Token
*token
=tb
->get_at(0);
354 && (token
->get_semval_id().get_dispname()
355 == p
.get_word()->get_dispname())) {
356 delete tb
->pop_front_token();
362 void OCSV_Parser::visit_setting(OCS_setting
& p
)
364 Error_Context
cntxt(&p
, "While parsing setting for this field: `%s'",
365 p
.get_id()->get_dispname().c_str());
368 case OCS_setting::S_T
: {
369 Type
*setting
=parse_type();
371 fs
=new FieldSetting_Type(p
.get_id()->clone(), setting
);
372 fs
->set_location(*setting
);
375 case OCS_setting::S_V
: {
376 Value
*setting
=parse_value();
378 fs
=new FieldSetting_Value(p
.get_id()->clone(), setting
);
379 fs
->set_location(*setting
);
382 case OCS_setting::S_VS
:
383 NOTSUPP("ValueSet settings");
387 case OCS_setting::S_O
: {
388 Object
*setting
=parse_object();
390 fs
=new FieldSetting_O(p
.get_id()->clone(), setting
);
391 fs
->set_location(*setting
);
394 case OCS_setting::S_OS
: {
395 ObjectSet
*setting
=parse_objectset();
397 fs
=new FieldSetting_OS(p
.get_id()->clone(), setting
);
398 fs
->set_location(*setting
);
401 case OCS_setting::S_UNDEF
:
402 FATAL_ERROR("Undefined setting");
413 size_t OCSV_Parser::is_ref(size_t pos
)
415 if(!(tb
->get_at(pos
)->get_token()==TOK_UpperIdentifier
416 || tb
->get_at(pos
)->get_token()==TOK_LowerIdentifier
))
419 while(tb
->get_at(pos2
)->get_token()=='.'
420 && tb
->get_at(pos2
+1)->is_id())
422 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
427 size_t OCSV_Parser::is_tag(size_t pos
)
430 if(tb
->get_at(pos2
)->get_token()!='[')
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()) {
444 size_t OCSV_Parser::is_constraint(size_t pos
)
447 if(tb
->get_at(pos2
)->get_token()!='(')
449 unsigned blocklevel
=1;
450 for(pos2
=pos
+1; blocklevel
>0; pos2
++) {
451 switch(tb
->get_at(pos2
)->get_token()) {
463 if(tb
->get_at(pos2
)->get_token()==')') pos2
++;
467 size_t OCSV_Parser::is_constraints(size_t pos
)
469 size_t pos2
=pos
, pos3
;
470 while((pos3
=is_constraint(pos2
)))
475 size_t OCSV_Parser::is_nakedtype(size_t pos
)
478 switch(tb
->get_at(pos2
)->get_token()) {
481 case KW_GeneralString
:
483 case KW_GraphicString
:
485 case KW_NumericString
:
486 case KW_PrintableString
:
487 case KW_TeletexString
:
489 case KW_UniversalString
:
491 case KW_VideotexString
:
492 case KW_VisibleString
:
493 case KW_ISO646String
:
494 case KW_RELATIVE_OID
:
497 case KW_GeneralizedTime
:
499 case KW_ObjectDescriptor
:
504 if(tb
->get_at(pos2
)->get_token()==KW_STRING
) {
506 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
512 if(tb
->get_at(pos2
)->get_token()==KW_STRING
)
519 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
525 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
528 if(tb
->get_at(pos2
)->get_token()==KW_SIZE
)
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;
539 if(tb
->get_at(pos2
)->get_token()==KW_IDENTIFIER
)
544 if(tb
->get_at(pos2
)->get_token()==KW_STRING
)
549 if(tb
->get_at(pos2
)->get_token()==KW_PDV
)
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
562 pos2
=is_ref(pos
)+pos2
;
566 size_t OCSV_Parser::is_type(size_t pos
)
568 size_t pos2
=pos
, pos3
;
569 while((pos3
=is_tag(pos2
)))
571 pos2
+=is_nakedtype(pos2
);
572 pos2
+=is_constraints(pos2
);
576 size_t OCSV_Parser::is_value(size_t pos
)
579 switch(tb
->get_at(pos2
)->get_token()) {
589 case KW_PLUS_INFINITY
:
590 case KW_MINUS_INFINITY
:
595 if(tb
->get_at(pos2
)->get_token()==TOK_Number
596 || tb
->get_at(pos2
)->get_token()==TOK_RealNumber
)
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;
608 pos2
=is_ref(pos
)+pos
;
612 size_t OCSV_Parser::is_object(size_t pos
)
615 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
618 pos2
=is_ref(pos
)+pos
;
622 size_t OCSV_Parser::is_objectset(size_t pos
)
625 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
630 Block
* OCSV_Parser::get_first_n(size_t n
)
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
);
640 Type
* OCSV_Parser::parse_type()
645 Block
*block
=get_first_n(n
);
646 Node
*node
=block
->parse(KW_Block_Type
);
648 Type
*new_type
=dynamic_cast<Type
*>(node
);
650 new_type
=new Type(Type::T_ERROR
);
654 Value
* OCSV_Parser::parse_value()
659 Block
*block
=get_first_n(n
);
660 Node
*node
=block
->parse(KW_Block_Value
);
662 Value
*new_value
=dynamic_cast<Value
*>(node
);
664 new_value
=new Value(Value::V_ERROR
);
668 Object
* OCSV_Parser::parse_object()
673 Block
*block
=get_first_n(n
);
674 Node
*node
=block
->parse(KW_Block_Object
);
676 Object
*new_object
=dynamic_cast<Object
*>(node
);
678 new_object
=new Obj_defn();
682 ObjectSet
* OCSV_Parser::parse_objectset()
687 Block
*block
=get_first_n(n
);
688 Node
*node
=block
->parse(KW_Block_ObjectSet
);
690 ObjectSet
*new_objectset
=dynamic_cast<ObjectSet
*>(node
);
692 new_objectset
=new OS_defn();
693 return new_objectset
;
This page took 0.04419 seconds and 6 git commands to generate.