summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/parser/ParserScope.cpp21
-rw-r--r--src/core/parser/ParserScope.hpp33
-rw-r--r--src/plugins/xml/XmlParser.cpp68
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")});