Files CCore/inc/ddl/DDLEngine.h CCore/src/ddl/DDLEngine.cpp
Files CCore/inc/ddl/DDLMap.h CCore/src/ddl/DDLMap.cpp
Files CCore/inc/ddl/DDLTypedMap.h CCore/src/ddl/DDLTypeMap.cpp
Files CCore/inc/ddl/DDLPlatformTypes.h CCore/src/ddl/DDLPlatformTypes.cpp
Files CCore/inc/ddl/DDLMapTypes.h CCore/src/ddl/DDLMapTypes.cpp
Files CCore/inc/ddl/DDLMapBase.h CCore/src/ddl/DDLMapBase.cpp
Subfolders CCore/inc/ddl CCore/src/ddl
The directory ddl contains a DDL implementation. It is contained in the namespace DDL. To process a DDL source there are two main classes: TextEngine and FileEngine. The most of content of this directory is a DDL2 parser implementation and not needed to be used directly.
Engines return the result of processing of the following type:
struct EngineResult
{
EvalResult *eval;
BodyNode *body;
EngineResult() : eval(0),body(0) {}
EngineResult(NothingType) : EngineResult() {}
EngineResult(EvalResult *eval_,BodyNode *body_) : eval(eval_),body(body_) {}
EvalResult * operator + () const { return eval; }
bool operator ! () const { return !eval; }
};
It's a simple lightweight data structure with two fields. eval is a pointer to the EvalResult object, this object contains constant value table. body is a pointer to the root body node, this node represents the DDL source. Walking from this node you can examine the whole source content. If the processing has failed, the result is null.
class TextEngine : NoCopy
{
....
public:
TextEngine(PrintBase &msg,StrLen text,StrLen pretext=Empty);
~TextEngine();
EngineResult process();
};
The first constructor argument is a stream, where error messages will be printed to. The second is a text to be processed. The third is a "pretext". It is included before the text. To do the job use the method process(). This engine does not support the file inclusion. This engine is one-shoot, it should be used to process one input once. Result objects life-time is ended with the engine life-time end.
template <class FileName,class FileText>
class FileEngine : NoCopy
{
....
public:
static const ulen DefaultMaxFiles = 1000 ;
static const ulen DefaultMaxIncludes = 100 ;
static const ulen DefaultMaxFileLen = MaxULen ;
explicit FileEngine(PrintBase &msg,ulen mem_cap=MaxULen,
ulen max_files=DefaultMaxFiles,
ulen max_inc=DefaultMaxIncludes,
ulen max_file_len=DefaultMaxFileLen);
~FileEngine();
EngineResult process(StrLen file_name,StrLen pretext);
EngineResult process(StrLen file_name);
};
FileEngine can process a complex input from a real or a virtual file system. Two template parameters controls the file name processing and the file name to the file content mapping. The first constructor argument is a error report stream. Others are different engine limits. The method process() does the job. The first argument is a file name with a DDL text. Additional files may be opened during include operations. The second argument is a "pretext". It is included before the file text. The method process() can be called multiple times for different files. Loaded files are cached. Result objects life-time is ended with the next call of process(), or with the engine life-time end.
The first template parameter FileName is responsible for the file name manipulation. There is a default implementation of this class. It is recommended to use this implementation. Any other implementation must be interface compatible with this particular one.
The second template parameter must do the same thing as the FileToMem class, i.e. load the file content into the memory.
class FileText : NoCopy
{
public:
FileText(StrLen file_name,ulen max_len);
~FileText();
const uint8 * getPtr() const;
ulen getLen() const;
};
On HCore targets you can use the class FileToMem as the FileText template parameter.
struct EvalResult : NoCopy
{
DynArray<ConstResult> const_table;
DynArray<LenResult> len_table;
EvalResult() {}
void erase();
ulen_type getLen(const LenNode &node) const;
};
EvalResult contains two tables. Each constant, defined in the DDL2 source, has an associated ConstNode object. This object contains the field index. The entry in the const_table with this index contains the calculated value of the constant. Each array type with an explicit array length has an associated LenNode object. This object contains the field index. The entry in the len_table with this index contains the calculated value of the length.
struct ConstResult
{
TypeNode *type;
ConstNode *node;
Value value;
void set(ConstNode *node,const Value &value);
struct PrintOptType
{
EvalResult &result;
PrintOptType(EvalResult &result_) : result(result_) {}
};
template <class P>
void print(P &out,PrintOptType opt) const;
};
ConstResult contains three fields. type is a TypeNode pointer, node is a ConstNode pointer, value is the calculated constant value. This class is printable. To print you must provide the option, bounded to the original EvalResult object.
struct LenResult
{
LenNode *node;
ulen_type value;
void set(LenNode *node,ulen_type value);
template <class P>
void print(P &out) const;
};
LenResult contains two fields. node is a LenNode pointer, value is the calculated length value.
struct LenNode { .... ulen index; }; struct ConstNode { .... ScopeNode *parent; ulen depth; NameIdNode name; ulen index; }; struct ScopeNode { .... ScopeNode *parent; NameIdNode name; }; struct NameIdNode { .... PosName name; StrLen getStr() const { return name.str; } };
All LenNodes are zero-based indexed. The correspondent index is assigned to the index field.
All ConstNodes are zero-based indexed. The correspondent index is assigned to the index field. ConstNode contains also the filed name with its name and the field parent with the pointer to the ScopeNode which it belongs to. depth is the scope depth.
ScopeNode has the field parent with the pointer to the ScopeNode which it belongs to. It also has the field name with the scope name.
NameIdNode has the method getStr(). This method returns the name of the item.
union Value
{
imp_sint8 val_sint8;
imp_uint8 val_uint8;
imp_sint16 val_sint16;
imp_uint16 val_uint16;
imp_sint32 val_sint32;
imp_uint32 val_uint32;
imp_sint64 val_sint64;
imp_uint64 val_uint64;
imp_sint val_sint;
imp_uint val_uint;
imp_ulen val_ulen;
SLen val_slen;
Text val_text;
IP val_ip;
Block val_block;
Ptr val_ptr;
// methods
template <class Type>
Type get() const;
template <class Type>
void set(Type val);
};
Value is a union of different types. The actual member depends on the value type. You may use get<Type>() and set<Type>() methods to get and set values.
To represent integral types imp_XXX are used.
struct imp_XXX { XXX_integral_type value; .... };
Integral types are: sint8, uint8, ... and sint_type, uint_type, ulen_type. Last three types are platform-dependent.
Text represents text type.
struct Text
{
StrLen str;
// constructors
Text() {}
Text(StrLen str_) : str(str_) {}
// print object
template <class P>
void print(P &out) const;
};
IP represents ip type.
struct IP
{
uint8 address[4];
// constructors
IP() : address{} {}
IP(uint8 a1,uint8 a2,uint8 a3,uint8 a4) : address{a1,a2,a3,a4} {}
// methods
uint32 toInt() const;
// print object
template <class P>
void print(P &out) const;
};
Non-scalar values, like structures and arrays, are represented using the type Block.
struct Block
{
PtrLen<Value> data;
....
};
Each member of the range data is the value of the correspondent element of aggregate.
Pointer values are represented using the type Ptr.
struct Ptr { PtrNode *ptr_node; bool null; .... }; struct PtrNode { PtrNode *parent; ulen_type index; TypeNode *type; .... };
The field ptr_node points to the PtrNode object. This object contains three fields. type describes the type of the pointee constant or sub-constant. If this constant is a full constant, then parent is null and index is the ConstNode index. Otherwise parent represents the aggregate, the sub-constant is an element of, and index is the aggregate element index.
If the pointer is a null pointer of some type, then the field null is true and ptr_node->type describes the type.
struct TypeNode
{
struct Base
{
enum Type
{
Type_none = 0,
Type_sint,
Type_uint,
Type_ulen,
Type_sint8,
Type_uint8,
Type_sint16,
Type_uint16,
Type_sint32,
Type_uint32,
Type_sint64,
Type_uint64,
Type_text,
Type_ip,
TypeIntMin=Type_sint,
TypeIntMax=Type_uint64
};
Type type;
explicit Base(Type type_) : type(type_) {}
bool isIntegral() const { return type && type<Type_text ; }
bool isText() const { return type==Type_text; }
bool isIP() const { return type==Type_ip; }
};
struct Ref
{
AnyPtr<AliasNode,StructNode> ptr;
....
};
struct Ptr
{
TypeNode *type_node;
....
};
struct PolyPtr
{
TypeList *type_list;
....
};
struct Array
{
TypeNode *type_node;
....
};
struct ArrayLen
{
TypeNode *type_node;
LenNode len_node;
....
};
struct Struct
{
StructNode *struct_node;
....
};
AnyPtr<Base,Ref,Ptr,PolyPtr,Array,ArrayLen,Struct> ptr;
....
};
TypeNode is used to represent a type. Different type classes are encoded using AnyPtr field ptr. For example, to encode the type uint8, ptr is initialized by the pointer to the object of type TypeNode::Base and the field type of this object has the value TypeNode::Base::Type_uint8.
struct AliasNode
{
....
TypeNode *type_node;
TypeNode *result_type; // don't point to TypeNode Ref with another alias
};
AliasNode repesents a type declaration. The field result_type points to some "resulting" TypeNode, this node represents the aliased type and is not a Ref node with another AliasNode.
struct StructNode
{
....
ScopeNode scope_node;
ForwardList<FieldNode> field_list;
ulen dep_index;
};
StructNode represents a structure declaration. The field scope_node represents the correspondent scope. The field field_list is the list of structure fields. dep_index is a zero-based index of the structure. These indexes respect structure dependencies: if the structure A has a filed of the structure type B (or B[] or B[Len]), then the dep_index of the B is less than the dep_index of the A.
struct FieldNode
{
....
FieldNode *next;
NameIdNode name;
TypeNode *type_node;
ulen index;
ulen field_index;
};
FieldNode describes a structure field. index is a zero-based field index among all fields of all structures. field_index is a zero-based field index of this particular structure. name describes the field name and type_node — the field type.
/* struct TypeListNode */ struct TypeListNode { .... TypeListNode *prev; TypeNode *type_node; }; /* type TypeList */ using TypeList = CountList<TypeListNode> ;
These entities are used to represent a type list.
The best way to deal with a DDL processing result is to map it into a block of memory. The class Map is to do it.
class Map : NoCopy
{
....
public:
explicit Map(EngineResult result);
~Map();
ulen getLen() const;
void operator () (void *mem);
bool findStruct(StrLen name,const TypeDesc &desc);
void * findConst(StrLen name,const TypeDesc &desc);
};
You create an object of the type Map, providing the EngineResult as the argument. Then you have to allocate an aligned block of memory of the length getLen(). Once it's done, use the overloaded operator () to map data into this memory block. You may destroy the Map object and the Engine object at this point and keep the memory block as long as required. To find a particular constant you can use the method findConst() with the constant name and type, encoded using the class TypeDesc. If there is no such constant or types mismatch then null is returned. Otherwise the pointer to the mapped value is returned.
There is a simple helper class MapBase to help with the memory allocation for a Map object (the actual implementation is slightly different):
class MapBase : NoCopy
{
void *mem;
public:
template <class Map>
explicit MapBase(Map &map)
{
mem=MemAlloc(map.getLen());
map(mem);
}
~MapBase()
{
MemFree(mem);
}
};
/* consts */ enum TypeTag { // basic TypeTag_sint, // sint_type TypeTag_uint, // uint_type TypeTag_ulen, // ulen_type TypeTag_sint8, // sint8 TypeTag_uint8, // uint8 TypeTag_sint16, // sint16 TypeTag_uint16, // uint16 TypeTag_sint32, // sint32 TypeTag_uint32, // uint32 TypeTag_sint64, // sint64 TypeTag_uint64, // uint64 TypeTag_text, // StrLen TypeTag_ip, // uint32 // other TypeTag_ptr, // DataPtr TypeTag_polyptr, // TypedDataPtr TypeTag_array, // ArrayPtr -> elem[len] TypeTag_array_len, // elem[len] TypeTag_array_getlen, // elem[len] TypeTag_struct, // {field1,field2,...} // none TypeTag_none, // int TypeTag_int = TypeTag_sint }; /* struct TypeDesc */ struct TypeDesc { const TypeTag tag; explicit TypeDesc(const TypeTag tag_) : tag(tag_) {} };
TypeDesc, in fact, is a base class for the family of derived classes, designed to represent different type classes. The field tag has a describing type value, and derived classes has additional fields with extra information if required.
struct TypeDesc_basic : TypeDesc
{
explicit TypeDesc_basic(TypeTag tag);
};
This class is to represent basic types. You provide in constructor argument the correspondent type tag.
struct TypeDesc_ptr : TypeDesc
{
const TypeDesc &type;
explicit TypeDesc_ptr(const TypeDesc &type);
};
This class represents single type pointers. You provide in constructor argument the type descriptor.
template <ulen TypeCount>
struct TypeDesc_polyptr : TypeDesc_polyptr_base
{
const Type buf[TypeCount];
template <class ... TT>
explicit TypeDesc_polyptr(const TT & ... tt);
};
This class represents polymorphic pointer types. You provide in constructor arguments a list of type descriptors. TypeCount is a number of types.
struct TypeDesc_array : TypeDesc
{
const TypeDesc &type;
explicit TypeDesc_array(const TypeDesc &type);
};
This class represents array types without length. You provide in constructor argument the element type descriptor.
struct TypeDesc_array_len : TypeDesc
{
const TypeDesc &type;
const ulen_type len;
TypeDesc_array_len(const TypeDesc &type,ulen_type len);
};
This class represents array types with a given length. You provide in constructor arguments the element type descriptor and the array length.
struct TypeDesc_array_getlen : TypeDesc
{
const TypeDesc &type;
mutable ulen_type len; // filled by findConst() method
explicit TypeDesc_array_getlen(const TypeDesc &type);
};
This class represents array types with a given length. You provide in constructor argument the element type descriptor. But the actual array length is filled by the method findConst(). This descriptor must participate in findConst() directly or indirectly to be used later.
template <ulen FieldCount>
struct TypeDesc_struct : TypeDesc_struct_base
{
const Field buf[FieldCount];
template <class ... TT>
explicit TypeDesc_struct(const TT & ... tt);
};
This class represents structure types. You provide in constructor arguments a list of field type descriptors. FieldCount is a number of fields. This structure has some internal fields, these fields are filled by the method findConst(). This descriptor must participate in findConst() directly or indirectly to be used later.
DataPtr is a helper class. It is a "universal pointer" class. You may initialize an object of this type by the value, returned by the method findConst().
struct DataPtr
{
void *ptr;
// constructors
DataPtr() : ptr(0) {}
DataPtr(void *ptr_) : ptr(ptr_) {}
// methods
void * operator + () const { return ptr; }
bool operator ! () const { return !ptr; }
struct Proxy
{
void *ptr;
Proxy(void *ptr_) : ptr(ptr_) {}
template <class T>
operator T() const;
};
Proxy operator * () const { return ptr; }
DataPtr elem(const TypeDesc_struct_base &desc,ulen ind) const;
DataPtr select(const TypeDesc_struct_base &desc,ulen ind) const;
struct ProxyRange
{
void *ptr;
ulen len;
ProxyRange(void *ptr_,ulen len_) : ptr(ptr_),len(len_) {}
template <class T>
operator PtrLen<T>() const;
};
ProxyRange range(ulen len) const { return ProxyRange(ptr,len); }
};
Then you may use this object to get the constant value. Use the operator * and assign the result to the variable of the proper type. You may find the proper type in the TypeTag definition above.
You cannot use the operator *, however, if the constant type is a structure or an array with length. For structure types you may use the method select() to create a DataPtr to the desired field. The first argument is a structure type descriptor, the second is the zero-based field index. The descriptor contains inside some internal values, filled by the method findConst() to locate a particular field.
If the constant type is an array without length, you can cast to the type ArrayPtr, but you can also use the type PtrLen<T>, where the type T corresponds to the element type. Again, you cannot do it, if the element type is a structure or an array with length.
struct ArrayPtr
{
void *ptr;
ulen len;
ArrayPtr() : ptr(0),len(0) {}
ArrayPtr(void *ptr_,ulen len_) : ptr(ptr_),len(len_) {}
};
This structure holds a pointer to the first element of the array and the number of the array elements. You may initialize an object of type DataPtr from this pointer.
If a DataPtr object corresponds to an array with length, you may use the method range() to build a PtrLen<T> object to access array elements. Just cast the return value to the proper range type. The element type cannot be a structure or array with length in this case.
To deal with an array of structures, use the method elem(). It returns a pointer to the element with the given index. You must provide the structure descriptor.
This class is used to deal with polymorphic pointers. It inherits the type DataPtr and has the additional field type. The value of this field is a 1-based index of the pointer type from the type list. It is zero if the pointer is a typeless null.
struct TypedDataPtr : DataPtr
{
ulen type; // 1-based type index
// constructors
TypedDataPtr() : type(0) {}
TypedDataPtr(void *ptr,ulen type_) : DataPtr(ptr),type(type_) {}
};
The most convenient way to map DDL data is the class TypedMap. But with this class you are bounded by the given set of DDL structure types. These type set is represented by the template parameter TypeSet. You should use the utility DDLTypeSet to generate the definition of this class from the DDL source.
template <class TypeSet>
class TypedMap : NoCopy
{
....
public:
explicit TypedMap(EngineResult result);
~TypedMap();
ulen getLen() const { return total; }
void operator () (void *mem);
template <class T>
T * findConst(StrLen name);
template <class T>
T takeConst(StrLen name);
};
TypedMap class usage is the same as for Map class. The difference is you have two methods to get a particular constant value.
findConst() searches for the constant with the given name and with the given type and returns a pointer to it. Null is returned if there is no such constant or it has a different type. The type is specified as the template parameter.
takeConst() does the same, but it returns the value and throw an exception on error.
In this case you always get a value of some C++ type, compatible with the DDL type. These types are available from the ddl/DDLMapTypes.h include file.
For integral types the compatible type is an integral C++ type. I.e. uint8 is mapped as uint8 etc. sint is mapped as sint_type, uint as uint_type and ulen as ulen_type.
ip is mapped as uint32.
text is mapped as MapText.
struct MapText
{
// data
char *ptr;
ulen len;
// methods
StrLen getStr() const { return StrLen(ptr,len); }
// cast
operator StrLen() const { return getStr(); }
};
Pointers are mapped as MapPtr.
template <class T>
struct MapPtr // layout-compatible with MapPtr<char>
{
// data
void *ptr;
// object ptr
void * operator + () const { return ptr; }
bool operator ! () const { return !ptr; }
T * getPtr() const { return static_cast<T *>(ptr); }
T & operator * () const { return *getPtr(); }
T * operator -> () const { return getPtr(); }
// cast
operator T * () const { return getPtr(); }
};
Polymorphic pointers are mapped as MapPolyPtr.
template <class ... TT>
struct MapPolyPtr // layout-compatible with MapPolyPtr<>
{
// data
void *ptr;
ulen type;
// methods
using AnyPtrType = AnyPtr<TT...> ;
AnyPtrType getPtr() const;
// cast
operator AnyPtrType() const { return getPtr(); }
};
Arrays are mapped as MapRange.
template <class T>
struct MapRange // layout-compatible with MapRange<char>
{
// data
void *ptr;
ulen len;
// methods
PtrLen<T> getRange() const;
// cast
operator PtrLen<T> () const { return getRange(); }
};
Finally, structure types are mapped using C++ structure definitions from the TypeSet class.
Here is LangTypes.ddl file.
/* LangTypes.ddl */ //---------------------------------------------------------------------------------------- // // Project: CondLangLR1 1.00 // // License: Boost Software License - Version 1.0 - August 17th, 2003 // // see http://www.boost.org/LICENSE_1_0.txt or the local copy // // Copyright (c) 2015 Sergey Strukov. All rights reserved. // //---------------------------------------------------------------------------------------- type AtomIndex = uint32 ; type SyntIndex = uint32 ; type KindIndex = uint32 ; type ElementIndex = uint32 ; type RuleIndex = uint32 ; type StateIndex = uint32 ; type FinalIndex = uint32 ; struct Lang { Atom[] atoms; Synt[] synts; Synt * [] lang; Element[] elements; Rule[] rules; TopRule[] top_rules; State[] states; Final[] finals; }; struct Atom { AtomIndex index; text name; Element *element; }; struct Synt { SyntIndex index; text name; Kind[] kinds; Rule * [] rules; }; struct Kind { KindIndex kindex; // index among all kinds KindIndex index; // index in synt array text name; Synt *synt; Element *element; TopRule * [] rules; }; struct Element { ElementIndex index; {Atom,Kind} * elem; }; struct Rule { RuleIndex index; text name; Kind *result; type Arg = {Atom,Synt} * ; Arg[] args; }; struct TopRule { RuleIndex index; text name; Rule *bottom; Kind *result; type Arg = {Atom,Kind} * ; Arg[] args; }; struct State { StateIndex index; Final *final; struct Transition { Element *element; State *state; }; Transition[] transitions; }; struct Final { FinalIndex index; struct Action { Atom *atom; // null for (End) Rule *rule; // null for <- ( STOP if atom is (END) ) }; Action[] actions; };
DDLTypeSet generates two C++ header files: LanTypeDef.gen.h and LangTypeSet.gen.h.
The first defines C++ structure types and aliases.
/* struct TypeDefCore */ struct TypeDefCore { // types struct S1; // #Final#Action struct S2; // #Final struct S3; // #State#Transition struct S4; // #State struct S5; // #TopRule struct S6; // #Rule struct S7; // #Element struct S8; // #Kind struct S9; // #Synt struct S10; // #Atom struct S11; // #Lang using A1 = DDL2::MapPolyPtr< S10 , S8 > ; // #TopRule#Arg using A2 = DDL2::MapPolyPtr< S10 , S9 > ; // #Rule#Arg using A3 = uint32 ; // #FinalIndex using A4 = uint32 ; // #StateIndex using A5 = uint32 ; // #RuleIndex using A6 = uint32 ; // #ElementIndex using A7 = uint32 ; // #KindIndex using A8 = uint32 ; // #SyntIndex using A9 = uint32 ; // #AtomIndex using XXX8226D906_9898_43AA_B1BE_D60B0A6E31C8 = TypeDefCore ; // structures struct S1 { DDL2::MapPtr< S10 > atom; DDL2::MapPtr< S6 > rule; struct Ext; }; struct S2 { A3 index; DDL2::MapRange< S1 > actions; using Action = XXX8226D906_9898_43AA_B1BE_D60B0A6E31C8::S1 ; struct Ext; }; struct S3 { DDL2::MapPtr< S7 > element; DDL2::MapPtr< S4 > state; struct Ext; }; struct S4 { A4 index; DDL2::MapPtr< S2 > final; DDL2::MapRange< S3 > transitions; using Transition = XXX8226D906_9898_43AA_B1BE_D60B0A6E31C8::S3 ; struct Ext; }; struct S5 { A5 index; DDL2::MapText name; DDL2::MapPtr< S6 > bottom; DDL2::MapPtr< S8 > result; DDL2::MapRange< A1 > args; using Arg = XXX8226D906_9898_43AA_B1BE_D60B0A6E31C8::A1 ; struct Ext; }; struct S6 { A5 index; DDL2::MapText name; DDL2::MapPtr< S8 > result; DDL2::MapRange< A2 > args; using Arg = XXX8226D906_9898_43AA_B1BE_D60B0A6E31C8::A2 ; struct Ext; }; struct S7 { A6 index; DDL2::MapPolyPtr< S10 , S8 > elem; struct Ext; }; struct S8 { A7 kindex; A7 index; DDL2::MapText name; DDL2::MapPtr< S9 > synt; DDL2::MapPtr< S7 > element; DDL2::MapRange< DDL2::MapPtr< S5 > > rules; struct Ext; }; struct S9 { A8 index; DDL2::MapText name; DDL2::MapRange< S8 > kinds; DDL2::MapRange< DDL2::MapPtr< S6 > > rules; struct Ext; }; struct S10 { A9 index; DDL2::MapText name; DDL2::MapPtr< S7 > element; struct Ext; }; struct S11 { DDL2::MapRange< S10 > atoms; DDL2::MapRange< S9 > synts; DDL2::MapRange< DDL2::MapPtr< S9 > > lang; DDL2::MapRange< S7 > elements; DDL2::MapRange< S6 > rules; DDL2::MapRange< S5 > top_rules; DDL2::MapRange< S4 > states; DDL2::MapRange< S2 > finals; struct Ext; }; // extra }; using XXX212CD757_09B3_4D89_BE20_65C1E4E5A819 = TypeDefCore ; namespace TypeDef { using StateIndex = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::A4 ; using KindIndex = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::A7 ; using RuleIndex = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::A5 ; using SyntIndex = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::A8 ; using AtomIndex = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::A9 ; using ElementIndex = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::A6 ; using FinalIndex = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::A3 ; using Atom = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S10 ; using Kind = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S8 ; using Lang = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S11 ; using Rule = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S6 ; using Synt = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S9 ; using Element = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S7 ; using TopRule = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S5 ; using Final = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S2 ; using State = XXX212CD757_09B3_4D89_BE20_65C1E4E5A819::S4 ; } // namespace TypeDef
You should use TypeDef namespace to refer a particular structure or a type alias. Use the same name, as the name of the DDL entity.
To use this file include it in your C++ source code inside some namespace to isolate it from the other stuff.
Each structure definition contains the declaration of the inner structure Ext. You may provide definitions of these structures to add additional functions to work with these structures.
The second file contains a definition of the TypeSet class.
/* struct TypeSet */ struct TypeSet : TypeDefCore { .... }; ....
Use this class as the template argument for the TypedMap class template.