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 ///////////////////////////////////////////////////////////////////////////////
10 #include "TokenBuf.hh"
12 #include "../Value.hh"
16 // =================================
18 // =================================
20 OCSV_Builder::OCSV_Builder(TokenBuf
*p_tb
, FieldSpecs
*p_fss
)
21 : OCS_Visitor(), fss(p_fss
)
24 FATAL_ERROR("NULL parameter: Asn::OCSV_Builder::OCSV_Builder()");
25 if(!p_tb
) { // default syntax
30 tb
->reset(p_tb
->get_filename());
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());
40 case TOK_RightVersionBrackets
:
41 token
->set_token(']');
42 tb
->push_back_token(token
);
43 tb
->push_back_token(token
->clone());
48 tb
->push_back_token(token
);
54 OCSV_Builder::~OCSV_Builder()
59 void OCSV_Builder::visit0(OCS_Node
& p
)
61 if(p
.get_is_builded())
62 FATAL_ERROR("Asn::OCSV_Builder::visit0()");
65 void OCSV_Builder::visit_root(OCS_root
& p
)
69 p
.get_seq().accept(*this);
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()) {
78 t_st
=OCS_setting::S_T
;
80 case FieldSpec::FS_V_FT
:
81 case FieldSpec::FS_V_VT
:
82 t_st
=OCS_setting::S_V
;
84 case FieldSpec::FS_VS_FT
:
85 case FieldSpec::FS_VS_VT
:
86 t_st
=OCS_setting::S_VS
;
89 t_st
=OCS_setting::S_O
;
91 case FieldSpec::FS_OS
:
92 t_st
=OCS_setting::S_OS
;
94 case FieldSpec::FS_ERROR
:
98 FATAL_ERROR("Asn::OCSV_Builder::visit_root()");
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
);
112 void OCSV_Builder::visit_seq(OCS_seq
& p
)
119 token
=tb
->pop_front_token();
120 token
->set_loc_info();
121 if(token
->get_token()=='\0') {
125 else if(token
->get_token()=='[') {
128 TokenBuf
*new_tb
=new TokenBuf();
129 while(blocklevel
>0) {
130 token
=tb
->pop_front_token();
131 switch(token
->get_token()) {
134 new_tb
->push_back_token(token
);
138 if(!blocklevel
) token
->set_token('\0');
139 new_tb
->push_back_token(token
);
142 token
->set_loc_info();
143 token
->error("Unmatched `['");
146 new_tb
->push_back_token(token
);
150 OCSV_Builder
*new_OCSV_Builder
=new OCSV_Builder(new_tb
, fss
);
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
;
157 else if(token
->is_literal_kw()) {
158 p
.add_node(new OCS_literal(token
->get_token()));
161 else if(token
->is_literal_id()) {
162 p
.add_node(new OCS_literal(token
->get_semval_id().clone()));
165 else if(token
->is_ampId()) {
166 OCS_setting::settingtype_t st
=OCS_setting::S_UNDEF
;
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());
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()");
178 case FieldSpec::FS_T
:
181 case FieldSpec::FS_V_FT
:
182 case FieldSpec::FS_V_VT
:
185 case FieldSpec::FS_VS_FT
:
186 case FieldSpec::FS_VS_VT
:
187 st
=OCS_setting::S_VS
;
189 case FieldSpec::FS_O
:
192 case FieldSpec::FS_OS
:
193 st
=OCS_setting::S_OS
;
195 case FieldSpec::FS_ERROR
:
198 FATAL_ERROR("Asn::OCSV_Builder::visit_seq()");
200 p
.add_node(new OCS_setting(st
, id
.clone()));
205 token
->set_loc_info();
206 token
->error("Unexpected `%s'", token
->get_token_name());
210 if(p
.get_is_opt() && p
.get_nof_nodes()==0)
211 token
->error("Empty optional group is not allowed");
215 void OCSV_Builder::visit_literal(OCS_literal
&)
217 FATAL_ERROR("Asn::OCSV_Builder::visit_literal()");
220 void OCSV_Builder::visit_setting(OCS_setting
&)
222 FATAL_ERROR("Asn::OCSV_Builder::visit_setting()");
225 // =================================
227 // =================================
229 OCSV_Parser::OCSV_Parser(TokenBuf
*p_tb
, Obj_defn
*p_my_obj
)
230 : OCS_Visitor(), my_obj(p_my_obj
), success(true)
233 FATAL_ERROR("NULL parameter: Asn::OCSV_Parser::OCSV_Parser()");
235 tb
->reset(p_tb
->get_filename());
238 Token
*token
=p_tb
->pop_front_token();
239 switch(token
->get_token()) {
243 tb
->push_back_token(token
);
248 OCSV_Parser::~OCSV_Parser()
253 void OCSV_Parser::visit_root(OCS_root
& p
)
255 if(!p
.get_is_builded() || !success
)
256 FATAL_ERROR("Asn::OCSV_Parser::visit_root()");
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') {
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");
269 DEBUG(1, "Erroneous object definition detected.");
270 DEBUG(1, "The correct syntax is:");
272 my_obj
->error("Check the syntax of objectclass"
273 " (consider using debug messages)");
274 my_obj
->set_is_erroneous();
278 void OCSV_Parser::visit_seq(OCS_seq
& p
)
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();
286 if(!p
.get_is_opt()) {
288 tb
->get_at(0)->error("Unexpected `%s'",
289 tb
->get_at(0)->get_token_name());
290 tb
->get_at(0)->error("Expecting `,'");
292 else prev_success
=true;
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);
303 if(!p
.get_is_opt()) {
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());
310 else prev_success
=true;
315 for(; i
<p
.get_nof_nodes(); i
++) {
316 p
.get_nth_node(i
)->accept(*this);
320 tb
->push_front_kw_token(',');
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());
333 void OCSV_Parser::visit_literal(OCS_literal
& p
)
337 if(p
.get_keyword()==tb
->get_at(0)->get_token()) {
338 delete tb
->pop_front_token();
343 Token
*token
=tb
->get_at(0);
345 && (token
->get_semval_id().get_dispname()
346 == p
.get_word()->get_dispname())) {
347 delete tb
->pop_front_token();
353 void OCSV_Parser::visit_setting(OCS_setting
& p
)
355 Error_Context
cntxt(&p
, "While parsing setting for this field: `%s'",
356 p
.get_id()->get_dispname().c_str());
359 case OCS_setting::S_T
: {
360 Type
*setting
=parse_type();
362 fs
=new FieldSetting_Type(p
.get_id()->clone(), setting
);
363 fs
->set_location(*setting
);
366 case OCS_setting::S_V
: {
367 Value
*setting
=parse_value();
369 fs
=new FieldSetting_Value(p
.get_id()->clone(), setting
);
370 fs
->set_location(*setting
);
373 case OCS_setting::S_VS
:
374 NOTSUPP("ValueSet settings");
378 case OCS_setting::S_O
: {
379 Object
*setting
=parse_object();
381 fs
=new FieldSetting_O(p
.get_id()->clone(), setting
);
382 fs
->set_location(*setting
);
385 case OCS_setting::S_OS
: {
386 ObjectSet
*setting
=parse_objectset();
388 fs
=new FieldSetting_OS(p
.get_id()->clone(), setting
);
389 fs
->set_location(*setting
);
392 case OCS_setting::S_UNDEF
:
393 FATAL_ERROR("Undefined setting");
404 size_t OCSV_Parser::is_ref(size_t pos
)
406 if(!(tb
->get_at(pos
)->get_token()==TOK_UpperIdentifier
407 || tb
->get_at(pos
)->get_token()==TOK_LowerIdentifier
))
410 while(tb
->get_at(pos2
)->get_token()=='.'
411 && tb
->get_at(pos2
+1)->is_id())
413 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
418 size_t OCSV_Parser::is_tag(size_t pos
)
421 if(tb
->get_at(pos2
)->get_token()!='[')
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()) {
435 size_t OCSV_Parser::is_constraint(size_t pos
)
438 if(tb
->get_at(pos2
)->get_token()!='(')
440 unsigned blocklevel
=1;
441 for(pos2
=pos
+1; blocklevel
>0; pos2
++) {
442 switch(tb
->get_at(pos2
)->get_token()) {
454 if(tb
->get_at(pos2
)->get_token()==')') pos2
++;
458 size_t OCSV_Parser::is_constraints(size_t pos
)
460 size_t pos2
=pos
, pos3
;
461 while((pos3
=is_constraint(pos2
)))
466 size_t OCSV_Parser::is_nakedtype(size_t pos
)
469 switch(tb
->get_at(pos2
)->get_token()) {
472 case KW_GeneralString
:
474 case KW_GraphicString
:
476 case KW_NumericString
:
477 case KW_PrintableString
:
478 case KW_TeletexString
:
480 case KW_UniversalString
:
482 case KW_VideotexString
:
483 case KW_VisibleString
:
484 case KW_ISO646String
:
485 case KW_RELATIVE_OID
:
488 case KW_GeneralizedTime
:
490 case KW_ObjectDescriptor
:
495 if(tb
->get_at(pos2
)->get_token()==KW_STRING
) {
497 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
503 if(tb
->get_at(pos2
)->get_token()==KW_STRING
)
510 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
516 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
519 if(tb
->get_at(pos2
)->get_token()==KW_SIZE
)
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;
530 if(tb
->get_at(pos2
)->get_token()==KW_IDENTIFIER
)
535 if(tb
->get_at(pos2
)->get_token()==KW_STRING
)
540 if(tb
->get_at(pos2
)->get_token()==KW_PDV
)
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
553 pos2
=is_ref(pos
)+pos2
;
557 size_t OCSV_Parser::is_type(size_t pos
)
559 size_t pos2
=pos
, pos3
;
560 while((pos3
=is_tag(pos2
)))
562 pos2
+=is_nakedtype(pos2
);
563 pos2
+=is_constraints(pos2
);
567 size_t OCSV_Parser::is_value(size_t pos
)
570 switch(tb
->get_at(pos2
)->get_token()) {
580 case KW_PLUS_INFINITY
:
581 case KW_MINUS_INFINITY
:
586 if(tb
->get_at(pos2
)->get_token()==TOK_Number
587 || tb
->get_at(pos2
)->get_token()==TOK_RealNumber
)
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;
599 pos2
=is_ref(pos
)+pos
;
603 size_t OCSV_Parser::is_object(size_t pos
)
606 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
609 pos2
=is_ref(pos
)+pos
;
613 size_t OCSV_Parser::is_objectset(size_t pos
)
616 if(tb
->get_at(pos2
)->get_token()==TOK_Block
)
621 Block
* OCSV_Parser::get_first_n(size_t n
)
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
);
631 Type
* OCSV_Parser::parse_type()
636 Block
*block
=get_first_n(n
);
637 Node
*node
=block
->parse(KW_Block_Type
);
639 Type
*new_type
=dynamic_cast<Type
*>(node
);
641 new_type
=new Type(Type::T_ERROR
);
645 Value
* OCSV_Parser::parse_value()
650 Block
*block
=get_first_n(n
);
651 Node
*node
=block
->parse(KW_Block_Value
);
653 Value
*new_value
=dynamic_cast<Value
*>(node
);
655 new_value
=new Value(Value::V_ERROR
);
659 Object
* OCSV_Parser::parse_object()
664 Block
*block
=get_first_n(n
);
665 Node
*node
=block
->parse(KW_Block_Object
);
667 Object
*new_object
=dynamic_cast<Object
*>(node
);
669 new_object
=new Obj_defn();
673 ObjectSet
* OCSV_Parser::parse_objectset()
678 Block
*block
=get_first_n(n
);
679 Node
*node
=block
->parse(KW_Block_ObjectSet
);
681 ObjectSet
*new_objectset
=dynamic_cast<ObjectSet
*>(node
);
683 new_objectset
=new OS_defn();
684 return new_objectset
;
This page took 0.061135 seconds and 6 git commands to generate.