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 --- 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 +--- 5 files changed, 106 insertions(+), 56 deletions(-) (limited to 'src/core') 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