diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-03 22:54:17 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-03 22:54:17 +0100 |
commit | ec6306ad1e746d47ed66af6274fb6710c70933a2 (patch) | |
tree | d00627f99142e62f98894861673a91e14c6eb834 | |
parent | 7a8a8a31416cfebf785135754035608f4d919bf5 (diff) |
Fixed XML-Importer failing
-rw-r--r-- | src/core/parser/ParserScope.cpp | 21 | ||||
-rw-r--r-- | src/core/parser/ParserScope.hpp | 33 | ||||
-rw-r--r-- | src/plugins/xml/XmlParser.cpp | 68 |
3 files changed, 98 insertions, 24 deletions
diff --git a/src/core/parser/ParserScope.cpp b/src/core/parser/ParserScope.cpp index 1937697..b97dabd 100644 --- a/src/core/parser/ParserScope.cpp +++ b/src/core/parser/ParserScope.cpp @@ -90,10 +90,23 @@ Rooted<Node> ParserScopeBase::select(RttiSet types, int maxDepth) return nodes[i]; } } - throw LoggableException{ - std::string( - "Expected be inside an element of one of the internal types ") + - Utils::join(types, "\", \"", "\"", "\"")}; + return nullptr; +} + +Rooted<Node> ParserScopeBase::selectOrThrow(RttiSet types, int maxDepth) +{ + Rooted<Node> res = select(types, maxDepth); + if (res == nullptr) { + std::vector<std::string> typenames; + for (auto type : types) { + typenames.push_back(type->name); + } + throw LoggableException{std::string( + "Expected to be inside an element of one " + "of the internal types ") + + Utils::join(typenames, "\", \"", "\"", "\"")}; + } + return res; } /* Class DeferredResolution */ diff --git a/src/core/parser/ParserScope.hpp b/src/core/parser/ParserScope.hpp index dc1b1bf..7be3c4a 100644 --- a/src/core/parser/ParserScope.hpp +++ b/src/core/parser/ParserScope.hpp @@ -145,6 +145,33 @@ public: /** * Ascends in the stack starting with the leaf node, returns the first node + * that matches the type given in the RttiSet or nullptr if none matches. + * + * @param types is a set of Rtti types for which should be searched in the + * stack. + * @param maxDepth is the maximum number of stack entries the selection + * function may ascend. A negative value indicates no limitation. + * @return the matching node or nullptr if the node was not found. + */ + Rooted<Node> select(RttiSet types, int maxDepth = -1); + + /** + * Ascends in the stack starting with the leaf node, returns the first node + * that matches the given type or nullptr if none matches. + * + * @tparam T is the type that should be searched in the stack. + * @param maxDepth is the maximum number of stack entries the selection + * function may ascend. A negative value indicates no limitation. + * @return the matching node or nullptr if the node was not found. + */ + template <class T> + Rooted<T> select(int maxDepth = -1) + { + return select(RttiSet{&typeOf<T>()}, maxDepth).cast<T>(); + } + + /** + * Ascends in the stack starting with the leaf node, returns the first node * that matches the type given in the RttiSet. Throws an exception if no * node matches. * @@ -154,7 +181,7 @@ public: * function may ascend. A negative value indicates no limitation. * @return the matching node. */ - Rooted<Node> select(RttiSet types, int maxDepth = -1); + Rooted<Node> selectOrThrow(RttiSet types, int maxDepth = -1); /** * Ascends in the stack starting with the leaf node, returns the first node @@ -166,9 +193,9 @@ public: * @return the matching node. */ template <class T> - Rooted<T> select(int maxDepth = -1) + Rooted<T> selectOrThrow(int maxDepth = -1) { - return select(RttiSet{&typeOf<T>()}, maxDepth).cast<T>(); + return selectOrThrow(RttiSet{&typeOf<T>()}, maxDepth).cast<T>(); } }; diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index f4e5caf..e56d528 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -86,12 +86,6 @@ public: project()->createTypesystem(args["name"].asString()); typesystem->setLocation(location()); - // Check whether this typesystem is a direct child of a domain - Handle<Node> parent = scope().select({&RttiTypes::Domain}); - if (parent != nullptr) { - parent.cast<Domain>()->referenceTypesystem(typesystem); - } - // Push the typesystem onto the scope, set the POST_HEAD flag to true scope().push(typesystem); scope().setFlag(ParserFlag::POST_HEAD, false); @@ -105,7 +99,7 @@ public: } }; -class TypesystemStructHandler : public Handler { +class TypesystemEnumHandler : public Handler { public: using Handler::Handler; @@ -118,7 +112,7 @@ public: const std::string &parent = args["parent"].asString(); // Fetch the current typesystem and create the struct node - Rooted<Typesystem> typesystem = scope().select<Typesystem>(); + Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>(); Rooted<StructType> structType = typesystem->createStructType(name); structType->setLocation(location()); @@ -134,14 +128,54 @@ public: } }); } + scope().push(structType); + } + + void end() override + { + scope().pop(); + } + + static Handler *create(const HandlerData &handlerData) + { + return new TypesystemEnumHandler{handlerData}; + } +}; + +class TypesystemStructHandler : public Handler { +public: + using Handler::Handler; + + void start(Variant::mapType &args) override + { + scope().setFlag(ParserFlag::POST_HEAD, true); - // Descend into the struct type + // Fetch the arguments used for creating this type + const std::string &name = args["name"].asString(); + const std::string &parent = args["parent"].asString(); + + // Fetch the current typesystem and create the struct node + Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>(); + Rooted<StructType> structType = typesystem->createStructType(name); + structType->setLocation(location()); + + // Try to resolve the parent type and set it as parent structure + if (!parent.empty()) { + scope().resolve<StructType>( + parent, structType, logger(), + [](Handle<Node> parent, Handle<Node> structType, + Logger &logger) { + if (parent != nullptr) { + structType.cast<StructType>()->setParentStructure( + parent.cast<StructType>(), logger); + } + }); + } scope().push(structType); } void end() override { - // Descend from the struct type scope().pop(); } @@ -164,7 +198,7 @@ public: const bool optional = !(defaultValue.isObject() && defaultValue.asObject() == nullptr); - Rooted<StructType> structType = scope().select<StructType>(); + Rooted<StructType> structType = scope().selectOrThrow<StructType>(); Rooted<Attribute> attribute = structType->createAttribute(name, defaultValue, optional, logger()); attribute->setLocation(location()); @@ -212,7 +246,7 @@ public: const std::string &type = args["type"].asString(); const Variant &value = args["value"]; - Rooted<Typesystem> typesystem = scope().select<Typesystem>(); + Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>(); Rooted<Constant> constant = typesystem->createConstant(name, value); constant->setLocation(location()); @@ -266,7 +300,7 @@ public: const std::string &isa = args["isa"].asString(); - Rooted<Domain> domain = scope().select<Domain>(); + Rooted<Domain> domain = scope().selectOrThrow<Domain>(); Rooted<StructuredClass> structuredClass = domain->createStructuredClass( args["name"].asString(), args["cardinality"].asCardinality(), nullptr, nullptr, args["transparent"].asBool(), @@ -439,13 +473,14 @@ static const ParserState Typesystem = .elementHandler(TypesystemHandler::create) .arguments({Argument::String("name", "")}); static const ParserState TypesystemEnum = - ParserStateBuilder().createdNodeType(&RttiTypes::EnumType).parent( - &Typesystem); + ParserStateBuilder() + .createdNodeType(&RttiTypes::EnumType) + .elementHandler(TypesystemEnumHandler::create) + .parent(&Typesystem); static const ParserState TypesystemStruct = ParserStateBuilder() .parent(&Typesystem) .createdNodeType(&RttiTypes::StructType) - .elementHandler(TypesystemStructHandler::create) .arguments({Argument::String("name"), Argument::String("parent", "")}); static const ParserState TypesystemStructField = @@ -458,7 +493,6 @@ static const ParserState TypesystemConstant = ParserStateBuilder() .parent(&Typesystem) .createdNodeType(&RttiTypes::Constant) - .elementHandler(TypesystemConstantHandler::create) .arguments({Argument::String("name"), Argument::String("type"), Argument::Any("value")}); |