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 ///////////////////////////////////////////////////////////////////////////////
20 * This namespace contains things related to ASN.1 compiler.
32 * This is used when parsing internal stuff (e.g., EXTERNAL,
33 * EMBEDDED PDV, etc.).
35 extern Assignments *parsed_assignments;
37 using namespace Common;
55 /* not defined, only declared in this file */
65 * Struct to represent default tagging.
69 EXPLICIT, /**< EXPLICIT TAGS */
70 IMPLICIT, /**< IMPLICIT TAGS */
71 AUTOMATIC /**< AUTOMATIC TAGS */
76 * Helper-class for parameterized assignments.
78 class Ass_pard : public Node {
80 Assignment *my_ass; // link to...
81 Block *parlist_block; /**< parameter list */
82 /** if the block (parlist) is pre-parsed then it is deleted, and
83 * the content is put into these vectors. */
84 vector<Identifier> dummyrefs;
85 /** contains one tokenbuf for each parameter; e.g. for parameter
86 * "INTEGER : i" it contains "i INTEGER ::=" */
87 vector<TokenBuf> governors;
88 /** Instance counters: for each target module a separate counter is
89 * maintained to get deterministic instance numbers in case of incremental
91 map<Common::Module*, size_t> inst_cnts;
93 Ass_pard(const Ass_pard& p);
94 Ass_pard& operator=(const Ass_pard& p);
95 /** Split the formal parameterlist */
98 Ass_pard(Block *p_parlist_block);
100 virtual Ass_pard* clone() const
101 {return new Ass_pard(*this);}
102 void set_my_ass(Assignment *p_my_ass) {my_ass=p_my_ass;}
103 /** Returns the number of formal parameters. 0 means the parameter
104 * list is erroneous. */
105 size_t get_nof_pars();
106 const Identifier& get_nth_dummyref(size_t i);
107 TokenBuf* clone_nth_governor(size_t i);
108 /** Returns the next instance number for target module \a p_mod */
109 size_t new_instnum(Common::Module *p_mod);
113 * Abstract class to represent different kinds of assignments.
115 class Assignment : public Common::Assignment {
116 protected: // many classes derived
120 Assignment(const Assignment& p);
121 Assignment& operator=(const Assignment& p);
122 virtual string get_genname() const;
123 virtual Assignment* new_instance0();
125 Assignment(asstype_t p_asstype, Identifier *p_id, Ass_pard *p_ass_pard);
126 virtual ~Assignment();
127 virtual Assignment* clone() const =0;
128 virtual bool is_asstype(asstype_t p_asstype, ReferenceChain* refch=0);
129 virtual void set_right_scope(Scope *p_scope) =0;
130 void set_dontgen() {dontgen=true;}
131 /** Returns 0 if assignment is not parameterized! */
132 virtual Ass_pard* get_ass_pard() const { return ass_pard; }
133 /** Returns 0 if this assignment is not parameterized! */
134 Assignment* new_instance(Common::Module *p_mod);
135 virtual Type* get_Type();
136 virtual Value* get_Value();
137 virtual ValueSet* get_ValueSet();
138 virtual ObjectClass* get_ObjectClass();
139 virtual Object* get_Object();
140 virtual ObjectSet* get_ObjectSet();
142 virtual void dump(unsigned level) const;
146 * Class to store assignments. It also contains the ASN-related
147 * pre-defined (so-called "useful") stuff.
149 class Assignments : public Common::Assignments {
151 /** Special assignments. */
152 static Module *_spec_asss;
154 static void create_spec_asss();
155 static void destroy_spec_asss();
156 /** Returns whether module \a p_mod is the module that contains the
157 * special assignments */
158 static bool is_spec_asss(Common::Module *p_mod);
160 /** The assignments. */
161 map<string, Assignment> asss_m;
162 vector<Assignment> asss_v;
163 /** Indicates whether the uniqueness of identifiers has been checked. */
166 Assignments(const Assignments&);
169 Assignments() : Common::Assignments(), asss_m(), asss_v(), checked(false)
172 virtual ~Assignments();
173 virtual Assignments* clone() const;
174 /** Sets the fullname. */
175 virtual void set_fullname(const string& p_fullname);
176 /** Also looks into special assignments. */
177 virtual bool has_local_ass_withId(const Identifier& p_id);
178 /** Also looks into special assignments. */
179 virtual Assignment* get_local_ass_byId(const Identifier& p_id);
180 virtual size_t get_nof_asss();
181 virtual Common::Assignment* get_ass_byIndex(size_t p_i);
182 /** Adds the Assignment. If \a checked flag is true and the id of the new
183 * assignment is not unique it reports the error. */
184 void add_ass(Assignment *p_ass);
185 /** Checks the uniqueness of identifiers. */
187 /** Checks all assignments. */
189 /** Sets the scope for the right side of assignments. Used in
190 * parametrization. There is a strange situation that the left
191 * and right sides of assignments can have different parent
193 void set_right_scope(Scope *p_scope);
194 void generate_code(output_struct* target);
195 void generate_code(CodeGenHelper& cgh);
196 void dump(unsigned level) const;
200 * Class to represent ASN-modules.
202 class Module : public Common::Module {
204 /** default tagging */
205 TagDefault::tagdef_t tagdef;
206 /** extensibility implied */
208 /** exported stuff */
210 /** imported stuff. */
212 /** assignments of the module */
215 /** Copy constructor not implemented. */
216 Module(const Module&);
217 /** Assignment not implemented */
218 Module& operator=(const Module&);
220 Module(Identifier *p_modid, TagDefault::tagdef_t p_tagdef,
221 bool p_extens_impl, Exports *p_exp, Imports *p_imp,
222 Assignments *p_asss);
224 virtual Module* clone() const;
225 virtual Common::Assignment* importAssignment(
226 const Identifier& p_source_modid, const Identifier& p_id) const;
227 /** Sets the fullname. */
228 virtual void set_fullname(const string& p_fullname);
229 virtual Common::Assignments* get_scope_asss();
230 virtual bool has_imported_ass_withId(const Identifier& p_id);
231 /** Returns the assignment referenced by p_ref. Appends an error
232 * message an returns 0 if assignment is not found. */
233 virtual Common::Assignment* get_ass_bySRef(Ref_simple *p_ref);
234 virtual Assignments *get_asss();
235 virtual bool exports_sym(const Identifier& p_id);
236 virtual void chk_imp(ReferenceChain& refch, vector<Common::Module>& moduleStack);
239 virtual void get_imported_mods(module_set_t& p_imported_mods);
240 virtual bool has_circular_import();
241 virtual void generate_code_internal(CodeGenHelper& cgh);
243 virtual void dump(unsigned level) const;
244 void add_ass(Assignment *p_ass);
245 TagDefault::tagdef_t get_tagdef() const { return tagdef; }
247 /** Generates JSON schema segments for the types defined in the modules,
248 * and references to these types.
250 * @param json JSON document containing the main schema, schema segments for
251 * the types will be inserted here
252 * @param json_refs map of JSON documents containing the references to each type */
253 virtual void generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs);
258 * Used only while parsing a module (and building the AST).
260 class Symbols : public Node {
261 friend class Exports;
263 friend class Imports;
265 /** string => Identifier container */
266 typedef map<string, Identifier> syms_t;
267 /** temporary container for symbols (no uniqueness checks) */
268 vector<Identifier> syms_v;
272 /** Copy constructor not implemented. */
273 Symbols(const Symbols&);
274 /** Assignment not implemented. */
275 Symbols& operator=(const Symbols&);
277 /** Default constructor. */
278 Symbols() : Node(), syms_v(), syms_m() { }
281 /** Not implemented. */
282 virtual Symbols* clone() const;
283 /** Adds \a p_id to the symlist. */
284 void add_sym(Identifier *p_id);
285 /** Ensures uniqueness of identifiers in syms */
286 void chk_uniq(const Location& p_loc);
290 * Exported symbols of a module.
292 class Exports : public Node, public Location {
295 /** string => Identifier container */
300 /** exported symbols */
303 /** Copy constructor not implemented. */
304 Exports(const Exports&);
305 /** Assignment not implemented */
306 Exports& operator=(const Exports&);
308 /** Constructor used when the module exports all. */
309 Exports(bool p_expall=false);
310 /** Constructor used when there is a SymbolList. */
311 Exports(Symbols *p_symlist);
314 /** Not implemented. */
315 virtual Exports* clone() const;
316 /** Sets the internal pointer to its module. */
317 void set_my_mod(Module *p_mod) {my_mod=p_mod;}
318 /** Returns true if a symbol with identifier \a p_id is
320 bool exports_sym(const Identifier& p_id);
321 /** Checks whether the exported symbols are defined in the module. */
328 class ImpMod : public Node, public Location {
329 friend class Imports;
333 /** identifier of imported module */
335 /** pointer to the imported module */
337 /** imported symbols */
340 /** Copy constructor not implemented. */
341 ImpMod(const ImpMod&);
342 /** Assignment not implemented */
343 ImpMod& operator=(const ImpMod&);
346 ImpMod(Identifier *p_modid, Symbols *p_symlist);
349 /** Not implemented. */
350 virtual ImpMod* clone() const;
351 /** Sets the internal pointer to its module. */
352 void set_my_mod(Module *p_mod) {my_mod=p_mod;}
353 /** Gets the module id of imported module. */
354 const Identifier& get_modid() const {return *modid;}
355 void set_mod(Common::Module *p_mod) { mod = p_mod; }
356 Common::Module *get_mod() const { return mod; }
357 bool has_sym(const Identifier& p_id) const;
358 /** Checks whether the imported symbols exist. Appends error
359 * messages when needed. */
360 void chk_imp(ReferenceChain& refch);
361 void generate_code(output_struct *target);
367 class Imports : public Node, public Location {
372 /** imported modules */
373 vector<Asn::ImpMod> impmods_v;
374 map<string, Asn::ImpMod> impmods;
375 /** these symbols are mentioned only once in IMPORTS */
376 map<string, Common::Module> impsyms_1;
377 /** these symbols are mentioned more than once in IMPORTS. This
378 * map is used as a set. */
379 map<string, void> impsyms_m;
380 /** Indicates whether the import list has been checked. */
382 /** Indicates whether the owner module is a part of a circular import
386 /** Copy constructor not implemented. */
387 Imports(const Imports&);
388 /** Assignment not implemented */
389 Imports& operator=(const Imports&);
393 : Node(), my_mod(0), impmods_v(), impmods(), impsyms_1(), impsyms_m(),
394 checked(false), is_circular(false) {}
397 /** Not implemented. */
398 virtual Imports* clone() const;
399 /** Adds the ImpMod. If a module with that id already exists,
400 * throws an Error_AST_uniq exception. */
401 void add_impmod(ImpMod *p_impmod);
402 /** Sets the internal pointer my_mod to \a p_mod. */
403 void set_my_mod(Module *p_mod);
404 /** Recursive check. Checks whether the modules with the id exist,
405 * then checks that ImpMod. */
406 void chk_imp(ReferenceChain& refch);
407 /** Returns whether symbols from module with identifier \a p_id
409 bool has_impmod_withId(const Identifier& p_id) const
410 { return impmods.has_key(p_id.get_name()); }
411 const ImpMod *get_impmod_byId(const Identifier& p_id) const
412 { return impmods[p_id.get_name()]; }
413 /** Returns whether a symbol with identifier \a p_id is imported from one
415 bool has_impsym_withId(const Identifier& p_id) const;
416 void get_imported_mods(Module::module_set_t& p_imported_mods);
417 bool get_is_circular() const { return is_circular; }
418 void generate_code(output_struct *target);
422 * Undefined assignment.
424 class Ass_Undef : public Assignment {
428 /** the classified assignment */
431 void classify_ass(ReferenceChain *refch=0);
432 virtual Assignment* new_instance0();
433 Ass_Undef(const Ass_Undef& p);
434 /// Assignment disabled
435 Ass_Undef& operator=(const Ass_Undef& p);
437 Ass_Undef(Identifier *p_id, Ass_pard *p_ass_pard,
438 Node *p_left, Node *p_right);
439 virtual ~Ass_Undef();
440 virtual Assignment* clone() const;
441 virtual asstype_t get_asstype() const;
442 virtual void set_fullname(const string& p_fullname);
443 virtual void set_my_scope(Scope *p_scope);
444 virtual void set_right_scope(Scope *p_scope);
445 virtual bool is_asstype(asstype_t p_asstype, ReferenceChain* refch=0);
446 virtual Ass_pard* get_ass_pard() const;
447 virtual Setting* get_Setting();
448 virtual Type* get_Type();
449 virtual Value* get_Value();
450 virtual ValueSet* get_ValueSet();
451 virtual ObjectClass* get_ObjectClass();
452 virtual Object* get_Object();
453 virtual ObjectSet* get_ObjectSet();
455 virtual void generate_code(output_struct *target, bool clean_up = false);
456 virtual void generate_code(CodeGenHelper& cgh);
457 virtual void dump(unsigned level) const;
459 bool _error_if_pard();
463 * Erroneous assignment.
465 class Ass_Error : public Assignment {
467 Setting *setting_error;
471 /// Copy constructor not implemented (even though clone works)
472 Ass_Error(const Ass_Error& p);
473 /// Assignment disabled
474 Ass_Error& operator=(const Ass_Error& p);
475 virtual Assignment* new_instance0();
477 Ass_Error(Identifier *p_id, Ass_pard *p_ass_pard);
478 virtual ~Ass_Error();
479 virtual Assignment* clone() const;
480 virtual bool is_asstype(asstype_t p_asstype, ReferenceChain* refch=0);
481 virtual void set_right_scope(Scope *) {}
482 virtual Setting* get_Setting();
483 virtual Type* get_Type();
484 virtual Value* get_Value();
485 virtual ValueSet* get_ValueSet();
486 virtual ObjectClass* get_ObjectClass();
487 virtual Object* get_Object();
488 virtual ObjectSet* get_ObjectSet();
490 virtual void dump(unsigned level) const;
496 class Ass_T : public Assignment {
500 virtual Assignment* new_instance0();
501 /// Copy constructor for clone() only
502 Ass_T(const Ass_T& p);
503 /// Assignment disabled
504 Ass_T& operator=(const Ass_T& p);
506 Ass_T(Identifier *p_id, Ass_pard *p_ass_pard, Type *p_right);
508 virtual Ass_T* clone() const
509 {return new Ass_T(*this);}
510 virtual void set_fullname(const string& p_fullname);
511 virtual void set_my_scope(Scope *p_scope);
512 virtual void set_right_scope(Scope *p_scope);
513 virtual Setting* get_Setting() {return get_Type();}
514 virtual Type* get_Type();
516 virtual void generate_code(output_struct *target, bool clean_up = false);
517 virtual void generate_code(CodeGenHelper& cgh);
518 virtual void dump(unsigned level) const;
524 class Ass_V : public Assignment {
529 virtual Assignment* new_instance0();
530 /// Copy constructor for clone() only
531 Ass_V(const Ass_V& p);
532 /// Assignment disabled
533 Ass_V& operator=(const Ass_V& p);
535 Ass_V(Identifier *p_id, Ass_pard *p_ass_pard,
536 Type *p_left, Value *p_right);
538 virtual Ass_V* clone() const
539 {return new Ass_V(*this);}
540 virtual void set_fullname(const string& p_fullname);
541 virtual void set_my_scope(Scope *p_scope);
542 virtual void set_right_scope(Scope *p_scope);
543 virtual Setting* get_Setting() {return get_Value();}
544 virtual Type* get_Type();
545 virtual Value* get_Value();
547 virtual void generate_code(output_struct *target, bool clean_up = false);
548 virtual void generate_code(CodeGenHelper& cgh);
549 virtual void dump(unsigned level) const;
553 * ValueSet assignment.
555 class Ass_VS : public Assignment {
561 virtual Assignment* new_instance0();
562 /// Copy constructor for clone() only
563 Ass_VS(const Ass_VS& p);
564 /// Assignment disabled
565 Ass_VS& operator=(const Ass_VS& p);
567 Ass_VS(Identifier *p_id, Ass_pard *p_ass_pard,
568 Type *p_left, Block *p_right);
570 virtual Ass_VS* clone() const
571 {return new Ass_VS(*this);}
572 virtual void set_fullname(const string& p_fullname);
573 virtual void set_my_scope(Scope *p_scope);
574 virtual void set_right_scope(Scope *p_scope);
575 virtual Setting* get_Setting() {return get_Type();}
576 virtual Type* get_Type();
578 virtual void generate_code(output_struct *target, bool clean_up = false);
579 virtual void generate_code(CodeGenHelper& cgh);
580 virtual void dump(unsigned level) const;
584 * ObjectClass assignment.
586 class Ass_OC : public Assignment {
590 virtual Assignment* new_instance0();
591 /// Copy constructor for clone() only
592 Ass_OC(const Ass_OC& p);
593 /// Assignment disabled
594 Ass_OC& operator=(const Ass_OC& p);
596 Ass_OC(Identifier *p_id, Ass_pard *p_ass_pard, ObjectClass *p_right);
598 virtual Ass_OC* clone() const
599 {return new Ass_OC(*this);}
600 virtual void set_fullname(const string& p_fullname);
601 virtual void set_my_scope(Scope *p_scope);
602 virtual void set_right_scope(Scope *p_scope);
604 virtual Setting* get_Setting() {return get_ObjectClass();}
605 virtual ObjectClass* get_ObjectClass();
606 virtual void generate_code(output_struct *target, bool clean_up = false);
607 virtual void generate_code(CodeGenHelper& cgh);
608 virtual void dump(unsigned level) const;
614 class Ass_O : public Assignment {
619 virtual Assignment* new_instance0();
620 /// Copy constructor for clone() only
621 Ass_O(const Ass_O& p);
622 /// Assignment disabled
623 Ass_O& operator=(const Ass_O& p);
625 Ass_O(Identifier *p_id, Ass_pard *p_ass_pard,
626 ObjectClass *p_left, Object *p_right);
628 virtual Ass_O* clone() const
629 {return new Ass_O(*this);}
630 virtual void set_fullname(const string& p_fullname);
631 virtual void set_my_scope(Scope *p_scope);
632 virtual void set_right_scope(Scope *p_scope);
633 virtual Setting* get_Setting() {return get_Object();}
634 //virtual ObjectClass* get_ObjectClass();
635 virtual Object* get_Object();
637 virtual void generate_code(output_struct *target, bool clean_up = false);
638 virtual void generate_code(CodeGenHelper& cgh);
639 virtual void dump(unsigned level) const;
643 * ObjectSet assignment.
645 class Ass_OS : public Assignment {
650 virtual Assignment* new_instance0();
651 /// Copy constructor for clone() only
652 Ass_OS(const Ass_OS& p);
653 /// Assignment disabled
654 Ass_OS& operator=(const Ass_OS& p);
656 Ass_OS(Identifier *p_id, Ass_pard *p_ass_pard,
657 ObjectClass *p_left, ObjectSet *p_right);
659 virtual Ass_OS* clone() const
660 {return new Ass_OS(*this);}
661 virtual void set_fullname(const string& p_fullname);
662 virtual void set_my_scope(Scope *p_scope);
663 virtual void set_right_scope(Scope *p_scope);
664 virtual Setting* get_Setting() {return get_ObjectSet();}
665 //virtual ObjectClass* get_ObjectClass();
666 virtual ObjectSet* get_ObjectSet();
668 virtual void generate_code(output_struct *target, bool clean_up = false);
669 virtual void generate_code(CodeGenHelper& cgh);
670 virtual void dump(unsigned level) const;
673 /** @} end of AST group */
677 #endif // _Asn_AST_HH