From 84c9abc3e9762c4486ddc5ca0352a5d697a51987 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Wed, 25 Feb 2015 23:09:26 +0100 Subject: start of branch, commit log will be rewritten --- src/core/parser/stack/DocumentHandler.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/parser/stack/DocumentHandler.hpp') diff --git a/src/core/parser/stack/DocumentHandler.hpp b/src/core/parser/stack/DocumentHandler.hpp index 862081c..dda7d8b 100644 --- a/src/core/parser/stack/DocumentHandler.hpp +++ b/src/core/parser/stack/DocumentHandler.hpp @@ -167,7 +167,7 @@ public: bool start(Variant::mapType &args) override; void end() override; - bool data(Variant &data) override; + bool data(TokenizedData &data) override; bool fieldStart(bool &isDefault, size_t fieldIdx) override; @@ -213,4 +213,4 @@ extern const Rtti DocumentField; } } -#endif /* _OUSIA_PARSER_STACK_DOCUMENT_HANDLER_HPP_ */ \ No newline at end of file +#endif /* _OUSIA_PARSER_STACK_DOCUMENT_HANDLER_HPP_ */ -- cgit v1.2.3 From f65e7af0dd0028ec481360eeaa16c4ff95ce253b Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 2 Mar 2015 10:59:50 +0100 Subject: Got all handlers compling again --- CMakeLists.txt | 12 +-- src/core/parser/stack/DocumentHandler.cpp | 18 ++--- src/core/parser/stack/DocumentHandler.hpp | 4 +- src/core/parser/stack/Handler.hpp | 3 +- src/core/parser/stack/Stack.cpp | 123 +++++++++++++++++++++++------- src/core/parser/stack/Stack.hpp | 14 +--- 6 files changed, 112 insertions(+), 62 deletions(-) (limited to 'src/core/parser/stack/DocumentHandler.hpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index b206458..cef1e31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,16 +181,16 @@ ADD_LIBRARY(ousia_core src/core/parser/ParserContext src/core/parser/ParserScope src/core/parser/stack/Callbacks -# src/core/parser/stack/DocumentHandler -# src/core/parser/stack/DomainHandler -# src/core/parser/stack/GenericParserStates + src/core/parser/stack/DocumentHandler + src/core/parser/stack/DomainHandler + src/core/parser/stack/GenericParserStates src/core/parser/stack/Handler -# src/core/parser/stack/ImportIncludeHandler + src/core/parser/stack/ImportIncludeHandler src/core/parser/stack/State # src/core/parser/stack/Stack src/core/parser/stack/TokenRegistry src/core/parser/stack/TokenStack -# src/core/parser/stack/TypesystemHandler + src/core/parser/stack/TypesystemHandler src/core/parser/utils/SourceOffsetVector src/core/parser/utils/TokenizedData src/core/parser/utils/Tokenizer @@ -215,8 +215,8 @@ ADD_LIBRARY(ousia_core #) ADD_LIBRARY(ousia_osml - src/formats/osml/OsmlParser src/formats/osml/OsmlStreamParser + src/formats/osml/OsmlParser ) TARGET_LINK_LIBRARIES(ousia_osml diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp index d44176a..714ab1b 100644 --- a/src/core/parser/stack/DocumentHandler.cpp +++ b/src/core/parser/stack/DocumentHandler.cpp @@ -246,8 +246,6 @@ bool DocumentChildHandler::start(Variant::mapType &args) parent->getDescriptor()->getFieldDescriptorIndex(); } // create the entity for the new element at last. - // TODO: REMOVE - strct_name = strct->getName(); entity = parent->createChildStructuredEntity(strct, lastFieldIdx, args, nameAttr); } @@ -373,15 +371,8 @@ bool DocumentChildHandler::convertData(Handle field, return valid && scope().resolveValue(data, type, logger); } -bool DocumentChildHandler::data(TokenizedData &data) +bool DocumentChildHandler::data() { - // TODO: Handle this correctly - Variant text = data.text(WhitespaceMode::TRIM); - if (text == nullptr) { - // For now, except "no data" as success - return true; - } - // We're past the region in which explicit fields can be defined in the // parent structure element scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, true); @@ -401,6 +392,7 @@ bool DocumentChildHandler::data(TokenizedData &data) // If it is a primitive field directly, try to parse the content. if (field->isPrimitive()) { // Add it as primitive content. + Variant text = readData(); if (!convertData(field, text, logger())) { return false; } @@ -419,6 +411,10 @@ bool DocumentChildHandler::data(TokenizedData &data) for (auto primitiveField : defaultFields) { // Then try to parse the content using the type specification. forks.emplace_back(logger().fork()); + + // TODO: Actually the data has to be read after the path has been + // created (as createPath may push more tokens onto the stack) + Variant text = readData(); if (!convertData(primitiveField, text, forks.back())) { continue; } @@ -428,7 +424,6 @@ bool DocumentChildHandler::data(TokenizedData &data) // Construct the necessary path NodeVector path = field->pathTo(primitiveField, logger()); - // TODO: Create methods with indices instead of names. createPath(fieldIdx, path, parent); // Then create the primitive element @@ -439,6 +434,7 @@ bool DocumentChildHandler::data(TokenizedData &data) // No field was found that might take the data -- dump the error messages // from the loggers -- or, if there were no primitive fields, clearly state // this fact + Variant text = readData(); if (defaultFields.empty()) { logger().error("Got data, but structure \"" + name() + "\" does not have any primitive field", diff --git a/src/core/parser/stack/DocumentHandler.hpp b/src/core/parser/stack/DocumentHandler.hpp index dda7d8b..c51c188 100644 --- a/src/core/parser/stack/DocumentHandler.hpp +++ b/src/core/parser/stack/DocumentHandler.hpp @@ -93,8 +93,6 @@ public: class DocumentChildHandler : public Handler { private: bool isExplicitField = false; - //TODO: REMOVE - std::string strct_name; /** * Code shared by both the start(), fieldStart() and the data() method. @@ -167,7 +165,7 @@ public: bool start(Variant::mapType &args) override; void end() override; - bool data(TokenizedData &data) override; + bool data() override; bool fieldStart(bool &isDefault, size_t fieldIdx) override; diff --git a/src/core/parser/stack/Handler.hpp b/src/core/parser/stack/Handler.hpp index 848d395..377a214 100644 --- a/src/core/parser/stack/Handler.hpp +++ b/src/core/parser/stack/Handler.hpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace ousia { @@ -37,7 +38,7 @@ class Variant; namespace parser_stack { // More forward declarations -class Callbacks; +class HandlerCallbacks; class State; /** diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp index 292e7e2..ff03a6b 100644 --- a/src/core/parser/stack/Stack.cpp +++ b/src/core/parser/stack/Stack.cpp @@ -210,7 +210,6 @@ static LoggableException buildInvalidCommandException( /* Class StackImpl */ class StackImpl { - private: /** * Reference at the parser context. @@ -231,7 +230,7 @@ private: /** * Return the reference in the Logger instance stored within the context. */ - Logger &logger(); + Logger &logger() {return ctx.getLogger();} /** * Used internally to get all expected command names for the current state. @@ -311,12 +310,28 @@ private: * @return true if all handlers on the stack are valid. */ bool handlersValid(); -}; +public: + StackImpl(ParserContext &ctx, + const std::multimap &states); + + ~StackImpl(); -/* Class Stack */ + const State ¤tState() const; + std::string currentCommandName() const; -Stack::Stack(ParserContext &ctx, + void commandStart(const Variant &name, const Variant::mapType &args, + bool range); + void annotationStart(const Variant &className, const Variant &args, + bool range); + void annotationEnd(const Variant &className, const Variant &elementName); + void rangeEnd(); + void fieldStart(bool isDefault); + void fieldEnd(); + void data(const TokenizedData &data); +}; + +StackImpl::StackImpl(ParserContext &ctx, const std::multimap &states) : ctx(ctx), states(states) { @@ -327,7 +342,7 @@ Stack::Stack(ParserContext &ctx, } } -Stack::~Stack() +StackImpl::~StackImpl() { while (!stack.empty()) { // Fetch the topmost stack element @@ -351,7 +366,7 @@ Stack::~Stack() } } -void Stack::deduceState() +void StackImpl::deduceState() { // Assemble all states std::vector states; @@ -384,7 +399,7 @@ void Stack::deduceState() info.fieldStart(true, false, true); } -std::set Stack::expectedCommands() +std::set StackImpl::expectedCommands() { const State *currentState = &(this->currentState()); std::set res; @@ -396,17 +411,17 @@ std::set Stack::expectedCommands() return res; } -const State &Stack::currentState() +const State &StackImpl::currentState() { return stack.empty() ? States::None : stack.back().handler->getState(); } -std::string Stack::currentCommandName() +std::string StackImpl::currentCommandName() { return stack.empty() ? std::string{} : stack.back().handler->getName(); } -const State *Stack::findTargetState(const std::string &name) +const State *StackImpl::findTargetState(const std::string &name) { const State *currentState = &(this->currentState()); auto range = states.equal_range(name); @@ -420,7 +435,7 @@ const State *Stack::findTargetState(const std::string &name) return nullptr; } -const State *Stack::findTargetStateOrWildcard(const std::string &name) +const State *StackImpl::findTargetStateOrWildcard(const std::string &name) { // Try to find the target state with the given name, if none is found, try // find a matching "*" state. @@ -431,16 +446,16 @@ const State *Stack::findTargetStateOrWildcard(const std::string &name) return targetState; } -HandlerInfo &Stack::currentInfo() +HandlerInfo &StackImpl::currentInfo() { return stack.empty() ? EmptyHandlerInfo : stack.back(); } -HandlerInfo &Stack::lastInfo() +HandlerInfo &StackImpl::lastInfo() { return stack.size() < 2U ? EmptyHandlerInfo : stack[stack.size() - 2]; } -void Stack::endCurrentHandler() +void StackImpl::endCurrentHandler() { if (!stack.empty()) { // Fetch the handler info for the current top-level element @@ -467,7 +482,7 @@ void Stack::endCurrentHandler() } } -void Stack::endOverdueHandlers() +void StackImpl::endOverdueHandlers() { if (!stack.empty()) { // Fetch the handler info for the current top-level element @@ -483,7 +498,7 @@ void Stack::endOverdueHandlers() } } -bool Stack::ensureHandlerIsInField() +bool StackImpl::ensureHandlerIsInField() { // If the current handler is not in a field (and actually has a handler) // try to start a default field @@ -507,7 +522,7 @@ bool Stack::ensureHandlerIsInField() return true; } -bool Stack::handlersValid() +bool StackImpl::handlersValid() { for (auto it = stack.crbegin(); it != stack.crend(); it++) { if (!it->valid) { @@ -517,9 +532,7 @@ bool Stack::handlersValid() return true; } -Logger &Stack::logger() { return ctx.getLogger(); } - -void Stack::command(const Variant &name, const Variant::mapType &args) +void StackImpl::commandStart(const Variant &name, const Variant::mapType &args) { // End handlers that already had a default field and are currently not // active. @@ -611,7 +624,22 @@ void Stack::command(const Variant &name, const Variant::mapType &args) } } -void Stack::data(TokenizedData data) +void StackImpl::annotationStart(const Variant &className, const Variant &args) +{ + // TODO +} + +void StackImpl::annotationEnd(const Variant &className, const Variant &elementName) +{ + // TODO +} + +void StackImpl::rangeEnd() +{ + // TODO +} + +void StackImpl::data(TokenizedData data) { // TODO: Rewrite this function for token handling // TODO: This loop needs to be refactored out @@ -626,7 +654,8 @@ void Stack::data(TokenizedData data) // make sure the data actually is data if (stack.empty()) { if (hasNonWhitespaceText) { - throw LoggableException("No command here to receive data.", data); + throw LoggableException("No command here to receive data.", + data); } return; } @@ -699,7 +728,7 @@ void Stack::data(TokenizedData data) } } -void Stack::data(const Variant &stringData) +void StackImpl::data(const Variant &stringData) { // Fetch the SourceLocation of the given stringData variant SourceLocation loc = stringData.getLocation(); @@ -712,7 +741,7 @@ void Stack::data(const Variant &stringData) data(tokenizedData); } -void Stack::fieldStart(bool isDefault) +void StackImpl::fieldStart(bool isDefault) { // Make sure the current handler stack is not empty if (stack.empty()) { @@ -764,7 +793,7 @@ void Stack::fieldStart(bool isDefault) info.fieldStart(defaultField, false, valid); } -void Stack::fieldEnd() +void StackImpl::fieldEnd() { // Unroll the stack until the next explicitly open field while (!stack.empty()) { @@ -799,14 +828,50 @@ void Stack::fieldEnd() info.fieldEnd(); } -void Stack::annotationStart(const Variant &className, const Variant &args) +/* Class Stack */ + +Stack::Stack(ParserContext &ctx, + const std::multimap &states) + : impl(new StackImpl(ctx, states)) +{ +} + +Stack::~Stack() { - // TODO + // Do nothing here, stub needed because StackImpl is incomplete in hpp +} + +const State &Stack::currentState() const { return impl->currentState(); } + +std::string Stack::currentCommandName() const +{ + return impl->currentCommandName(); +} + +void Stack::commandStart(const Variant &name, const Variant::mapType &args, + bool range) +{ + impl->commandStart(name, args, range); +} + +void Stack::annotationStart(const Variant &className, const Variant &args, + bool range) +{ + impl->annotationStart(className, args, range); } void Stack::annotationEnd(const Variant &className, const Variant &elementName) { - // TODO + impl->annotationEnd(className, elementName); } + +void Stack::rangeEnd() { impl->rangeEnd(); } + +void Stack::fieldStart(bool isDefault) { impl->fieldStart(isDefault); } + +void Stack::fieldEnd() { impl->fieldEnd(); } + +void Stack::data(const TokenizedData &data) { impl->data(data); } +}; } } diff --git a/src/core/parser/stack/Stack.hpp b/src/core/parser/stack/Stack.hpp index e1173d0..1d87b9c 100644 --- a/src/core/parser/stack/Stack.hpp +++ b/src/core/parser/stack/Stack.hpp @@ -81,7 +81,7 @@ public: * @return the state of the currently active Handler instance or * States::None if no handler is on the stack. */ - const State ¤tState(); + const State ¤tState() const; /** * Returns the command name that is currently being handled. @@ -89,7 +89,7 @@ public: * @return the name of the command currently being handled by the active * Handler instance or an empty string if no handler is currently active. */ - std::string currentCommandName(); + std::string currentCommandName() const; /** * Function that should be called whenever a new command is reached. @@ -154,16 +154,6 @@ public: * that should be read. */ void data(const TokenizedData &data); - - /** - * Function that shuold be called whenever character data is found in the - * input stream. The given string variant is converted into a TokenizedData - * instance internally. - * - * @param stringData is a string variant containing the data that has been - * found. - */ - void data(const Variant &stringData); }; } } -- cgit v1.2.3 From 3cc6ebf406c53b0c82a52f0daf1ce14c62f7b521 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 2 Mar 2015 16:30:51 +0100 Subject: Implemented new "start" methods in the Handler instances --- CMakeLists.txt | 6 +- src/core/parser/stack/DocumentHandler.cpp | 133 +++++++++++++++--------- src/core/parser/stack/DocumentHandler.hpp | 69 ++++++++++--- src/core/parser/stack/DomainHandler.cpp | 76 ++++++++------ src/core/parser/stack/DomainHandler.hpp | 22 ++-- src/core/parser/stack/Handler.cpp | 102 +++++++++---------- src/core/parser/stack/Handler.hpp | 150 +++++++++++++++------------- src/core/parser/stack/Stack.cpp | 24 +++-- src/core/parser/stack/TypesystemHandler.cpp | 29 +++--- src/core/parser/stack/TypesystemHandler.hpp | 15 ++- 10 files changed, 375 insertions(+), 251 deletions(-) (limited to 'src/core/parser/stack/DocumentHandler.hpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index cef1e31..45310a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,7 +187,7 @@ ADD_LIBRARY(ousia_core src/core/parser/stack/Handler src/core/parser/stack/ImportIncludeHandler src/core/parser/stack/State -# src/core/parser/stack/Stack + src/core/parser/stack/Stack src/core/parser/stack/TokenRegistry src/core/parser/stack/TokenStack src/core/parser/stack/TypesystemHandler @@ -387,7 +387,7 @@ IF(TEST) # ) ADD_EXECUTABLE(ousia_test_osml -# test/formats/osml/OsmlParserTest + test/formats/osml/OsmlParserTest test/formats/osml/OsmlStreamParserTest ) @@ -400,7 +400,7 @@ IF(TEST) ADD_EXECUTABLE(ousia_test_osxml test/formats/osxml/OsxmlEventParserTest -# test/formats/osxml/OsxmlParserTest + test/formats/osxml/OsxmlParserTest ) TARGET_LINK_LIBRARIES(ousia_test_osxml 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 = 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 &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 strct = scope().resolve( - 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()->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 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 strct = scope().resolve( - 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) +{ + // Set the internal mode correctly + setMode(Mode::TOKEN, token); + + // TODO: Handle token start + return false; +} + +DocumentChildHandler::EndTokenResult DocumentChildHandler::endToken( + const Token &token, Handle 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 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()->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 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) override; + EndTokenResult endToken(const Token &token, Handle 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 = @@ -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 parent = scope().selectOrThrow(); @@ -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 parent = scope().selectOrThrow(); - 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 field, Handle 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 parent = scope().selectOrThrow(); @@ -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 field = scope().selectOrThrow(); @@ -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 strct = scope().selectOrThrow(); @@ -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 parentNameNode = scope().selectOrThrow(); 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 strct = parentNameNode->getParent().cast(); @@ -274,12 +284,12 @@ bool DomainParentFieldHandler::start(Variant::mapType &args) // StructuredClass as child to it. scope().resolve( parentNameNode->getName(), strct, logger(), - [type, name, optional](Handle parent, Handle strct, - Logger &logger) { + [type, fieldName, optional](Handle parent, Handle strct, + Logger &logger) { if (parent != nullptr) { Rooted field = (parent.cast()->createFieldDescriptor( - logger, type, name, optional)).first; + logger, type, fieldName, optional)).first; field->addChild(strct.cast()); } }); @@ -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 parentNameNode = scope().selectOrThrow(); - const std::string &name = args["ref"].asString(); + const std::string &ref = args["ref"].asString(); Rooted strct = parentNameNode->getParent().cast(); auto loc = location(); // resolve the parent, get the referenced field and add the declared // StructuredClass as child to it. - scope().resolve( - parentNameNode->getName(), strct, logger(), - [name, loc](Handle parent, Handle strct, Logger &logger) { - if (parent != nullptr) { - Rooted field = - parent.cast()->getFieldDescriptor(name); - if (field == nullptr) { - logger.error( - std::string("Could not find referenced field ") + name, - loc); - return; - } - field->addChild(strct.cast()); - } - }); + scope().resolve(parentNameNode->getName(), strct, logger(), + [ref, loc](Handle parent, + Handle strct, Logger &logger) { + if (parent != nullptr) { + Rooted field = + parent.cast()->getFieldDescriptor(ref); + if (field == nullptr) { + logger.error( + std::string("Could not find referenced field ") + ref, loc); + return; + } + field->addChild(strct.cast()); + } + }); 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 &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) { - // Accept any field - return true; + // EmptyHandler does not support tokens. + return false; } -void EmptyHandler::fieldEnd() +Handler::EndTokenResult EmptyHandler::endToken(const Token &token, + Handle 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) +{ + return false; +} + +Handler::EndTokenResult StaticHandler::endToken(const Token &token, + Handle 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 #include #include +#include namespace ousia { @@ -60,11 +61,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. */ @@ -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); }; /** @@ -154,13 +148,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, @@ -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) = 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: + *
    + *
  1. The token marks the end of the complete handler and the calling + * code should call the "end" method.
  2. + *
  3. 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. + *
  4. The token did not anything in this context. Basically this shuold + * never happen, but who knows.
  5. + *
+ * + * @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) = 0; /** * Called before the command for which this handler is defined ends (is @@ -310,35 +350,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 @@ -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) override; + EndTokenResult endToken(const Token &token, Handle 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) override; + EndTokenResult endToken(const Token &token, Handle 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 */ /** @@ -41,6 +41,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. */ @@ -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 = std::shared_ptr{ - ctor({ctx, *this, "", state, SourceLocation{}})}; + std::shared_ptr handler = + std::shared_ptr{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{ctor( - {ctx, *this, name.asString(), *targetState, name.getLocation()})}; + std::shared_ptr 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 = @@ -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 = scope().selectOrThrow(); - Rooted structType = typesystem->createStructType(name); + Rooted 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 = scope().selectOrThrow(); - Rooted attribute = - structType->createAttribute(name, defaultValue, optional, logger()); + Rooted 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 = scope().selectOrThrow(); - Rooted constant = typesystem->createConstant(name, value); + Rooted 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. -- cgit v1.2.3 From e0b9f6ef6692ee8c37386c23f721dc6a57f69ae6 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 2 Mar 2015 18:10:28 +0100 Subject: Storing type and name in the HandlerData once again, using a Token --- src/core/parser/stack/Callbacks.hpp | 3 +- src/core/parser/stack/DocumentHandler.cpp | 61 +++++-------------- src/core/parser/stack/DocumentHandler.hpp | 59 +++---------------- src/core/parser/stack/DomainHandler.cpp | 55 +++++++---------- src/core/parser/stack/DomainHandler.hpp | 22 +++---- src/core/parser/stack/Handler.cpp | 44 +++++++------- src/core/parser/stack/Stack.cpp | 91 +++++++++++++++++------------ src/core/parser/stack/TokenStack.hpp | 4 +- src/core/parser/stack/TypesystemHandler.cpp | 15 ++--- src/core/parser/stack/TypesystemHandler.hpp | 15 ++--- 10 files changed, 148 insertions(+), 221 deletions(-) (limited to 'src/core/parser/stack/DocumentHandler.hpp') diff --git a/src/core/parser/stack/Callbacks.hpp b/src/core/parser/stack/Callbacks.hpp index 092664a..dfe41fc 100644 --- a/src/core/parser/stack/Callbacks.hpp +++ b/src/core/parser/stack/Callbacks.hpp @@ -87,7 +87,8 @@ public: * @param tokens is a list of TokenSyntaxDescriptor instances that should be * stored on the stack. */ - void pushTokens(const std::vector &tokens); + virtual void pushTokens(const std::vector &tokens) = 0; + /** * Removes the previously pushed list of tokens from the stack. */ diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp index de6e367..e931d8d 100644 --- a/src/core/parser/stack/DocumentHandler.cpp +++ b/src/core/parser/stack/DocumentHandler.cpp @@ -37,8 +37,7 @@ namespace parser_stack { /* DocumentHandler */ -bool DocumentHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DocumentHandler::startCommand(Variant::mapType &args) { Rooted document = context().getProject()->createDocument(args["name"].asString()); @@ -54,24 +53,10 @@ void DocumentHandler::end() { scope().pop(logger()); } /* DocumentChildHandler */ DocumentChildHandler::DocumentChildHandler(const HandlerData &handlerData) - : Handler(handlerData), mode(Mode::STRUCT) + : Handler(handlerData), isExplicitField(false) { } -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 &parentNode, size_t &fieldIdx, DocumentEntity *&parent) { @@ -142,12 +127,8 @@ void DocumentChildHandler::createPath(const size_t &firstFieldIdx, scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, false); } -bool DocumentChildHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DocumentChildHandler::startCommand(Variant::mapType &args) { - // 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. @@ -176,11 +157,11 @@ bool DocumentChildHandler::startCommand(const std::string &commandName, return false; } Rooted strct = scope().resolve( - 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()->createRootStructuredEntity( @@ -200,7 +181,7 @@ bool DocumentChildHandler::startCommand(const std::string &commandName, */ { 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)) { @@ -208,7 +189,7 @@ bool DocumentChildHandler::startCommand(const std::string &commandName, std::string( "Data or structure commands have already been " "given, command \"") + - name + std::string( + name() + std::string( "\" is not interpreted explicit " "field. Move explicit field " "references to the beginning."), @@ -218,7 +199,7 @@ bool DocumentChildHandler::startCommand(const std::string &commandName, manager(), parentNode, newFieldIdx, false)}; field->setLocation(location()); scope().push(field); - setMode(Mode::EXPLICIT_FIELD, name); + isExplicitField = true; return true; } } @@ -227,11 +208,11 @@ bool DocumentChildHandler::startCommand(const std::string &commandName, // Otherwise create a new StructuredEntity // TODO: Consider Anchors and AnnotationEntities Rooted strct = scope().resolve( - 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()); } @@ -278,26 +259,15 @@ bool DocumentChildHandler::startCommand(const std::string &commandName, } } -bool DocumentChildHandler::startAnnotation(const std::string &name, - Variant::mapType &args, +bool DocumentChildHandler::startAnnotation(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) +bool DocumentChildHandler::startToken(Handle node) { - // Set the internal mode correctly - setMode(Mode::TOKEN, token); - // TODO: Handle token start return false; } @@ -313,7 +283,7 @@ void DocumentChildHandler::end() { // In case of explicit fields we do not want to pop something from the // stack. - if (mode == Mode::STRUCT) { + if (!isExplicitField) { // pop the "main" element. scope().pop(logger()); } @@ -321,8 +291,7 @@ void DocumentChildHandler::end() bool DocumentChildHandler::fieldStart(bool &isDefault, size_t fieldIdx) { - // TODO: Handle other cases - if (mode == Mode::EXPLICIT_FIELD) { + if (isExplicitField) { // In case of explicit fields we do not want to create another field. isDefault = true; return fieldIdx == 0; @@ -471,7 +440,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 { diff --git a/src/core/parser/stack/DocumentHandler.hpp b/src/core/parser/stack/DocumentHandler.hpp index 9a41508..d34c020 100644 --- a/src/core/parser/stack/DocumentHandler.hpp +++ b/src/core/parser/stack/DocumentHandler.hpp @@ -53,8 +53,7 @@ class DocumentHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &commandName, - Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; void end() override; /** @@ -92,55 +91,11 @@ 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: /** - * 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. + * If set to true, this handler represents an explicit field. */ - 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); + bool isExplicitField; /** * Code shared by both the start(), fieldStart() and the data() method. @@ -211,11 +166,10 @@ private: public: DocumentChildHandler(const HandlerData &handlerData); - bool startCommand(const std::string &commandName, - Variant::mapType &args) override; - bool startAnnotation(const std::string &name, Variant::mapType &args, + bool startCommand(Variant::mapType &args) override; + bool startAnnotation(Variant::mapType &args, AnnotationType annotationType) override; - bool startToken(const Token &token, Handle node) override; + bool startToken(Handle node) override; EndTokenResult endToken(const Token &token, Handle node) override; void end() override; bool data() override; @@ -257,3 +211,4 @@ extern const Rtti DocumentField; } #endif /* _OUSIA_PARSER_STACK_DOCUMENT_HANDLER_HPP_ */ + diff --git a/src/core/parser/stack/DomainHandler.cpp b/src/core/parser/stack/DomainHandler.cpp index 5ca4f5b..aef5b47 100644 --- a/src/core/parser/stack/DomainHandler.cpp +++ b/src/core/parser/stack/DomainHandler.cpp @@ -33,8 +33,7 @@ namespace parser_stack { /* DomainHandler */ -bool DomainHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainHandler::startCommand(Variant::mapType &args) { // Create the Domain node Rooted domain = @@ -58,8 +57,7 @@ void DomainHandler::end() { scope().pop(logger()); } /* DomainStructHandler */ -bool DomainStructHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainStructHandler::startCommand(Variant::mapType &args) { scope().setFlag(ParserFlag::POST_HEAD, true); @@ -90,8 +88,7 @@ bool DomainStructHandler::startCommand(const std::string &commandName, void DomainStructHandler::end() { scope().pop(logger()); } /* DomainAnnotationHandler */ -bool DomainAnnotationHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainAnnotationHandler::startCommand(Variant::mapType &args) { scope().setFlag(ParserFlag::POST_HEAD, true); @@ -109,8 +106,7 @@ void DomainAnnotationHandler::end() { scope().pop(logger()); } /* DomainAttributesHandler */ -bool DomainAttributesHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainAttributesHandler::startCommand(Variant::mapType &args) { // Fetch the current typesystem and create the struct node Rooted parent = scope().selectOrThrow(); @@ -126,8 +122,7 @@ void DomainAttributesHandler::end() { scope().pop(logger()); } /* DomainFieldHandler */ -bool DomainFieldHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainFieldHandler::startCommand(Variant::mapType &args) { FieldDescriptor::FieldType type; if (args["isSubtree"].asBool()) { @@ -157,16 +152,15 @@ void DomainFieldHandler::end() { scope().pop(logger()); } /* DomainFieldRefHandler */ -bool DomainFieldRefHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainFieldRefHandler::startCommand(Variant::mapType &args) { Rooted parent = scope().selectOrThrow(); - const std::string &ref = args["ref"].asString(); + const std::string &name = args["ref"].asString(); auto loc = location(); - scope().resolveFieldDescriptor(ref, parent, logger(), + scope().resolveFieldDescriptor(name, parent, logger(), [loc](Handle field, Handle parent, Logger &logger) { if (field != nullptr) { @@ -188,8 +182,7 @@ void DomainFieldRefHandler::end() {} /* DomainPrimitiveHandler */ -bool DomainPrimitiveHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainPrimitiveHandler::startCommand(Variant::mapType &args) { Rooted parent = scope().selectOrThrow(); @@ -229,14 +222,13 @@ void DomainPrimitiveHandler::end() { scope().pop(logger()); } /* DomainChildHandler */ -bool DomainChildHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainChildHandler::startCommand(Variant::mapType &args) { Rooted field = scope().selectOrThrow(); - const std::string &ref = args["ref"].asString(); + const std::string &name = args["ref"].asString(); scope().resolve( - ref, field, logger(), + name, field, logger(), [](Handle child, Handle field, Logger &logger) { if (child != nullptr) { field.cast()->addChild( @@ -248,8 +240,7 @@ bool DomainChildHandler::startCommand(const std::string &commandName, /* DomainParentHandler */ -bool DomainParentHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainParentHandler::startCommand(Variant::mapType &args) { Rooted strct = scope().selectOrThrow(); @@ -264,8 +255,7 @@ void DomainParentHandler::end() { scope().pop(logger()); } /* DomainParentFieldHandler */ -bool DomainParentFieldHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainParentFieldHandler::startCommand(Variant::mapType &args) { Rooted parentNameNode = scope().selectOrThrow(); FieldDescriptor::FieldType type; @@ -275,7 +265,7 @@ bool DomainParentFieldHandler::startCommand(const std::string &commandName, type = FieldDescriptor::FieldType::TREE; } - const std::string &fieldName = args["name"].asString(); + const std::string &name = args["name"].asString(); const bool optional = args["optional"].asBool(); Rooted strct = parentNameNode->getParent().cast(); @@ -284,12 +274,12 @@ bool DomainParentFieldHandler::startCommand(const std::string &commandName, // StructuredClass as child to it. scope().resolve( parentNameNode->getName(), strct, logger(), - [type, fieldName, optional](Handle parent, Handle strct, + [type, name, optional](Handle parent, Handle strct, Logger &logger) { if (parent != nullptr) { Rooted field = (parent.cast()->createFieldDescriptor( - logger, type, fieldName, optional)).first; + logger, type, name, optional)).first; field->addChild(strct.cast()); } }); @@ -298,12 +288,11 @@ bool DomainParentFieldHandler::startCommand(const std::string &commandName, /* DomainParentFieldRefHandler */ -bool DomainParentFieldRefHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool DomainParentFieldRefHandler::startCommand(Variant::mapType &args) { Rooted parentNameNode = scope().selectOrThrow(); - const std::string &ref = args["ref"].asString(); + const std::string &name = args["ref"].asString(); Rooted strct = parentNameNode->getParent().cast(); auto loc = location(); @@ -311,14 +300,14 @@ bool DomainParentFieldRefHandler::startCommand(const std::string &commandName, // resolve the parent, get the referenced field and add the declared // StructuredClass as child to it. scope().resolve(parentNameNode->getName(), strct, logger(), - [ref, loc](Handle parent, + [name, loc](Handle parent, Handle strct, Logger &logger) { if (parent != nullptr) { Rooted field = - parent.cast()->getFieldDescriptor(ref); + parent.cast()->getFieldDescriptor(name); if (field == nullptr) { logger.error( - std::string("Could not find referenced field ") + ref, loc); + std::string("Could not find referenced field ") + name, loc); return; } field->addChild(strct.cast()); diff --git a/src/core/parser/stack/DomainHandler.hpp b/src/core/parser/stack/DomainHandler.hpp index 4116919..f12d863 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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; static Handler *create(const HandlerData &handlerData) { @@ -154,7 +154,7 @@ class DomainParentHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; static Handler *create(const HandlerData &handlerData) { @@ -179,7 +179,7 @@ class DomainParentFieldRefHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &name, Variant::mapType &args) override; + bool startCommand(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 006e521..c01e74c 100644 --- a/src/core/parser/stack/Handler.cpp +++ b/src/core/parser/stack/Handler.cpp @@ -32,8 +32,9 @@ namespace parser_stack { /* Class HandlerData */ HandlerData::HandlerData(ParserContext &ctx, HandlerCallbacks &callbacks, - const State &state, const SourceLocation &location) - : ctx(ctx), callbacks(callbacks), state(state), location(location) + const State &state, const Token &token, + HandlerType type) + : ctx(ctx), callbacks(callbacks), state(state), token(token), type(type) { } @@ -60,7 +61,20 @@ Logger &Handler::logger() return handlerData.ctx.getLogger(); } -const SourceLocation &Handler::location() const { return handlerData.location; } +const std::string &Handler::name() const { return handlerData.token.content; } + +TokenId Handler::tokenId() const { return handlerData.token.id; } + +const Token &Handler::token() const { return handlerData.token; } + +const SourceLocation &Handler::location() const +{ + return handlerData.token.location; +} + +HandlerType Handler::type() const { return handlerData.type; } + +const State &Handler::state() const { return handlerData.state; } Variant Handler::readData() { return handlerData.callbacks.readData(); } @@ -81,8 +95,6 @@ void Handler::unregisterToken(TokenId id) handlerData.callbacks.unregisterToken(id); } -const State &Handler::getState() const { return handlerData.state; } - void Handler::setLogger(Logger &logger) { internalLogger = &logger; } void Handler::resetLogger() { internalLogger = nullptr; } @@ -91,15 +103,13 @@ const SourceLocation &Handler::getLocation() const { return location(); } /* Class EmptyHandler */ -bool EmptyHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool EmptyHandler::startCommand(Variant::mapType &args) { // Well, we'll support any command we get, don't we? return true; } -bool EmptyHandler::startAnnotation(const std::string &name, - Variant::mapType &args, +bool EmptyHandler::startAnnotation(Variant::mapType &args, Handler::AnnotationType annotationType) { // Do not support annotations. Annotations are too complicated for poor @@ -107,7 +117,7 @@ bool EmptyHandler::startAnnotation(const std::string &name, return false; } -bool EmptyHandler::startToken(const Token &token, Handle node) +bool EmptyHandler::startToken(Handle node) { // EmptyHandler does not support tokens. return false; @@ -149,24 +159,19 @@ Handler *EmptyHandler::create(const HandlerData &handlerData) /* Class StaticHandler */ -bool StaticHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool StaticHandler::startCommand(Variant::mapType &args) { // Do nothing in the default implementation, accept anything return true; } -bool StaticHandler::startAnnotation(const std::string &name, - Variant::mapType &args, +bool StaticHandler::startAnnotation(Variant::mapType &args, Handler::AnnotationType annotationType) { return false; } -bool StaticHandler::startToken(const Token &token, Handle node) -{ - return false; -} +bool StaticHandler::startToken(Handle node) { return false; } Handler::EndTokenResult StaticHandler::endToken(const Token &token, Handle node) @@ -209,8 +214,7 @@ StaticFieldHandler::StaticFieldHandler(const HandlerData &handlerData, { } -bool StaticFieldHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool StaticFieldHandler::startCommand(Variant::mapType &args) { if (!argName.empty()) { auto it = args.find(argName); diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp index 3545c37..cad4078 100644 --- a/src/core/parser/stack/Stack.cpp +++ b/src/core/parser/stack/Stack.cpp @@ -41,11 +41,6 @@ namespace { */ class HandlerInfo { public: - /** - * Name of the command or the token sequence. - */ - std::string name; - /** * Pointer pointing at the actual handler instance. */ @@ -362,7 +357,7 @@ public: void unregisterToken(TokenId id) override; Variant readData() override; bool hasData(); - void pushTokens(const std::vector &tokens) override; + void pushTokens(const std::vector &tokens) override; void popTokens() override; }; @@ -394,7 +389,7 @@ StackImpl::~StackImpl() !info.inImplicitDefaultField) { logger().error( std::string("Reached end of stream, but command \"") + - info.name + + currentCommandName() + "\" has not ended yet. Command was started here:", info.handler->getLocation()); } @@ -428,8 +423,8 @@ void StackImpl::deduceState() HandlerConstructor ctor = state.elementHandler ? state.elementHandler : EmptyHandler::create; - std::shared_ptr handler = - std::shared_ptr{ctor({ctx, *this, state, SourceLocation{}})}; + std::shared_ptr handler = std::shared_ptr{ + ctor({ctx, *this, state, SourceLocation{}, HandlerType::COMMAND})}; stack.emplace_back(handler); // Set the correct flags for this implicit handler @@ -452,12 +447,12 @@ std::set StackImpl::expectedCommands() const State &StackImpl::currentState() const { - return stack.empty() ? States::None : stack.back().handler->getState(); + return stack.empty() ? States::None : stack.back().handler->state(); } std::string StackImpl::currentCommandName() const { - return stack.empty() ? std::string{} : stack.back().name; + return stack.empty() ? std::string{} : stack.back().handler->name(); } const State *StackImpl::findTargetState(const std::string &name) @@ -616,21 +611,29 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args, ? targetState->elementHandler : EmptyHandler::create; std::shared_ptr handler{ - ctor({ctx, *this, *targetState, name.getLocation()})}; + ctor({ctx, + *this, + *targetState, + {name.asString(), name.getLocation()}, + HandlerType::COMMAND})}; stack.emplace_back(handler); - // Fetch the HandlerInfo for the parent element and the current element + // Fetch the HandlerInfo for the parent element and the current + // element HandlerInfo &parentInfo = lastInfo(); HandlerInfo &info = currentInfo(); - // Call the "start" method of the handler, store the result of the start - // method as the validity of the handler -- do not call the start method + // Call the "start" method of the handler, store the result of the + // start + // method as the validity of the handler -- do not call the start + // method // if the stack is currently invalid (as this may cause further, // unwanted errors) bool validStack = handlersValid(); info.valid = false; if (validStack) { - // Canonicalize the arguments (if this has not already been done), + // Canonicalize the arguments (if this has not already been + // done), // allow additional arguments and numeric indices Variant::mapType canonicalArgs = args; targetState->arguments.validateMap(canonicalArgs, loggerFork, true, @@ -638,8 +641,7 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args, handler->setLogger(loggerFork); try { - info.valid = - handler->startCommand(name.asString(), canonicalArgs); + info.valid = handler->startCommand(canonicalArgs); } catch (LoggableException ex) { loggerFork.log(ex); @@ -647,8 +649,10 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args, handler->resetLogger(); } - // We started the command within an implicit default field and it is not - // valid -- remove both the new handler and the parent field from the + // We started the command within an implicit default field and it is + // not + // valid -- remove both the new handler and the parent field from + // the // stack if (!info.valid && parentInfo.inImplicitDefaultField) { endCurrentHandler(); @@ -656,7 +660,8 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args, continue; } - // If we ended up here, starting the command may or may not have worked, + // If we ended up here, starting the command may or may not have + // worked, // but after all, we cannot unroll the stack any further. Update the // "valid" flag, commit any potential error messages and return. info.valid = parentInfo.valid && info.valid; @@ -687,13 +692,15 @@ void StackImpl::data(const TokenizedData &data) // TODO: Rewrite this function for token handling // TODO: This loop needs to be refactored out /*while (!data.atEnd()) { - // End handlers that already had a default field and are currently not + // End handlers that already had a default field and are currently + not // active. endOverdueHandlers(); const bool hasNonWhitespaceText = data.hasNonWhitespaceText(); - // Check whether there is any command the data can be sent to -- if not, + // Check whether there is any command the data can be sent to -- if + not, // make sure the data actually is data if (stack.empty()) { if (hasNonWhitespaceText) { @@ -712,10 +719,12 @@ void StackImpl::data(const TokenizedData &data) continue; } - // If this field should not get any data, log an error and do not call + // If this field should not get any data, log an error and do not + call // the "data" handler if (!info.inValidField) { - // If the "hadDefaultField" flag is set, we already issued an error + // If the "hadDefaultField" flag is set, we already issued an + error // message if (!info.hadDefaultField) { if (hasNonWhitespaceText) { @@ -726,8 +735,10 @@ void StackImpl::data(const TokenizedData &data) } if (handlersValid() && info.inValidField) { - // Fork the logger and set it as temporary logger for the "start" - // method. We only want to keep error messages if this was not a try + // Fork the logger and set it as temporary logger for the + "start" + // method. We only want to keep error messages if this was not a + try // to implicitly open a default field. LoggerFork loggerFork = logger().fork(); info.handler->setLogger(loggerFork); @@ -735,12 +746,14 @@ void StackImpl::data(const TokenizedData &data) // Pass the data to the current Handler instance bool valid = false; try { - // Create a fork of the TokenizedData and let the handler work + // Create a fork of the TokenizedData and let the handler + work // on it TokenizedData dataFork = data; valid = info.handler->data(dataFork); - // If the data was validly handled by the handler, commit the + // If the data was validly handled by the handler, commit + the // change if (valid) { data = dataFork; @@ -754,14 +767,16 @@ void StackImpl::data(const TokenizedData &data) info.handler->resetLogger(); // If placing the data here failed and we're currently in an - // implicitly opened field, just unroll the stack to the next field + // implicitly opened field, just unroll the stack to the next + field // and try again if (!valid && info.inImplicitDefaultField) { endCurrentHandler(); continue; } - // Commit the content of the logger fork. Do not change the valid + // Commit the content of the logger fork. Do not change the + valid // flag. loggerFork.commit(); } @@ -783,12 +798,14 @@ void StackImpl::fieldStart(bool isDefault) HandlerInfo &info = currentInfo(); if (info.inField) { logger().error( - "Got field start, but there is no command for which to start the " + "Got field start, but there is no command for which to start " + "the " "field."); return; } - // If the handler already had a default field we cannot start a new field + // If the handler already had a default field we cannot start a new + // field // (the default field always is the last field) -- mark the command as // invalid if (info.hadDefaultField) { @@ -797,7 +814,8 @@ void StackImpl::fieldStart(bool isDefault) std::string("\" does not have any more fields")); } - // Copy the isDefault flag to a local variable, the fieldStart method will + // Copy the isDefault flag to a local variable, the fieldStart method + // will // write into this variable bool defaultField = isDefault; @@ -843,7 +861,8 @@ void StackImpl::fieldEnd() return; } - // Only continue if the current handler stack is in a valid state, do not + // Only continue if the current handler stack is in a valid state, do + // not // call the fieldEnd function if something went wrong before if (handlersValid() && !info.hadDefaultField && info.inValidField) { try { @@ -868,7 +887,7 @@ void StackImpl::unregisterToken(TokenId id) tokenRegistry.unregisterToken(id); } -void StackImpl::pushTokens(const std::vector &tokens) +void StackImpl::pushTokens(const std::vector &tokens) { // TODO } diff --git a/src/core/parser/stack/TokenStack.hpp b/src/core/parser/stack/TokenStack.hpp index af734bb..f2e7edc 100644 --- a/src/core/parser/stack/TokenStack.hpp +++ b/src/core/parser/stack/TokenStack.hpp @@ -82,9 +82,9 @@ public: TokenStack(const TokenStack &parentStack) : TokenStack(&parentStack) {} /** - * Pushes a list of TokenSyntaxDescriptor instances onto the internal stack. + * Pushes a list of SyntaxDescriptor instances onto the internal stack. * - * @param tokens is a list of TokenSyntaxDescriptor instances that should be + * @param tokens is a list of SyntaxDescriptor instances that should be * stored on the stack. */ void pushTokens(const std::vector &tokens); diff --git a/src/core/parser/stack/TypesystemHandler.cpp b/src/core/parser/stack/TypesystemHandler.cpp index 110c56f..3fa641a 100644 --- a/src/core/parser/stack/TypesystemHandler.cpp +++ b/src/core/parser/stack/TypesystemHandler.cpp @@ -32,8 +32,7 @@ namespace parser_stack { /* TypesystemHandler */ -bool TypesystemHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool TypesystemHandler::startCommand(Variant::mapType &args) { // Create the typesystem instance Rooted typesystem = @@ -64,8 +63,7 @@ void TypesystemHandler::end() { scope().pop(logger()); } /* TypesystemEnumHandler */ -bool TypesystemEnumHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool TypesystemEnumHandler::startCommand(Variant::mapType &args) { scope().setFlag(ParserFlag::POST_HEAD, true); @@ -93,8 +91,7 @@ void TypesystemEnumEntryHandler::doHandle(const Variant &fieldData, /* TypesystemStructHandler */ -bool TypesystemStructHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool TypesystemStructHandler::startCommand(Variant::mapType &args) { scope().setFlag(ParserFlag::POST_HEAD, true); @@ -127,8 +124,7 @@ void TypesystemStructHandler::end() { scope().pop(logger()); } /* TypesystemStructFieldHandler */ -bool TypesystemStructFieldHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool TypesystemStructFieldHandler::startCommand(Variant::mapType &args) { // Read the argument values const std::string &fieldName = args["name"].asString(); @@ -167,8 +163,7 @@ bool TypesystemStructFieldHandler::startCommand(const std::string &commandName, /* TypesystemConstantHandler */ -bool TypesystemConstantHandler::startCommand(const std::string &commandName, - Variant::mapType &args) +bool TypesystemConstantHandler::startCommand(Variant::mapType &args) { scope().setFlag(ParserFlag::POST_HEAD, true); diff --git a/src/core/parser/stack/TypesystemHandler.hpp b/src/core/parser/stack/TypesystemHandler.hpp index 75cba01..0773a3a 100644 --- a/src/core/parser/stack/TypesystemHandler.hpp +++ b/src/core/parser/stack/TypesystemHandler.hpp @@ -43,8 +43,7 @@ class TypesystemHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &commandName, - Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; void end() override; /** @@ -68,8 +67,7 @@ class TypesystemEnumHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &commandName, - Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; void end() override; /** @@ -116,8 +114,7 @@ class TypesystemStructHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &commandName, - Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; void end() override; /** @@ -142,8 +139,7 @@ class TypesystemStructFieldHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &commandName, - Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; /** * Creates a new instance of the TypesystemStructFieldHandler. @@ -166,8 +162,7 @@ class TypesystemConstantHandler : public StaticHandler { public: using StaticHandler::StaticHandler; - bool startCommand(const std::string &commandName, - Variant::mapType &args) override; + bool startCommand(Variant::mapType &args) override; /** * Creates a new instance of the TypesystemConstantHandler. -- cgit v1.2.3