An XML serialization description file, xmlser file for short, consists of include directives and other content:
xml‑serialization‑description‑file | → | include‑directives namespace‑content |
xmlsergen puts include directives beginning with the [hpp] file tag to the generated header file, and include directives beginning with the [cpp] file tag to the generated source file. Include directives that have no file tag are put to the generated header file.
include‑directives | → | include‑directive* |
include‑directive | → | file‑tag? # include file‑path |
file‑tag | → | [ (cpp | hpp) ] |
Other content of the xmlser file consists of declarations and definitions:
namespace‑content | → | (declaration | definition)* |
There can be two kinds of declarations: forward-class-declarations and using-alias-declarations.
declaration | → | forward‑class‑declaration | using‑alias‑declaration |
A forward-class-declaration consists of the keyword class followed by a class identifier followed by a semicolon:
forward‑class‑declaration | → | class identifier ; |
xmlsergen puts the forward-class-declarations to the generated header file.
A using-alias-declaration consists of the keyword using followed by an identifier followed by an assignment symbol followed by a a nonempty sequence of identifiers seperated by two colons followed by a semicolon:
using‑alias‑declaration | → | using identifier = qualified‑id ; |
qualified‑id | → | identifier (:: identifier)* |
xmlsergen puts the using-alias-declarations to the generated header file.
There are four kinds of definitions: class, enum, namespace and C++ block definitions:
definition | → | class | enum | namespace | cpp‑block |
A class definition consists of a keyword class followed by an optional api declaration followed by an identifier followed by optional class inheritance followed by class content within pair of braces.
A class inheritance consists of a colon followed a list of base classes separated by commas.
There are two kinds of class inheritance: internal and external. An internal inheritance is denoted by a single class identifier. That class must be defined within this or another xmlser file. There can be at most one internal base class for a class. An external inheritance is denoted by the keyword base followed by a class identifier within pair of parenthesis. That class should not be defined in any xmlser file, it should be an external class. There can be any number of external base classes for a class.
The class content consists of member variables and C++ code blocks. xmlsergen places C++ code blocks defined inside a class to the generated header file inside the corresponding generated C++ class.
class | → | class api? identifier inheritance? { class‑content } |
inheritance | → | : base‑class ( , base‑class )* |
base‑class | → | base ( identifier ) | identifier |
class‑content | → | (member‑variable | cpp‑block)* |
A member variable declaration consists of the type of the member variable followed by the name of the member variable followed by a semicolon:
member‑variable | → | type identifier ; |
xmlsergen places member variable declarations within the generated class to the generated header file. It generates default initialization for each member variable in the generated class constructor and places it to the generated source file.
A C++ code block consists of arbitrary content within pair of <% and %> delimiters. xmlsergen places code blocks inside a class to the generated header file within the class. It places code blocks following classes in a xmlser file to the end of the generated source file.
cpp‑block | → | <% (. - %>)* %> |
An enumerated type definition consists of the keyword enum followed by an identifier followed by enumeration content within pair of braces.
An enumeration content consists of a list of enumeration constants separated by commas.
An enumeration constant is denoted by an identifier.
enum | → | enum identifier { enum‑content } |
enum‑content | → | (enum‑constant (, enum‑constant)*)? |
enum‑constant | → | identifier |
xmlsergen places enumerated type definitions to the generated header file.
A namespace definition consists of the keyword namespace followed by an identifier followed by namespace content within pair of braces:
namespace | → | namespace identifier { namespace‑content } |
A type declaration consists of a scalar, class or template type followed by optional pointer type symbol, an asterisk, followed by optional array type symbol, a pair of square brackets:
type | → | (scalar‑type | class‑type | template‑type) *? ([])? |
A scalar type has a single keyword and a corresponding C++ type. The C++ type may be a fundamental C++ type, such as bool: a type defined in the C++ standard library, such as time_point: std::chrono::steady_clock::time_point, a type defined in the Boost library, such as uuid: boost::uuids::uuid or a type defined in soulng::util library, such as date: soulng::util::Date.
scalar‑type | → | bool | sbyte | byte | short | ushort | int | uint | long | ulong | float | double | char | wchar | uchar | uuid | string | wstring | ustring | date | datetime | timestamp | time_point | duration |
xmlsergen converts the scalar type denoted by a soulng keyword to the corresponding C++ type and places the C++ declaration to the generated header file within a class definition.
A class type is denoted by a class identifier:
class‑type | → | identifier |
xmlsergen recognizes two kinds of template types: xml_ptr<T> and unique_xml_ptr<T>.
xml_ptr is an alias to the serialization library sngxml::xmlser::XmlPtr class template.
unique_xml_ptr is an alias to the serialization library sngxml::xmlser::UniqueXmlPtr class template.
template‑type | → | identifier < identifier > |
A pointer type is denoted by an asterisk following a base type. xmlsergen converts the pointer type to std::unique_ptr<T> where T is the base type.
An array type is denoted by a pair of square brackets following a base type. xmlsergen converts the array type to std::vector<T> where T is the base type.
type | → | (scalar‑type | class‑type | template‑type) *? ([])? |
xml‑serialization‑description‑file | → | include‑directives namespace‑content |
include‑directives | → | include‑directive* |
include‑directive | → | file‑tag? # include file‑path |
file‑tag | → | [ (cpp | hpp) ] |
namespace‑content | → | (declaration | definition)* |
declaration | → | forward‑class‑declaration | using‑alias‑declaration |
forward‑class‑declaration | → | class identifier ; |
using‑alias‑declaration | → | using identifier = qualified‑id ; |
qualified‑id | → | identifier (:: identifier)* |
definition | → | class | enum | namespace | cpp‑block |
class | → | class api? identifier inheritance? { class‑content } |
inheritance | → | : base‑class ( , base‑class )* |
base‑class | → | base ( identifier ) | identifier |
class‑content | → | (member‑variable | cpp‑block)* |
member‑variable | → | type identifier ; |
cpp‑block | → | <% (. - %>)* %> |
enum | → | enum identifier { enum‑content } |
enum‑content | → | (enum‑constant (, enum‑constant)*)? |
enum‑constant | → | identifier |
namespace | → | namespace identifier { namespace‑content } |
type | → | (scalar‑type | class‑type | template‑type) *? ([])? |
scalar‑type | → | bool | sbyte | byte | short | ushort | int | uint | long | ulong | float | double | char | wchar | uchar | uuid | string | wstring | ustring | date | datetime | timestamp | time_point | duration |
class‑type | → | identifier |
template‑type | → | identifier < identifier > |