summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-03-02 16:30:51 +0100
committerAndreas Stöckel <andreas@somweyr.de>2015-03-02 16:30:51 +0100
commit3cc6ebf406c53b0c82a52f0daf1ce14c62f7b521 (patch)
tree8d5538a8a07af563c3e8f5f2e789ec3e80b81313 /src
parent072992a634d816fc7061b7eee5fd0cabe4242de4 (diff)
Implemented new "start" methods in the Handler instances
Diffstat (limited to 'src')
-rw-r--r--src/core/parser/stack/DocumentHandler.cpp133
-rw-r--r--src/core/parser/stack/DocumentHandler.hpp69
-rw-r--r--src/core/parser/stack/DomainHandler.cpp76
-rw-r--r--src/core/parser/stack/DomainHandler.hpp22
-rw-r--r--src/core/parser/stack/Handler.cpp102
-rw-r--r--src/core/parser/stack/Handler.hpp150
-rw-r--r--src/core/parser/stack/Stack.cpp24
-rw-r--r--src/core/parser/stack/TypesystemHandler.cpp29
-rw-r--r--src/core/parser/stack/TypesystemHandler.hpp15
9 files changed, 372 insertions, 248 deletions
diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp
index 714ab1b..de6e367 100644
--- a/src/core/parser/stack/DocumentHandler.cpp
+++ b/src/core/parser/stack/DocumentHandler.cpp
@@ -37,7 +37,8 @@ namespace parser_stack {
/* DocumentHandler */
-bool DocumentHandler::start(Variant::mapType &args)
+bool DocumentHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
Rooted<Document> document =
context().getProject()->createDocument(args["name"].asString());
@@ -52,6 +53,25 @@ void DocumentHandler::end() { scope().pop(logger()); }
/* DocumentChildHandler */
+DocumentChildHandler::DocumentChildHandler(const HandlerData &handlerData)
+ : Handler(handlerData), mode(Mode::STRUCT)
+{
+}
+
+void DocumentChildHandler::setMode(Mode mode, const std::string &name)
+{
+ this->mode = mode;
+ this->name = name;
+ this->token = Token();
+}
+
+void DocumentChildHandler::setMode(Mode mode, const Token &token)
+{
+ this->mode = mode;
+ this->name = token.content;
+ this->token = token;
+}
+
void DocumentChildHandler::preamble(Rooted<Node> &parentNode, size_t &fieldIdx,
DocumentEntity *&parent)
{
@@ -122,10 +142,14 @@ void DocumentChildHandler::createPath(const size_t &firstFieldIdx,
scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, false);
}
-bool DocumentChildHandler::start(Variant::mapType &args)
+bool DocumentChildHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
- // extract the special "name" attribute from the input arguments.
- // the remaining attributes will be forwarded to the newly constructed
+ // Set the internal mode to STRUCT and copy the name
+ setMode(Mode::STRUCT, name);
+
+ // Extract the special "name" attribute from the input arguments.
+ // The remaining attributes will be forwarded to the newly constructed
// element.
std::string nameAttr;
{
@@ -152,11 +176,11 @@ bool DocumentChildHandler::start(Variant::mapType &args)
return false;
}
Rooted<StructuredClass> strct = scope().resolve<StructuredClass>(
- Utils::split(name(), ':'), logger());
+ Utils::split(name, ':'), logger());
if (strct == nullptr) {
// if we could not resolve the name, throw an exception.
throw LoggableException(
- std::string("\"") + name() + "\" could not be resolved.",
+ std::string("\"") + name + "\" could not be resolved.",
location());
}
entity = parentNode.cast<Document>()->createRootStructuredEntity(
@@ -169,13 +193,6 @@ bool DocumentChildHandler::start(Variant::mapType &args)
preamble(parentNode, fieldIdx, parent);
- // TODO: REMOVE
- std::string thisName = name();
- std::string parentClassName;
- if (parent != nullptr) {
- parentClassName = parent->getDescriptor()->getName();
- }
-
/*
* Try to find a FieldDescriptor for the given tag if we are not in
* a field already. This does _not_ try to construct transparent
@@ -183,7 +200,7 @@ bool DocumentChildHandler::start(Variant::mapType &args)
*/
{
ssize_t newFieldIdx =
- parent->getDescriptor()->getFieldDescriptorIndex(name());
+ parent->getDescriptor()->getFieldDescriptorIndex(name);
if (newFieldIdx != -1) {
// Check whether explicit fields are allowed here, if not
if (scope().getFlag(ParserFlag::POST_EXPLICIT_FIELDS)) {
@@ -191,17 +208,17 @@ bool DocumentChildHandler::start(Variant::mapType &args)
std::string(
"Data or structure commands have already been "
"given, command \"") +
- name() + std::string(
- "\" is not interpreted explicit "
- "field. Move explicit field "
- "references to the beginning."),
+ name + std::string(
+ "\" is not interpreted explicit "
+ "field. Move explicit field "
+ "references to the beginning."),
location());
} else {
Rooted<DocumentField> field{new DocumentField(
manager(), parentNode, newFieldIdx, false)};
field->setLocation(location());
scope().push(field);
- isExplicitField = true;
+ setMode(Mode::EXPLICIT_FIELD, name);
return true;
}
}
@@ -210,11 +227,11 @@ bool DocumentChildHandler::start(Variant::mapType &args)
// Otherwise create a new StructuredEntity
// TODO: Consider Anchors and AnnotationEntities
Rooted<StructuredClass> strct = scope().resolve<StructuredClass>(
- Utils::split(name(), ':'), logger());
+ Utils::split(name, ':'), logger());
if (strct == nullptr) {
// if we could not resolve the name, throw an exception.
throw LoggableException(
- std::string("\"") + name() + "\" could not be resolved.",
+ std::string("\"") + name + "\" could not be resolved.",
location());
}
@@ -261,24 +278,56 @@ bool DocumentChildHandler::start(Variant::mapType &args)
}
}
+bool DocumentChildHandler::startAnnotation(const std::string &name,
+ Variant::mapType &args,
+ AnnotationType annotationType)
+{
+ // Set the internal mode and name correctly
+ if (annotationType == AnnotationType::START) {
+ setMode(Mode::ANNOTATION_START, name);
+ } else {
+ setMode(Mode::ANNOTATION_END, name);
+ }
+
+ // TODO: Handle annotation
+ return false;
+}
+
+bool DocumentChildHandler::startToken(const Token &token, Handle<Node> node)
+{
+ // Set the internal mode correctly
+ setMode(Mode::TOKEN, token);
+
+ // TODO: Handle token start
+ return false;
+}
+
+DocumentChildHandler::EndTokenResult DocumentChildHandler::endToken(
+ const Token &token, Handle<Node> node)
+{
+ // TODO: Handle token end
+ return EndTokenResult::ENDED_NONE;
+}
+
void DocumentChildHandler::end()
{
- // in case of explicit fields we do not want to pop something from the
+ // In case of explicit fields we do not want to pop something from the
// stack.
- if (isExplicitField) {
- return;
+ if (mode == Mode::STRUCT) {
+ // pop the "main" element.
+ scope().pop(logger());
}
- // pop the "main" element.
- scope().pop(logger());
}
bool DocumentChildHandler::fieldStart(bool &isDefault, size_t fieldIdx)
{
- if (isExplicitField) {
+ // TODO: Handle other cases
+ if (mode == Mode::EXPLICIT_FIELD) {
// In case of explicit fields we do not want to create another field.
isDefault = true;
return fieldIdx == 0;
}
+
Rooted<Node> parentNode = scope().getLeaf();
assert(parentNode->isa(&RttiTypes::StructuredEntity) ||
parentNode->isa(&RttiTypes::AnnotationEntity));
@@ -291,7 +340,7 @@ bool DocumentChildHandler::fieldStart(bool &isDefault, size_t fieldIdx)
parent->getDescriptor()->getFieldDescriptors();
if (isDefault) {
- if(fields.empty()){
+ if (fields.empty()) {
return false;
}
fieldIdx = fields.size() - 1;
@@ -317,33 +366,19 @@ void DocumentChildHandler::fieldEnd()
{
assert(scope().getLeaf()->isa(&RttiTypes::DocumentField));
- // pop the field from the stack.
+ // Pop the field from the stack.
scope().pop(logger());
- // pop all remaining transparent elements.
+ // Pop all remaining transparent elements.
while (scope().getLeaf()->isa(&RttiTypes::StructuredEntity) &&
scope().getLeaf().cast<StructuredEntity>()->isTransparent()) {
- // pop the transparent element.
+ // Pop the transparent element.
scope().pop(logger());
- // pop the transparent field.
+ // Pop the transparent field.
scope().pop(logger());
}
}
-bool DocumentChildHandler::annotationStart(const Variant &className,
- Variant::mapType &args)
-{
- // TODO: Implement
- return false;
-}
-
-bool DocumentChildHandler::annotationEnd(const Variant &className,
- const Variant &elementName)
-{
- // TODO: Implement
- return false;
-}
-
bool DocumentChildHandler::convertData(Handle<FieldDescriptor> field,
Variant &data, Logger &logger)
{
@@ -436,7 +471,7 @@ bool DocumentChildHandler::data()
// this fact
Variant text = readData();
if (defaultFields.empty()) {
- logger().error("Got data, but structure \"" + name() +
+ logger().error("Got data, but structure \"" + name +
"\" does not have any primitive field",
text);
} else {
@@ -467,7 +502,9 @@ const State DocumentChild = StateBuilder()
.createdNodeTypes({&RttiTypes::StructureNode,
&RttiTypes::AnnotationEntity,
&RttiTypes::DocumentField})
- .elementHandler(DocumentChildHandler::create);
+ .elementHandler(DocumentChildHandler::create)
+ .supportsAnnotations(true)
+ .supportsTokens(true);
}
}
diff --git a/src/core/parser/stack/DocumentHandler.hpp b/src/core/parser/stack/DocumentHandler.hpp
index c51c188..9a41508 100644
--- a/src/core/parser/stack/DocumentHandler.hpp
+++ b/src/core/parser/stack/DocumentHandler.hpp
@@ -53,7 +53,8 @@ class DocumentHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
void end() override;
/**
@@ -91,8 +92,55 @@ public:
* defined elements in an Ousía document.
*/
class DocumentChildHandler : public Handler {
+public:
+ /**
+ * Enum type used to represent the mode of the DocumentChildHandler.
+ * TODO: Having to have such a type is actually quite stupid, it would be
+ * nicer to have separate handler classes for each of these cases. But this
+ * is a story for a different day.
+ */
+ enum class Mode {
+ STRUCT,
+ EXPLICIT_FIELD,
+ ANNOTATION_START,
+ ANNOTATION_END,
+ TOKEN
+ };
+
private:
- bool isExplicitField = false;
+ /**
+ * Internal Mode of the DocumentChildHandler.
+ */
+ Mode mode;
+
+ /**
+ * Contains the name of the command or the annotation that is represented
+ * by this DocumentChildHandler.
+ */
+ std::string name;
+
+ /**
+ * Token represented by the document child handler.
+ */
+ Token token;
+
+ /**
+ * Switches the mode to the given mode and copies the given name. Resets the
+ * token.
+ *
+ * @param mode is the new mode.
+ * @param name is the new name.
+ */
+ void setMode(Mode mode, const std::string &name);
+
+ /**
+ * Switches the mode to the given mode and copies the given token, sets the
+ * name to the content of the token.
+ *
+ * @param mode is the new mode.
+ * @param token is the new token.
+ */
+ void setMode(Mode mode, const Token &token);
/**
* Code shared by both the start(), fieldStart() and the data() method.
@@ -161,22 +209,19 @@ private:
Logger &logger);
public:
- using Handler::Handler;
+ DocumentChildHandler(const HandlerData &handlerData);
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
+ bool startAnnotation(const std::string &name, Variant::mapType &args,
+ AnnotationType annotationType) override;
+ bool startToken(const Token &token, Handle<Node> node) override;
+ EndTokenResult endToken(const Token &token, Handle<Node> node) override;
void end() override;
bool data() override;
-
bool fieldStart(bool &isDefault, size_t fieldIdx) override;
-
void fieldEnd() override;
- bool annotationStart(const Variant &className,
- Variant::mapType &args) override;
-
- bool annotationEnd(const Variant &className,
- const Variant &elementName) override;
-
/**
* Creates a new instance of the DocumentChildHandler.
*
diff --git a/src/core/parser/stack/DomainHandler.cpp b/src/core/parser/stack/DomainHandler.cpp
index aa18faa..5ca4f5b 100644
--- a/src/core/parser/stack/DomainHandler.cpp
+++ b/src/core/parser/stack/DomainHandler.cpp
@@ -33,7 +33,8 @@ namespace parser_stack {
/* DomainHandler */
-bool DomainHandler::start(Variant::mapType &args)
+bool DomainHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
// Create the Domain node
Rooted<Domain> domain =
@@ -57,7 +58,8 @@ void DomainHandler::end() { scope().pop(logger()); }
/* DomainStructHandler */
-bool DomainStructHandler::start(Variant::mapType &args)
+bool DomainStructHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
scope().setFlag(ParserFlag::POST_HEAD, true);
@@ -88,7 +90,8 @@ bool DomainStructHandler::start(Variant::mapType &args)
void DomainStructHandler::end() { scope().pop(logger()); }
/* DomainAnnotationHandler */
-bool DomainAnnotationHandler::start(Variant::mapType &args)
+bool DomainAnnotationHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
scope().setFlag(ParserFlag::POST_HEAD, true);
@@ -106,7 +109,8 @@ void DomainAnnotationHandler::end() { scope().pop(logger()); }
/* DomainAttributesHandler */
-bool DomainAttributesHandler::start(Variant::mapType &args)
+bool DomainAttributesHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
// Fetch the current typesystem and create the struct node
Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
@@ -122,7 +126,8 @@ void DomainAttributesHandler::end() { scope().pop(logger()); }
/* DomainFieldHandler */
-bool DomainFieldHandler::start(Variant::mapType &args)
+bool DomainFieldHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
FieldDescriptor::FieldType type;
if (args["isSubtree"].asBool()) {
@@ -152,15 +157,16 @@ void DomainFieldHandler::end() { scope().pop(logger()); }
/* DomainFieldRefHandler */
-bool DomainFieldRefHandler::start(Variant::mapType &args)
+bool DomainFieldRefHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
- const std::string &name = args["ref"].asString();
+ const std::string &ref = args["ref"].asString();
auto loc = location();
- scope().resolveFieldDescriptor(name, parent, logger(),
+ scope().resolveFieldDescriptor(ref, parent, logger(),
[loc](Handle<Node> field,
Handle<Node> parent, Logger &logger) {
if (field != nullptr) {
@@ -182,7 +188,8 @@ void DomainFieldRefHandler::end() {}
/* DomainPrimitiveHandler */
-bool DomainPrimitiveHandler::start(Variant::mapType &args)
+bool DomainPrimitiveHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
@@ -222,7 +229,8 @@ void DomainPrimitiveHandler::end() { scope().pop(logger()); }
/* DomainChildHandler */
-bool DomainChildHandler::start(Variant::mapType &args)
+bool DomainChildHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
Rooted<FieldDescriptor> field = scope().selectOrThrow<FieldDescriptor>();
@@ -240,7 +248,8 @@ bool DomainChildHandler::start(Variant::mapType &args)
/* DomainParentHandler */
-bool DomainParentHandler::start(Variant::mapType &args)
+bool DomainParentHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
Rooted<StructuredClass> strct = scope().selectOrThrow<StructuredClass>();
@@ -255,7 +264,8 @@ void DomainParentHandler::end() { scope().pop(logger()); }
/* DomainParentFieldHandler */
-bool DomainParentFieldHandler::start(Variant::mapType &args)
+bool DomainParentFieldHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
Rooted<DomainParent> parentNameNode = scope().selectOrThrow<DomainParent>();
FieldDescriptor::FieldType type;
@@ -265,7 +275,7 @@ bool DomainParentFieldHandler::start(Variant::mapType &args)
type = FieldDescriptor::FieldType::TREE;
}
- const std::string &name = args["name"].asString();
+ const std::string &fieldName = args["name"].asString();
const bool optional = args["optional"].asBool();
Rooted<StructuredClass> strct =
parentNameNode->getParent().cast<StructuredClass>();
@@ -274,12 +284,12 @@ bool DomainParentFieldHandler::start(Variant::mapType &args)
// StructuredClass as child to it.
scope().resolve<Descriptor>(
parentNameNode->getName(), strct, logger(),
- [type, name, optional](Handle<Node> parent, Handle<Node> strct,
- Logger &logger) {
+ [type, fieldName, optional](Handle<Node> parent, Handle<Node> strct,
+ Logger &logger) {
if (parent != nullptr) {
Rooted<FieldDescriptor> field =
(parent.cast<Descriptor>()->createFieldDescriptor(
- logger, type, name, optional)).first;
+ logger, type, fieldName, optional)).first;
field->addChild(strct.cast<StructuredClass>());
}
});
@@ -288,32 +298,32 @@ bool DomainParentFieldHandler::start(Variant::mapType &args)
/* DomainParentFieldRefHandler */
-bool DomainParentFieldRefHandler::start(Variant::mapType &args)
+bool DomainParentFieldRefHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
Rooted<DomainParent> parentNameNode = scope().selectOrThrow<DomainParent>();
- const std::string &name = args["ref"].asString();
+ const std::string &ref = args["ref"].asString();
Rooted<StructuredClass> strct =
parentNameNode->getParent().cast<StructuredClass>();
auto loc = location();
// resolve the parent, get the referenced field and add the declared
// StructuredClass as child to it.
- scope().resolve<Descriptor>(
- parentNameNode->getName(), strct, logger(),
- [name, loc](Handle<Node> parent, Handle<Node> strct, Logger &logger) {
- if (parent != nullptr) {
- Rooted<FieldDescriptor> field =
- parent.cast<Descriptor>()->getFieldDescriptor(name);
- if (field == nullptr) {
- logger.error(
- std::string("Could not find referenced field ") + name,
- loc);
- return;
- }
- field->addChild(strct.cast<StructuredClass>());
- }
- });
+ scope().resolve<Descriptor>(parentNameNode->getName(), strct, logger(),
+ [ref, loc](Handle<Node> parent,
+ Handle<Node> strct, Logger &logger) {
+ if (parent != nullptr) {
+ Rooted<FieldDescriptor> field =
+ parent.cast<Descriptor>()->getFieldDescriptor(ref);
+ if (field == nullptr) {
+ logger.error(
+ std::string("Could not find referenced field ") + ref, loc);
+ return;
+ }
+ field->addChild(strct.cast<StructuredClass>());
+ }
+ });
return true;
}
diff --git a/src/core/parser/stack/DomainHandler.hpp b/src/core/parser/stack/DomainHandler.hpp
index 76172d6..4116919 100644
--- a/src/core/parser/stack/DomainHandler.hpp
+++ b/src/core/parser/stack/DomainHandler.hpp
@@ -46,7 +46,7 @@ class DomainHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -59,7 +59,7 @@ class DomainStructHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -72,7 +72,7 @@ class DomainAnnotationHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -85,7 +85,7 @@ class DomainAttributesHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -98,7 +98,7 @@ class DomainFieldHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -111,7 +111,7 @@ class DomainFieldRefHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -124,7 +124,7 @@ class DomainPrimitiveHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -137,7 +137,7 @@ class DomainChildHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
static Handler *create(const HandlerData &handlerData)
{
@@ -154,7 +154,7 @@ class DomainParentHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
void end() override;
static Handler *create(const HandlerData &handlerData)
@@ -167,7 +167,7 @@ class DomainParentFieldHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
static Handler *create(const HandlerData &handlerData)
{
@@ -179,7 +179,7 @@ class DomainParentFieldRefHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &name, Variant::mapType &args) override;
static Handler *create(const HandlerData &handlerData)
{
diff --git a/src/core/parser/stack/Handler.cpp b/src/core/parser/stack/Handler.cpp
index 734976a..f9cefc2 100644
--- a/src/core/parser/stack/Handler.cpp
+++ b/src/core/parser/stack/Handler.cpp
@@ -32,13 +32,8 @@ namespace parser_stack {
/* Class HandlerData */
HandlerData::HandlerData(ParserContext &ctx, HandlerCallbacks &callbacks,
- const std::string &name, const State &state,
- const SourceLocation &location)
- : ctx(ctx),
- callbacks(callbacks),
- name(name),
- state(state),
- location(location)
+ const State &state, const SourceLocation &location)
+ : ctx(ctx), callbacks(callbacks), state(state), location(location)
{
}
@@ -67,22 +62,14 @@ Logger &Handler::logger()
const SourceLocation &Handler::location() const { return handlerData.location; }
-const std::string &Handler::name() const { return handlerData.name; }
-
-Variant Handler::readData()
-{
- return handlerData.callbacks.readData();
-}
+Variant Handler::readData() { return handlerData.callbacks.readData(); }
void Handler::pushTokens(const std::vector<TokenSyntaxDescriptor> &tokens)
{
handlerData.callbacks.pushTokens(tokens);
}
-void Handler::popTokens()
-{
- handlerData.callbacks.popTokens();
-}
+void Handler::popTokens() { handlerData.callbacks.popTokens(); }
TokenId Handler::registerToken(const std::string &token)
{
@@ -94,8 +81,6 @@ void Handler::unregisterToken(TokenId id)
handlerData.callbacks.unregisterToken(id);
}
-const std::string &Handler::getName() const { return name(); }
-
const State &Handler::getState() const { return handlerData.state; }
void Handler::setLogger(Logger &logger) { internalLogger = &logger; }
@@ -106,42 +91,51 @@ const SourceLocation &Handler::getLocation() const { return location(); }
/* Class EmptyHandler */
-bool EmptyHandler::start(Variant::mapType &args)
+bool EmptyHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
- // Just accept anything
+ // Well, we'll support any command we get, don't we?
return true;
}
-void EmptyHandler::end()
+bool EmptyHandler::startAnnotation(const std::string &name,
+ Variant::mapType &args,
+ Handler::AnnotationType annotationType)
{
- // Do nothing if a command ends
+ // Do not support annotations. Annotations are too complicated for poor
+ // EmptyHandler.
+ return false;
}
-bool EmptyHandler::fieldStart(bool &isDefaultField, size_t fieldIndex)
+bool EmptyHandler::startToken(const Token &token, Handle<Node> node)
{
- // Accept any field
- return true;
+ // EmptyHandler does not support tokens.
+ return false;
}
-void EmptyHandler::fieldEnd()
+Handler::EndTokenResult EmptyHandler::endToken(const Token &token,
+ Handle<Node> node)
{
- // Do not handle fields
+ // There are no tokens to end here.
+ return EndTokenResult::ENDED_NONE;
}
-bool EmptyHandler::annotationStart(const Variant &className,
- Variant::mapType &args)
+void EmptyHandler::end()
{
- // Accept any data
- return true;
+ // Do nothing if a command ends
}
-bool EmptyHandler::annotationEnd(const Variant &className,
- const Variant &elementName)
+bool EmptyHandler::fieldStart(bool &isDefaultField, size_t fieldIndex)
{
- // Accept any annotation
+ // Accept any field
return true;
}
+void EmptyHandler::fieldEnd()
+{
+ // Do not handle field ends
+}
+
bool EmptyHandler::data()
{
// Support any data
@@ -155,12 +149,31 @@ Handler *EmptyHandler::create(const HandlerData &handlerData)
/* Class StaticHandler */
-bool StaticHandler::start(Variant::mapType &args)
+bool StaticHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
// Do nothing in the default implementation, accept anything
return true;
}
+bool StaticHandler::startAnnotation(const std::string &name,
+ Variant::mapType &args,
+ Handler::AnnotationType annotationType)
+{
+ return false;
+}
+
+bool StaticHandler::startToken(const Token &token, Handle<Node> node)
+{
+ return false;
+}
+
+Handler::EndTokenResult StaticHandler::endToken(const Token &token,
+ Handle<Node> node)
+{
+ return EndTokenResult::ENDED_NONE;
+}
+
void StaticHandler::end()
{
// Do nothing here
@@ -182,20 +195,6 @@ void StaticHandler::fieldEnd()
// Do nothing here
}
-bool StaticHandler::annotationStart(const Variant &className,
- Variant::mapType &args)
-{
- // No annotations supported
- return false;
-}
-
-bool StaticHandler::annotationEnd(const Variant &className,
- const Variant &elementName)
-{
- // No annotations supported
- return false;
-}
-
bool StaticHandler::data()
{
logger().error("Did not expect any data here", readData());
@@ -210,7 +209,8 @@ StaticFieldHandler::StaticFieldHandler(const HandlerData &handlerData,
{
}
-bool StaticFieldHandler::start(Variant::mapType &args)
+bool StaticFieldHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
if (!argName.empty()) {
auto it = args.find(argName);
diff --git a/src/core/parser/stack/Handler.hpp b/src/core/parser/stack/Handler.hpp
index 19c3d65..f0968e7 100644
--- a/src/core/parser/stack/Handler.hpp
+++ b/src/core/parser/stack/Handler.hpp
@@ -25,6 +25,7 @@
#include <core/common/Variant.hpp>
#include <core/common/Whitespace.hpp>
#include <core/common/Token.hpp>
+#include <core/model/Node.hpp>
namespace ousia {
@@ -61,11 +62,6 @@ public:
HandlerCallbacks &callbacks;
/**
- * Contains the name of the command that is being handled.
- */
- std::string name;
-
- /**
* Contains the current state of the state machine.
*/
const State &state;
@@ -81,13 +77,11 @@ public:
* @param ctx is the parser context the handler should be executed in.
* @param callbacks is an instance of Callbacks used to notify
* the parser about certain state changes.
- * @param name is the name of the string.
* @param state is the state this handler was called for.
* @param location is the location at which the handler is created.
*/
HandlerData(ParserContext &ctx, HandlerCallbacks &callbacks,
- const std::string &name, const State &state,
- const SourceLocation &location);
+ const State &state, const SourceLocation &location);
};
/**
@@ -155,13 +149,6 @@ protected:
const SourceLocation &location() const;
/**
- * Returns the command name for which the handler was created.
- *
- * @return a const reference at the command name.
- */
- const std::string &name() const;
-
- /**
* Calls the corresponding function in the HandlerCallbacks instance. This
* method registers the given tokens as tokens that are generally available,
* tokens must be explicitly enabled using the "pushTokens" and "popTokens"
@@ -231,19 +218,23 @@ protected:
*/
// void popWhitespaceMode();
-
public:
/**
- * Virtual destructor.
+ * Enum representing the type of the annotation a Handle instance handles.
+ * It may either handle the start of an annotation or the end of an
+ * annotation.
*/
- virtual ~Handler();
+ enum class AnnotationType { START, END };
/**
- * Returns the command name for which the handler was created.
- *
- * @return a const reference at the command name.
+ * Enum type representing the possible outcomes of the endToken() method.
*/
- const std::string &getName() const;
+ enum class EndTokenResult { ENDED_THIS, ENDED_HIDDEN, ENDED_NONE };
+
+ /**
+ * Virtual destructor.
+ */
+ virtual ~Handler();
/**
* Reference at the State descriptor for which this Handler was created.
@@ -274,14 +265,63 @@ public:
const SourceLocation &getLocation() const;
/**
- * Called when the command that was specified in the constructor is
- * instanciated.
+ * Called whenever the handler should handle the start of a command. This
+ * method (or any other of the "start" methods) is called exactly once,
+ * after the constructor.
*
+ * @param name is the name of the command that is started here.
* @param args is a map from strings to variants (argument name and value).
- * @return true if the handler was successful in starting the element it
- * represents, false otherwise.
+ * @return true if the handler was successful in starting an element with
+ * the given name represents, false otherwise.
*/
- virtual bool start(Variant::mapType &args) = 0;
+ virtual bool startCommand(const std::string &commandName,
+ Variant::mapType &args) = 0;
+
+ /**
+ * Called whenever the handler should handle the start of an annotation.
+ * This method (or any other of the "start" methods) is called exactly once,
+ * after the constructor. This method is only called if the
+ * "supportsAnnotations" flag of the State instance referencing this Handler
+ * is set to true.
+ *
+ * @param name is the name of the annotation that is started here.
+ * @param args is a map from strings to variants (argument name and value).
+ * @param type specifies whether this handler should handle the start of an
+ * annotation or the end of an annotation.
+ */
+ virtual bool startAnnotation(const std::string &name,
+ Variant::mapType &args,
+ AnnotationType annotationType) = 0;
+
+ /**
+ * Called whenever the handler should handle the start of a token. This
+ * method (or any other of the "start" methods) is called exactly once,
+ * after the constructor. This method is only called if the "supportsTokens"
+ * flag of the State instance referencing this Handler is set to true.
+ *
+ * @param token is the Token for which the handler should be started.
+ * @param node is the node for which this token was registered.
+ */
+ virtual bool startToken(const Token &token, Handle<Node> node) = 0;
+
+ /**
+ * Called whenever a token is marked as "end" token and this handler happens
+ * to be the currently active handler. This operation may have three
+ * outcomes:
+ * <ol>
+ * <li>The token marks the end of the complete handler and the calling
+ * code should call the "end" method.</li>
+ * <li>The token marks the end of some element that is unknown the calling
+ * code. So the operation itself was a success, but the calling code
+ * should not call the "end" method.
+ * <li>The token did not anything in this context. Basically this shuold
+ * never happen, but who knows.</li>
+ * </ol>
+ *
+ * @param id is the Token for which the handler should be started.
+ * @param node is the node for which this token was registered.
+ */
+ virtual EndTokenResult endToken(const Token &token, Handle<Node> node) = 0;
/**
* Called before the command for which this handler is defined ends (is
@@ -311,35 +351,6 @@ public:
virtual void fieldEnd() = 0;
/**
- * Called whenever an annotation starts while this handler is active. The
- * function should return true if starting the annotation was successful,
- * false otherwise.
- *
- * @param className is a string variant containing the name of the
- * annotation class and the location of the name in the source code.
- * @param args is a map from strings to variants (argument name and value).
- * @return true if the mentioned annotation could be started here, false
- * if an error occurred.
- */
- virtual bool annotationStart(const Variant &className,
- Variant::mapType &args) = 0;
-
- /**
- * Called whenever an annotation ends while this handler is active. The
- * function should return true if ending the annotation was successful,
- * false otherwise.
- *
- * @param className is a string variant containing the name of the
- * annotation class and the location of the class name in the source code.
- * @param elementName is a string variant containing the name of the
- * annotation class and the location of the element name in the source code.
- * @return true if the mentioned annotation could be started here, false if
- * an error occurred.
- */
- virtual bool annotationEnd(const Variant &className,
- const Variant &elementName) = 0;
-
- /**
* Called whenever raw data (int the form of a string) is available for the
* Handler instance. Should return true if the data could be handled, false
* otherwise. The actual data variant must be retrieved using the "text()"
@@ -369,14 +380,15 @@ protected:
using Handler::Handler;
public:
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
+ bool startAnnotation(const std::string &name, Variant::mapType &args,
+ AnnotationType annotationType) override;
+ bool startToken(const Token &token, Handle<Node> node) override;
+ EndTokenResult endToken(const Token &token, Handle<Node> node) override;
void end() override;
bool fieldStart(bool &isDefault, size_t fieldIdx) override;
void fieldEnd() override;
- bool annotationStart(const Variant &className,
- Variant::mapType &args) override;
- bool annotationEnd(const Variant &className,
- const Variant &elementName) override;
bool data() override;
/**
@@ -395,14 +407,15 @@ protected:
using Handler::Handler;
public:
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
+ bool startAnnotation(const std::string &name, Variant::mapType &args,
+ AnnotationType annotationType) override;
+ bool startToken(const Token &token, Handle<Node> node) override;
+ EndTokenResult endToken(const Token &token, Handle<Node> node) override;
void end() override;
bool fieldStart(bool &isDefault, size_t fieldIdx) override;
void fieldEnd() override;
- bool annotationStart(const Variant &className,
- Variant::mapType &args) override;
- bool annotationEnd(const Variant &className,
- const Variant &elementName) override;
bool data() override;
};
@@ -453,9 +466,10 @@ protected:
virtual void doHandle(const Variant &fieldData, Variant::mapType &args) = 0;
public:
- bool start(Variant::mapType &args) override;
- void end() override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
bool data() override;
+ void end() override;
};
}
}
diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp
index a556999..3545c37 100644
--- a/src/core/parser/stack/Stack.cpp
+++ b/src/core/parser/stack/Stack.cpp
@@ -32,7 +32,7 @@
namespace ousia {
namespace parser_stack {
-
+namespace {
/* Class HandlerInfo */
/**
@@ -42,6 +42,11 @@ namespace parser_stack {
class HandlerInfo {
public:
/**
+ * Name of the command or the token sequence.
+ */
+ std::string name;
+
+ /**
* Pointer pointing at the actual handler instance.
*/
std::shared_ptr<Handler> handler;
@@ -96,6 +101,7 @@ public:
* Default constructor of the HandlerInfo class.
*/
HandlerInfo();
+
/**
* Constructor of the HandlerInfo class, allows to set all flags manually.
*/
@@ -182,6 +188,7 @@ void HandlerInfo::fieldEnd()
* Stub instance of HandlerInfo containing no handler information.
*/
static HandlerInfo EmptyHandlerInfo{true, true, true, true, false, true};
+}
/* Helper functions */
@@ -387,7 +394,7 @@ StackImpl::~StackImpl()
!info.inImplicitDefaultField) {
logger().error(
std::string("Reached end of stream, but command \"") +
- info.handler->getName() +
+ info.name +
"\" has not ended yet. Command was started here:",
info.handler->getLocation());
}
@@ -421,8 +428,8 @@ void StackImpl::deduceState()
HandlerConstructor ctor =
state.elementHandler ? state.elementHandler : EmptyHandler::create;
- std::shared_ptr<Handler> handler = std::shared_ptr<Handler>{
- ctor({ctx, *this, "", state, SourceLocation{}})};
+ std::shared_ptr<Handler> handler =
+ std::shared_ptr<Handler>{ctor({ctx, *this, state, SourceLocation{}})};
stack.emplace_back(handler);
// Set the correct flags for this implicit handler
@@ -450,7 +457,7 @@ const State &StackImpl::currentState() const
std::string StackImpl::currentCommandName() const
{
- return stack.empty() ? std::string{} : stack.back().handler->getName();
+ return stack.empty() ? std::string{} : stack.back().name;
}
const State *StackImpl::findTargetState(const std::string &name)
@@ -608,8 +615,8 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args,
HandlerConstructor ctor = targetState->elementHandler
? targetState->elementHandler
: EmptyHandler::create;
- std::shared_ptr<Handler> handler{ctor(
- {ctx, *this, name.asString(), *targetState, name.getLocation()})};
+ std::shared_ptr<Handler> handler{
+ ctor({ctx, *this, *targetState, name.getLocation()})};
stack.emplace_back(handler);
// Fetch the HandlerInfo for the parent element and the current element
@@ -631,7 +638,8 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args,
handler->setLogger(loggerFork);
try {
- info.valid = handler->start(canonicalArgs);
+ info.valid =
+ handler->startCommand(name.asString(), canonicalArgs);
}
catch (LoggableException ex) {
loggerFork.log(ex);
diff --git a/src/core/parser/stack/TypesystemHandler.cpp b/src/core/parser/stack/TypesystemHandler.cpp
index de8ee49..110c56f 100644
--- a/src/core/parser/stack/TypesystemHandler.cpp
+++ b/src/core/parser/stack/TypesystemHandler.cpp
@@ -32,7 +32,8 @@ namespace parser_stack {
/* TypesystemHandler */
-bool TypesystemHandler::start(Variant::mapType &args)
+bool TypesystemHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
// Create the typesystem instance
Rooted<Typesystem> typesystem =
@@ -63,7 +64,8 @@ void TypesystemHandler::end() { scope().pop(logger()); }
/* TypesystemEnumHandler */
-bool TypesystemEnumHandler::start(Variant::mapType &args)
+bool TypesystemEnumHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
scope().setFlag(ParserFlag::POST_HEAD, true);
@@ -91,17 +93,18 @@ void TypesystemEnumEntryHandler::doHandle(const Variant &fieldData,
/* TypesystemStructHandler */
-bool TypesystemStructHandler::start(Variant::mapType &args)
+bool TypesystemStructHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
scope().setFlag(ParserFlag::POST_HEAD, true);
// Fetch the arguments used for creating this type
- const std::string &name = args["name"].asString();
+ const std::string &structNmae = 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);
+ Rooted<StructType> structType = typesystem->createStructType(structNmae);
structType->setLocation(location());
// Try to resolve the parent type and set it as parent structure
@@ -124,18 +127,19 @@ void TypesystemStructHandler::end() { scope().pop(logger()); }
/* TypesystemStructFieldHandler */
-bool TypesystemStructFieldHandler::start(Variant::mapType &args)
+bool TypesystemStructFieldHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
// Read the argument values
- const std::string &name = args["name"].asString();
+ const std::string &fieldName = args["name"].asString();
const std::string &type = args["type"].asString();
const Variant &defaultValue = args["default"];
const bool optional =
!(defaultValue.isObject() && defaultValue.asObject() == nullptr);
Rooted<StructType> structType = scope().selectOrThrow<StructType>();
- Rooted<Attribute> attribute =
- structType->createAttribute(name, defaultValue, optional, logger());
+ Rooted<Attribute> attribute = structType->createAttribute(
+ fieldName, defaultValue, optional, logger());
attribute->setLocation(location());
// Try to resolve the type and default value
@@ -163,17 +167,18 @@ bool TypesystemStructFieldHandler::start(Variant::mapType &args)
/* TypesystemConstantHandler */
-bool TypesystemConstantHandler::start(Variant::mapType &args)
+bool TypesystemConstantHandler::startCommand(const std::string &commandName,
+ Variant::mapType &args)
{
scope().setFlag(ParserFlag::POST_HEAD, true);
// Read the argument values
- const std::string &name = args["name"].asString();
+ const std::string &constantName = args["name"].asString();
const std::string &type = args["type"].asString();
const Variant &value = args["value"];
Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>();
- Rooted<Constant> constant = typesystem->createConstant(name, value);
+ Rooted<Constant> constant = typesystem->createConstant(constantName, value);
constant->setLocation(location());
// Try to resolve the type
diff --git a/src/core/parser/stack/TypesystemHandler.hpp b/src/core/parser/stack/TypesystemHandler.hpp
index 85494f1..75cba01 100644
--- a/src/core/parser/stack/TypesystemHandler.hpp
+++ b/src/core/parser/stack/TypesystemHandler.hpp
@@ -43,7 +43,8 @@ class TypesystemHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
void end() override;
/**
@@ -67,7 +68,8 @@ class TypesystemEnumHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
void end() override;
/**
@@ -114,7 +116,8 @@ class TypesystemStructHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
void end() override;
/**
@@ -139,7 +142,8 @@ class TypesystemStructFieldHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
/**
* Creates a new instance of the TypesystemStructFieldHandler.
@@ -162,7 +166,8 @@ class TypesystemConstantHandler : public StaticHandler {
public:
using StaticHandler::StaticHandler;
- bool start(Variant::mapType &args) override;
+ bool startCommand(const std::string &commandName,
+ Variant::mapType &args) override;
/**
* Creates a new instance of the TypesystemConstantHandler.