diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-01 21:30:15 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-01 21:30:15 +0100 |
commit | 28fc6ac92cf8b058da22c54c939fc225779ac26d (patch) | |
tree | 6caf90848f577109fd2e89ff07af88f93d39d0c1 /src/plugins/xml | |
parent | ba5439849b72ac341344d55f2bf05ccf11e37410 (diff) |
Improved ParserStack state description
Diffstat (limited to 'src/plugins/xml')
-rw-r--r-- | src/plugins/xml/XmlParser.cpp | 297 |
1 files changed, 105 insertions, 192 deletions
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index 3b7e37f..42620c3 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -72,54 +72,6 @@ public: } }; -class HeadHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - // Make sure the "HEAD" node is actually allowed here - if (scope().getFlag(ParserFlag::POST_HEAD)) { - throw LoggableException{ - "\"head\" tag not allowed here, head was already specified or " - "another command was given first", - location()}; - } - - // Insert a new HeadNode instance - scope().push(new HeadNode{manager()}); - } - - void end() override - { - // Remove the HeadNode instance from the stack - scope().pop(); - scope().setFlag(ParserFlag::POST_HEAD, true); - } - - static Handler *create(const HandlerData &handlerData) - { - return new HeadHandler{handlerData}; - } -}; - -class DisableHeadHandler : public Handler { -public: - using Handler::Handler; - - void start(Variant::mapType &args) override - { - scope().setFlag(ParserFlag::POST_HEAD, true); - } - - void end() override {} - - static Handler *create(const HandlerData &handlerData) - { - return new DisableHeadHandler{handlerData}; - } -}; - class TypesystemHandler : public Handler { public: using Handler::Handler; @@ -194,7 +146,7 @@ public: } }; -class StructFieldHandler : public Handler { +class TypesystemStructFieldHandler : public Handler { public: using Handler::Handler; @@ -238,11 +190,11 @@ public: static Handler *create(const HandlerData &handlerData) { - return new StructFieldHandler{handlerData}; + return new TypesystemStructFieldHandler{handlerData}; } }; -class ConstantHandler : public Handler { +class TypesystemConstantHandler : public Handler { public: using Handler::Handler; @@ -272,7 +224,7 @@ public: static Handler *create(const HandlerData &handlerData) { - return new ConstantHandler{handlerData}; + return new TypesystemConstantHandler{handlerData}; } }; @@ -335,146 +287,106 @@ public: } }; -/* Document structure */ -static const State STATE_DOCUMENT = 0; -static const State STATE_DOCUMENT_HEAD = 1; - -/* Special commands */ -static const State STATE_IMPORT = 100; -static const State STATE_INCLUDE = 101; - -/* Type system definitions */ -static const State STATE_TYPESYSTEM = 200; -static const State STATE_TYPESYSTEM_HEAD = 201; -static const State STATE_TYPES = 202; -static const State STATE_CONSTANTS = 203; -static const State STATE_CONSTANT = 204; -static const State STATE_ENUM = 205; -static const State STATE_STRUCT = 206; -static const State STATE_FIELD = 207; - -/* Domain definitions */ -static const State STATE_DOMAIN = 300; -static const State STATE_DOMAIN_HEAD = 301; -static const State STATE_DOMAIN_STRUCTS = 302; -static const State STATE_DOMAIN_STRUCT = 303; -static const State STATE_DOMAIN_FIELDS = 304; -static const State STATE_DOMAIN_FIELD = 305; -static const State STATE_DOMAIN_PRIMITIVE_FIELD = 306; -static const State STATE_DOMAIN_CHILDREN = 307; -static const State STATE_DOMAIN_CHILD = 308; -static const State STATE_DOMAIN_CHILD_REF = 309; -static const State STATE_DOMAIN_PARENTS = 310; -static const State STATE_DOMAIN_PARENT = 311; -static const State STATE_DOMAIN_PARENT_FIELD = 312; -static const State STATE_DOMAIN_PARENT_FIELD_REF = 313; -static const State STATE_DOMAIN_ANNOTATIONS = 314; -static const State STATE_DOMAIN_ANNOTATION = 315; - -static const std::multimap<std::string, HandlerDescriptor> XML_HANDLERS{ - /* Document tags */ - {"document", - {{STATE_NONE}, - DocumentHandler::create, - STATE_DOCUMENT, - true, - {Argument::String("name", "")}}}, - {"head", {{STATE_DOCUMENT}, HeadHandler::create, STATE_DOCUMENT_HEAD}}, - - /* Special commands */ - {"import", - {{STATE_DOCUMENT_HEAD, STATE_TYPESYSTEM_HEAD}, nullptr, STATE_IMPORT}}, - {"include", {{STATE_ALL}, nullptr, STATE_INCLUDE}}, - - /* Typesystem */ - {"typesystem", - {{STATE_NONE, STATE_DOMAIN_HEAD}, - TypesystemHandler::create, - STATE_TYPESYSTEM, - false, - {Argument::String("name")}}}, - {"head", {{STATE_TYPESYSTEM}, HeadHandler::create, STATE_TYPESYSTEM}}, - {"types", {{STATE_TYPESYSTEM}, DisableHeadHandler::create, STATE_TYPES}}, - {"enum", {{STATE_TYPES}, nullptr, STATE_ENUM}}, - {"struct", - {{STATE_TYPES}, - TypesystemStructHandler::create, - STATE_STRUCT, - false, - {Argument::String("name"), Argument::String("parent", "")}}}, - {"field", - {{STATE_STRUCT}, - StructFieldHandler::create, - STATE_FIELD, - false, - {Argument::String("name"), Argument::String("type"), - Argument::Any("default", Variant::fromObject(nullptr))}}}, - {"constants", - {{STATE_TYPESYSTEM}, DisableHeadHandler::create, STATE_CONSTANTS}}, - {"constant", - {{STATE_CONSTANTS}, - ConstantHandler::create, - STATE_CONSTANT, - false, - {Argument::String("name"), Argument::String("type"), - Argument::Any("value")}}}, - - /* Domain */ - {"domain", - {{STATE_NONE, STATE_DOCUMENT_HEAD}, - DomainHandler::create, - STATE_DOMAIN, - false, - {Argument::String("name")}}}, - {"head", - {{STATE_DOMAIN}, - HeadHandler::create, - STATE_DOMAIN_HEAD, - false, - Arguments{}}}, - {"structs", - {{STATE_DOMAIN}, - DisableHeadHandler::create, - STATE_DOMAIN_STRUCTS, - false, - Arguments{}}}, - {"struct", - {{STATE_DOMAIN_STRUCTS}, - DomainStructHandler::create, - STATE_DOMAIN_STRUCT, - false, - Arguments{Argument::String("name"), - Argument::Cardinality("cardinality", AnyCardinality), - Argument::Bool("isRoot", false), - Argument::Bool("transparent", false), - Argument::String("isa", "")}}}, - {"fields", - {{STATE_DOMAIN_STRUCT, STATE_DOMAIN_ANNOTATIONS}, - nullptr, - STATE_DOMAIN_FIELDS, - false, - Arguments{}}}, - {"field", - {{STATE_DOMAIN_FIELDS}, - nullptr, - STATE_DOMAIN_FIELD, - false, - Arguments{Argument::String("name", ""), Argument::Bool("isSubtree", false), - Argument::Bool("optional", false)}}}, - {"primitive", - {{STATE_DOMAIN_FIELDS}, - nullptr, - STATE_DOMAIN_PRIMITIVE_FIELD, - false, - Arguments{Argument::String("name", ""), Argument::Bool("optional", false), - Argument::String("type")}}}, - {"annotations", - {{STATE_DOMAIN}, - DisableHeadHandler::create, - STATE_DOMAIN_ANNOTATIONS, - false, - Arguments{}}}}; +class ImportHandler : public Handler { +public: + using Handler::Handler; + + void start(Variant::mapType &args) override + { + // scope().import(); + } + + void end() override {} + + static Handler *create(const HandlerData &handlerData) + { + return new ImportHandler{handlerData}; + } +}; +namespace ParserStates { +/* Document states */ +static const ParserState Document = + ParserStateBuilder() + .parent(&None) + .elementHandler(DocumentHandler::create) + .arguments({Argument::String("name", "")}); + +/* Domain states */ +static const ParserState Domain = ParserStateBuilder() + .parents({&None, &Document}) + .elementHandler(DomainHandler::create) + .arguments({Argument::String("name")}); +static const ParserState DomainStruct = + ParserStateBuilder() + .parent(&Domain) + .elementHandler(DomainStructHandler::create) + .arguments({Argument::String("name"), + Argument::Cardinality("cardinality", AnyCardinality), + Argument::Bool("isRoot", false), + Argument::Bool("transparent", false), + Argument::String("isa", "")}); +static const ParserState DomainStructFields = + ParserStateBuilder().parent(&DomainStruct).arguments({}); +static const ParserState DomainStructField = + ParserStateBuilder().parent(&DomainStructFields).arguments( + {Argument::String("name", ""), Argument::Bool("isSubtree", false), + Argument::Bool("optional", false)}); +static const ParserState DomainStructPrimitive = + ParserStateBuilder().parent(&DomainStructFields).arguments( + {Argument::String("name", ""), Argument::Bool("optional", false), + Argument::String("type")}); + +/* Typesystem states */ +static const ParserState Typesystem = + ParserStateBuilder() + .parents({&None, &Domain}) + .elementHandler(TypesystemHandler::create) + .arguments({Argument::String("name", "")}); +static const ParserState TypesystemEnum = + ParserStateBuilder().parent(&Typesystem); +static const ParserState TypesystemStruct = + ParserStateBuilder() + .parent(&Typesystem) + .elementHandler(TypesystemStructHandler::create) + .arguments({Argument::String("name"), Argument::String("parent", "")}); +static const ParserState TypesystemStructField = + ParserStateBuilder() + .parent(&TypesystemStruct) + .elementHandler(TypesystemStructFieldHandler::create) + .arguments({Argument::String("name"), Argument::String("type"), + Argument::Any("default", Variant::fromObject(nullptr))}); +static const ParserState TypesystemConstant = + ParserStateBuilder() + .parent(&Typesystem) + .elementHandler(TypesystemConstantHandler::create) + .arguments({Argument::String("name"), Argument::String("type"), + Argument::Any("value")}); + +/* Special states for import and include */ +static const ParserState Import = + ParserStateBuilder().parents({&Document, &Typesystem, &Domain}).arguments( + {Argument::String("rel", ""), Argument::String("type", ""), + Argument::String("src")}); +static const ParserState Include = ParserStateBuilder().parent(&All).arguments( + {Argument::String("rel", ""), Argument::String("type", ""), + Argument::String("src")}); + +static const std::multimap<std::string, const ParserState *> XmlStates{ + {"document", &Document}, + {"domain", &Domain}, + {"struct", &DomainStruct}, + {"fields", &DomainStructFields}, + {"field", &DomainStructField}, + {"primitive", &DomainStructPrimitive}, + {"typesystem", &Typesystem}, + {"enum", &TypesystemEnum}, + {"struct", &TypesystemStruct}, + {"field", &TypesystemStructField}, + {"constant", &TypesystemConstant}, + {"import", &Import}, + {"include", &Include}}; +} /** * Wrapper class around the XML_Parser pointer which safely frees it whenever * the scope is left (e.g. because an exception was thrown). @@ -572,6 +484,7 @@ static void xmlCharacterDataHandler(void *p, const XML_Char *s, int len) XML_Parser parser = static_cast<XML_Parser>(p); ParserStack *stack = static_cast<ParserStack *>(XML_GetUserData(parser)); + syncLoggerPosition(parser); const std::string data = Utils::trim(std::string{s, static_cast<size_t>(len)}); if (!data.empty()) { @@ -588,7 +501,7 @@ void XmlParser::doParse(CharReader &reader, ParserContext &ctx) // Create the parser stack instance and pass the reference to the state // machine descriptor - ParserStack stack{ctx, XML_HANDLERS}; + ParserStack stack{ctx, ParserStates::XmlStates}; XML_SetUserData(&p, &stack); XML_UseParserAsHandlerArg(&p); |