From 7a8b4eb8b9d943959b919076596ec96ef0c4c03c Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 2 Mar 2015 00:36:18 +0100 Subject: Adapted Callbacks interface and Handlers --- src/core/parser/stack/Callbacks.hpp | 68 ++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 28 deletions(-) (limited to 'src/core/parser/stack/Callbacks.hpp') diff --git a/src/core/parser/stack/Callbacks.hpp b/src/core/parser/stack/Callbacks.hpp index 9c61000..d7b2547 100644 --- a/src/core/parser/stack/Callbacks.hpp +++ b/src/core/parser/stack/Callbacks.hpp @@ -30,66 +30,78 @@ #define _OUSIA_PARSER_STACK_CALLBACKS_HPP_ #include +#include #include +#include namespace ousia { + +// Forward declarations +class Variant; + namespace parser_stack { /** - * Interface defining a set of callback functions that act as a basis for the - * StateStackCallbacks and the ParserCallbacks. + * Interface between the Stack class and the underlying parser used for + * registering and unregistering tokens. */ -class Callbacks { +class ParserCallbacks { public: /** * Virtual descructor. */ - virtual ~Callbacks() {}; - - /** - * Sets the whitespace mode that specifies how string data should be - * processed. - * - * @param whitespaceMode specifies one of the three WhitespaceMode constants - * PRESERVE, TRIM or COLLAPSE. - */ - virtual void setWhitespaceMode(WhitespaceMode whitespaceMode) = 0; + virtual ~ParserCallbacks(); /** * Registers the given token as token that should be reported to the handler * using the "token" function. * * @param token is the token string that should be reported. + * @return the token id with which the token will be reported. Should return + * Tokens::Empty if the given token could not be registered. */ - virtual void registerToken(const std::string &token) = 0; + virtual TokenId registerToken(const std::string &token) = 0; /** * Unregisters the given token, it will no longer be reported to the handler * using the "token" function. * - * @param token is the token string that should be unregistered. + * @param id is the token id of the token that should be unregistered. */ - virtual void unregisterToken(const std::string &token) = 0; + virtual void unregisterToken(TokenId id) = 0; }; /** - * Interface defining the callback functions that can be passed from a - * StateStack to the underlying parser. + * Interface defining a set of callback functions that act as a basis for the + * StateStackCallbacks and the ParserCallbacks. */ -class ParserCallbacks : public Callbacks { +class HandlerCallbacks: public ParserCallbacks { +public: /** - * Checks whether the given token is supported by the parser. The parser - * returns true, if the token is supported, false if this token cannot be - * registered. Note that parsers that do not support the registration of - * tokens at all should always return "true". + * Reads a string variant form the current input stream. This function must + * be called from the data() method. * - * @param token is the token that should be checked for support. - * @return true if the token is generally supported (or the parser does not - * support registering tokens at all), false if the token is not supported, - * because e.g. it is a reserved token or it interferes with other tokens. + * @return a string variant containing the current text data. The return + * value depends on the currently set whitespace mode and the tokens that + * were enabled using the enableTokens callback method. + */ + Variant readData(); + + /** + * Pushes a list of TokenSyntaxDescriptor instances onto the internal stack. + * The tokens described in the token list are the tokens that are currently + * enabled. + * + * @param tokens is a list of TokenSyntaxDescriptor instances that should be + * stored on the stack. + */ + void pushTokens(const std::vector &tokens); + + /** + * Removes the previously pushed list of tokens from the stack. */ - virtual bool supportsToken(const std::string &token) = 0; + void popTokens(); }; } -- cgit v1.2.3 From 5b81f755a5303c3eab05c605711ecca32c071b6d Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 2 Mar 2015 11:46:47 +0100 Subject: Got Stack compiling again --- src/core/parser/stack/Callbacks.hpp | 28 ++-- src/core/parser/stack/Handler.hpp | 75 ++++----- src/core/parser/stack/Stack.cpp | 297 ++++++++++++++++++++++-------------- src/core/parser/stack/Stack.hpp | 5 +- src/formats/osml/OsmlParser.cpp | 2 +- src/formats/osxml/OsxmlParser.cpp | 15 +- 6 files changed, 251 insertions(+), 171 deletions(-) (limited to 'src/core/parser/stack/Callbacks.hpp') diff --git a/src/core/parser/stack/Callbacks.hpp b/src/core/parser/stack/Callbacks.hpp index d7b2547..8acc02d 100644 --- a/src/core/parser/stack/Callbacks.hpp +++ b/src/core/parser/stack/Callbacks.hpp @@ -76,18 +76,8 @@ public: * Interface defining a set of callback functions that act as a basis for the * StateStackCallbacks and the ParserCallbacks. */ -class HandlerCallbacks: public ParserCallbacks { +class HandlerCallbacks : public ParserCallbacks { public: - /** - * Reads a string variant form the current input stream. This function must - * be called from the data() method. - * - * @return a string variant containing the current text data. The return - * value depends on the currently set whitespace mode and the tokens that - * were enabled using the enableTokens callback method. - */ - Variant readData(); - /** * Pushes a list of TokenSyntaxDescriptor instances onto the internal stack. * The tokens described in the token list are the tokens that are currently @@ -96,14 +86,24 @@ 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. */ - void popTokens(); -}; + virtual void popTokens() = 0; + /** + * Reads a string variant form the current input stream. This function must + * be called from the data() method. + * + * @return a string variant containing the current text data. The return + * value depends on the currently set whitespace mode and the tokens that + * were enabled using the enableTokens callback method. + */ + virtual Variant readData() = 0; +}; } } diff --git a/src/core/parser/stack/Handler.hpp b/src/core/parser/stack/Handler.hpp index 377a214..19c3d65 100644 --- a/src/core/parser/stack/Handler.hpp +++ b/src/core/parser/stack/Handler.hpp @@ -161,6 +161,44 @@ protected: */ const std::string &name() const; + /** + * Calls the corresponding function in the HandlerCallbacks instance. This + * method registers the given tokens as tokens that are generally available, + * tokens must be explicitly enabled using the "pushTokens" and "popTokens" + * method. Tokens that have not been registered are not guaranteed to be + * reported (except for special tokens, these do not have to be registerd). + * + * @param token is the token string that should be made available. + * @return the TokenId that will be used to refer to the token. + */ + TokenId registerToken(const std::string &token); + + /** + * Calls the corresponding function in the HandlerCallbacks instance. This + * method unregisters the given token. Note that for a token to be no longer + * reported, this function has to be called as many times as registerToken() + * for the corresponding token. + * + * @param id is the id of the Token that should be unregistered. + */ + void unregisterToken(TokenId id); + + /** + * Pushes a list of TokenSyntaxDescriptor instances onto the internal stack. + * The tokens described in the token list are the tokens that are currently + * enabled. + * + * @param tokens is a list of TokenSyntaxDescriptor instances that should be + * stored on the stack. + */ + void pushTokens(const std::vector &tokens); + + /** + * Calls the corresponding function in the HandlerCallbacks instance. + * Removes the previously pushed list of tokens from the stack. + */ + void popTokens(); + /** * Calls the corresponding method in the HandlerCallbacks instance. Reads a * string variant form the current input stream. This function must be @@ -193,43 +231,6 @@ protected: */ // void popWhitespaceMode(); - /** - * Pushes a list of TokenSyntaxDescriptor instances onto the internal stack. - * The tokens described in the token list are the tokens that are currently - * enabled. - * - * @param tokens is a list of TokenSyntaxDescriptor instances that should be - * stored on the stack. - */ - void pushTokens(const std::vector &tokens); - - /** - * Calls the corresponding function in the HandlerCallbacks instance. - * Removes the previously pushed list of tokens from the stack. - */ - void popTokens(); - - /** - * Calls the corresponding function in the HandlerCallbacks instance. This - * method registers the given tokens as tokens that are generally available, - * tokens must be explicitly enabled using the "pushTokens" and "popTokens" - * method. Tokens that have not been registered are not guaranteed to be - * reported (except for special tokens, these do not have to be registerd). - * - * @param token is the token string that should be made available. - * @return the TokenId that will be used to refer to the token. - */ - TokenId registerToken(const std::string &token); - - /** - * Calls the corresponding function in the HandlerCallbacks instance. This - * method unregisters the given token. Note that for a token to be no longer - * reported, this function has to be called as many times as registerToken() - * for the corresponding token. - * - * @param id is the id of the Token that should be unregistered. - */ - void unregisterToken(TokenId id); public: /** diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp index ff03a6b..a556999 100644 --- a/src/core/parser/stack/Stack.cpp +++ b/src/core/parser/stack/Stack.cpp @@ -23,9 +23,12 @@ #include #include +#include "Callbacks.hpp" #include "Handler.hpp" #include "Stack.hpp" #include "State.hpp" +#include "TokenRegistry.hpp" +#include "TokenStack.hpp" namespace ousia { namespace parser_stack { @@ -209,8 +212,14 @@ static LoggableException buildInvalidCommandException( /* Class StackImpl */ -class StackImpl { +class StackImpl : public HandlerCallbacks { private: + /** + * Reference at an implementation of the ParserCallbacks instance to which + * certain handler callbacks are directed. + */ + ParserCallbacks &parser; + /** * Reference at the parser context. */ @@ -222,6 +231,18 @@ private: */ const std::multimap &states; + /** + * Registry responsible for registering the tokens proposed by the + * Handlers in the parser. + */ + TokenRegistry tokenRegistry; + + /** + * Pointer at a TokenizedDataReader instance from which the data should + * currently be read. + */ + TokenizedDataReader *dataReader; + /** * Internal stack used for managing the currently active Handler instances. */ @@ -230,7 +251,7 @@ private: /** * Return the reference in the Logger instance stored within the context. */ - Logger &logger() {return ctx.getLogger();} + Logger &logger() { return ctx.getLogger(); } /** * Used internally to get all expected command names for the current state. @@ -312,8 +333,8 @@ private: bool handlersValid(); public: - StackImpl(ParserContext &ctx, - const std::multimap &states); + StackImpl(ParserCallbacks &parser, ParserContext &ctx, + const std::multimap &states); ~StackImpl(); @@ -329,11 +350,22 @@ public: void fieldStart(bool isDefault); void fieldEnd(); void data(const TokenizedData &data); + + TokenId registerToken(const std::string &token) override; + void unregisterToken(TokenId id) override; + Variant readData() override; + bool hasData(); + void pushTokens(const std::vector &tokens) override; + void popTokens() override; }; -StackImpl::StackImpl(ParserContext &ctx, - const std::multimap &states) - : ctx(ctx), states(states) +StackImpl::StackImpl(ParserCallbacks &parser, ParserContext &ctx, + const std::multimap &states) + : parser(parser), + ctx(ctx), + states(states), + tokenRegistry(parser), + dataReader(nullptr) { // If the scope instance is not empty we need to deduce the current parser // state @@ -389,8 +421,8 @@ void StackImpl::deduceState() HandlerConstructor ctor = state.elementHandler ? state.elementHandler : EmptyHandler::create; - std::shared_ptr handler = - std::shared_ptr{ctor({ctx, "", 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 @@ -411,12 +443,12 @@ std::set StackImpl::expectedCommands() return res; } -const State &StackImpl::currentState() +const State &StackImpl::currentState() const { return stack.empty() ? States::None : stack.back().handler->getState(); } -std::string StackImpl::currentCommandName() +std::string StackImpl::currentCommandName() const { return stack.empty() ? std::string{} : stack.back().handler->getName(); } @@ -532,7 +564,8 @@ bool StackImpl::handlersValid() return true; } -void StackImpl::commandStart(const Variant &name, const Variant::mapType &args) +void StackImpl::commandStart(const Variant &name, const Variant::mapType &args, + bool range) { // End handlers that already had a default field and are currently not // active. @@ -575,8 +608,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, name.asString(), *targetState, name.getLocation()})}; + std::shared_ptr handler{ctor( + {ctx, *this, name.asString(), *targetState, name.getLocation()})}; stack.emplace_back(handler); // Fetch the HandlerInfo for the parent element and the current element @@ -624,12 +657,14 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args) } } -void StackImpl::annotationStart(const Variant &className, const Variant &args) +void StackImpl::annotationStart(const Variant &className, const Variant &args, + bool range) { // TODO } -void StackImpl::annotationEnd(const Variant &className, const Variant &elementName) +void StackImpl::annotationEnd(const Variant &className, + const Variant &elementName) { // TODO } @@ -639,106 +674,93 @@ void StackImpl::rangeEnd() // TODO } -void StackImpl::data(TokenizedData data) +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 - // active. - endOverdueHandlers(); - - const bool hasNonWhitespaceText = data.hasNonWhitespaceText(); - - // 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) { - throw LoggableException("No command here to receive data.", - data); - } - return; - } - - // Fetch the current command handler information - HandlerInfo &info = currentInfo(); - - // Make sure the current handler has an open field - if (!ensureHandlerIsInField()) { - endCurrentHandler(); - continue; - } - - // 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 - // message - if (!info.hadDefaultField) { - if (hasNonWhitespaceText) { - logger().error("Did not expect any data here", data); - } - return; - } - } - - 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 - // to implicitly open a default field. - LoggerFork loggerFork = logger().fork(); - info.handler->setLogger(loggerFork); - - // Pass the data to the current Handler instance - bool valid = false; - try { - // 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 - // change - if (valid) { - data = dataFork; - } - } - catch (LoggableException ex) { - loggerFork.log(ex); - } - - // Reset the logger instance as soon as possible - 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 - // and try again - if (!valid && info.inImplicitDefaultField) { - endCurrentHandler(); - continue; - } - - // Commit the content of the logger fork. Do not change the valid - // flag. - loggerFork.commit(); - } - - // There was no reason to unroll the stack any further, so continue - return; - } -} - -void StackImpl::data(const Variant &stringData) -{ - // Fetch the SourceLocation of the given stringData variant - SourceLocation loc = stringData.getLocation(); - - // Create a TokenizedData instance and feed the given string data into it - TokenizedData tokenizedData(loc.getSourceId()); - tokenizedData.append(stringData.asString(), loc.getStart()); - - // Call the actual "data" method - data(tokenizedData); + /*while (!data.atEnd()) { + // 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, + // make sure the data actually is data + if (stack.empty()) { + if (hasNonWhitespaceText) { + throw LoggableException("No command here to receive data.", + data); + } + return; + } + + // Fetch the current command handler information + HandlerInfo &info = currentInfo(); + + // Make sure the current handler has an open field + if (!ensureHandlerIsInField()) { + endCurrentHandler(); + continue; + } + + // 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 + // message + if (!info.hadDefaultField) { + if (hasNonWhitespaceText) { + logger().error("Did not expect any data here", data); + } + return; + } + } + + 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 + // to implicitly open a default field. + LoggerFork loggerFork = logger().fork(); + info.handler->setLogger(loggerFork); + + // Pass the data to the current Handler instance + bool valid = false; + try { + // 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 + // change + if (valid) { + data = dataFork; + } + } + catch (LoggableException ex) { + loggerFork.log(ex); + } + + // Reset the logger instance as soon as possible + 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 + // and try again + if (!valid && info.inImplicitDefaultField) { + endCurrentHandler(); + continue; + } + + // Commit the content of the logger fork. Do not change the valid + // flag. + loggerFork.commit(); + } + + // There was no reason to unroll the stack any further, so continue + return; + }*/ } void StackImpl::fieldStart(bool isDefault) @@ -828,11 +850,55 @@ void StackImpl::fieldEnd() info.fieldEnd(); } +TokenId StackImpl::registerToken(const std::string &token) +{ + return tokenRegistry.registerToken(token); +} + +void StackImpl::unregisterToken(TokenId id) +{ + tokenRegistry.unregisterToken(id); +} + +void StackImpl::pushTokens(const std::vector &tokens) +{ + // TODO +} + +void StackImpl::popTokens() +{ + // TODO +} + +Variant StackImpl::readData() +{ + if (dataReader != nullptr) { + TokenizedDataReaderFork dataReaderFork = dataReader->fork(); + Token token; + + // TODO: Use correct token set + TokenSet tokens; + + // TODO: Use correct whitespace mode + WhitespaceMode mode = WhitespaceMode::COLLAPSE; + + dataReaderFork.read(token, tokens, mode); + if (token.id == Tokens::Data) { + Variant res = Variant::fromString(token.content); + res.setLocation(token.getLocation()); + return res; + } + } + return Variant{}; +} + +bool StackImpl::hasData() { return readData() != nullptr; } + /* Class Stack */ -Stack::Stack(ParserContext &ctx, +Stack::Stack(ParserCallbacks &parser, ParserContext &ctx, const std::multimap &states) - : impl(new StackImpl(ctx, states)) + : impl(new StackImpl(parser, ctx, states)) { } @@ -872,6 +938,5 @@ 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 1d87b9c..de281d4 100644 --- a/src/core/parser/stack/Stack.hpp +++ b/src/core/parser/stack/Stack.hpp @@ -42,6 +42,7 @@ class Variant; namespace parser_stack { // Forward declarations +class ParserCallbacks; class StackImpl; class State; @@ -63,11 +64,13 @@ public: /** * Creates a new instance of the Stack class. * + * @param parser is an implementation of the ParserCallbacks instance to + * which certain calls are directed. * @param ctx is the parser context the parser stack is working on. * @param states is a map containing the command names and pointers at the * corresponding State instances. */ - Stack(ParserContext &ctx, + Stack(ParserCallbacks &parser, ParserContext &ctx, const std::multimap &states); /** diff --git a/src/formats/osml/OsmlParser.cpp b/src/formats/osml/OsmlParser.cpp index c25974f..36ef2b6 100644 --- a/src/formats/osml/OsmlParser.cpp +++ b/src/formats/osml/OsmlParser.cpp @@ -73,7 +73,7 @@ public: : logger(ctx.getLogger()), ctx(ctx), parser(reader, logger), - stack(ctx, GenericParserStates) + stack(parser, ctx, GenericParserStates) { } diff --git a/src/formats/osxml/OsxmlParser.cpp b/src/formats/osxml/OsxmlParser.cpp index afe0dc6..10cc77a 100644 --- a/src/formats/osxml/OsxmlParser.cpp +++ b/src/formats/osxml/OsxmlParser.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -32,7 +33,7 @@ using namespace parser_stack; /** * Class containing the actual OsxmlParser implementation. */ -class OsxmlParserImplementation : public OsxmlEvents { +class OsxmlParserImplementation : public OsxmlEvents, ParserCallbacks { private: /** * Actual xml parser -- converts the xml stream into a set of events. @@ -56,7 +57,7 @@ public: */ OsxmlParserImplementation(CharReader &reader, ParserContext &ctx) : parser(reader, *this, ctx.getLogger()), - stack(ctx, GenericParserStates) + stack(*this, ctx, GenericParserStates) { } @@ -86,6 +87,16 @@ public: void rangeEnd() override { stack.rangeEnd(); } void data(const TokenizedData &data) override { stack.data(data); } + + TokenId registerToken(const std::string &token) override + { + return Tokens::Empty; + } + + void unregisterToken(TokenId id) override + { + // Do nothing here + } }; /* Class OsxmlParser */ -- cgit v1.2.3 From 5d6ee07995c7f59e66e0df558c8ebe7d2a8d1f68 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Mon, 2 Mar 2015 15:52:13 +0100 Subject: refactored SyntaxDescriptor to Token.hpp and added TokenDescriptor class. --- CMakeLists.txt | 1 + src/core/common/Token.cpp | 14 --- src/core/common/Token.hpp | 67 +----------- src/core/model/Syntax.cpp | 58 +++++++++++ src/core/model/Syntax.hpp | 196 +++++++++++++++++++++++++++++++++++ src/core/parser/stack/Callbacks.hpp | 3 +- src/core/parser/stack/Handler.cpp | 2 +- src/core/parser/stack/Handler.hpp | 3 +- src/core/parser/stack/TokenStack.cpp | 4 +- src/core/parser/stack/TokenStack.hpp | 5 +- 10 files changed, 266 insertions(+), 87 deletions(-) create mode 100644 src/core/model/Syntax.cpp create mode 100644 src/core/model/Syntax.hpp (limited to 'src/core/parser/stack/Callbacks.hpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index b206458..13de9ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,7 @@ ADD_LIBRARY(ousia_core src/core/model/Project src/core/model/RootNode src/core/model/Style + src/core/model/Syntax src/core/model/Typesystem src/core/parser/Parser src/core/parser/ParserContext diff --git a/src/core/common/Token.cpp b/src/core/common/Token.cpp index e454ae4..17ce03e 100644 --- a/src/core/common/Token.cpp +++ b/src/core/common/Token.cpp @@ -20,19 +20,5 @@ namespace ousia { -/* Class TokenSyntaxDescriptor */ - -void TokenSyntaxDescriptor::insertIntoTokenSet(TokenSet &set) const -{ - if (start != Tokens::Empty) { - set.insert(start); - } - if (end != Tokens::Empty) { - set.insert(end); - } - if (shortForm != Tokens::Empty) { - set.insert(shortForm); - } -} } diff --git a/src/core/common/Token.hpp b/src/core/common/Token.hpp index f89a0ce..f37151f 100644 --- a/src/core/common/Token.hpp +++ b/src/core/common/Token.hpp @@ -173,71 +173,6 @@ struct Token { const SourceLocation &getLocation() const { return location; } }; -/** - * Class describing the user defined syntax for a single field or annotation. - */ -struct TokenSyntaxDescriptor { - /** - * Possible start token or Tokens::Empty if no token is set. - */ - TokenId start; - - /** - * Possible end token or Tokens::Empty if no token is set. - */ - TokenId end; - - /** - * Possible representation token or Tokens::Empty if no token is set. - */ - TokenId shortForm; - - /** - * Flag specifying whether this TokenSyntaxDescriptor describes an - * annotation. - */ - bool isAnnotation; - - /** - * Default constructor, sets all token ids to Tokens::Empty and isAnnotation - * to false. - */ - TokenSyntaxDescriptor() - : start(Tokens::Empty), - end(Tokens::Empty), - shortForm(Tokens::Empty), - isAnnotation(false) - { - } - - /** - * Member initializer constructor. - * - * @param start is a possible start token. - * @param end is a possible end token. - * @param shortForm is a possible short form token. - * @param isAnnotation is set to true if this syntax descriptor describes an - * annotation. - */ - TokenSyntaxDescriptor(TokenId start, TokenId end, TokenId shortForm, - bool isAnnotation) - : start(start), - end(end), - shortForm(shortForm), - isAnnotation(isAnnotation) - { - } - - /** - * Inserts all tokens referenced in this TokenSyntaxDescriptor into the - * given TokenSet. Skips token ids set to Tokens::Empty. - * - * @param set is the TokenSet instance into which the Tokens should be - * inserted. - */ - void insertIntoTokenSet(TokenSet &set) const; -}; } -#endif /* _OUSIA_TOKENS_HPP_ */ - +#endif /* _OUSIA_TOKENS_HPP_ */ \ No newline at end of file diff --git a/src/core/model/Syntax.cpp b/src/core/model/Syntax.cpp new file mode 100644 index 0000000..9dbaccc --- /dev/null +++ b/src/core/model/Syntax.cpp @@ -0,0 +1,58 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "Syntax.hpp" + +#include "Domain.hpp" + +namespace ousia { + +/* Class TokenSyntaxDescriptor */ + +bool SyntaxDescriptor::isAnnotation() const +{ + return descriptor->isa(&RttiTypes::AnnotationClass); +} +bool SyntaxDescriptor::isFieldDescriptor() const +{ + return descriptor->isa(&RttiTypes::FieldDescriptor); +} +bool SyntaxDescriptor::isStruct() const +{ + return descriptor->isa(&RttiTypes::StructuredClass); +} + +void SyntaxDescriptor::insertIntoTokenSet(TokenSet &set) const +{ + if (start != Tokens::Empty) { + set.insert(start); + } + if (end != Tokens::Empty) { + set.insert(end); + } + if (shortForm != Tokens::Empty) { + set.insert(shortForm); + } +} + +bool SyntaxDescriptor::isEmpty() const +{ + return start == Tokens::Empty && end == Tokens::Empty && + shortForm == Tokens::Empty; +} +} \ No newline at end of file diff --git a/src/core/model/Syntax.hpp b/src/core/model/Syntax.hpp new file mode 100644 index 0000000..4da3408 --- /dev/null +++ b/src/core/model/Syntax.hpp @@ -0,0 +1,196 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file Syntax.hpp + * + * This header contains the Descriptor classes for user definable syntax for + * Document entities or fields. These classes are referenced in Ontology.hpp. + */ + +#ifndef _OUSIA_MODEL_SYNTAX_HPP_ +#define _OUSIA_MODEL_SYNTAX_HPP_ + +#include +#include "Node.hpp" + +namespace ousia { + +/** + * Class to describe a single token that shall be used as user-defined syntax. + */ +struct TokenDescriptor { + /** + * The string content of this token, if it is not a special one. + */ + std::string token; + /** + * A flag to be set true if this TokenDescriptor uses a special token. + */ + bool special; + /** + * An id to uniquely identify this token. + */ + TokenId id; + + /** + * Constructor for non-special tokens. The special flag is set to false and + * the id to Tokens::Empty. + * + * @param token The string content of this token, if it is not a special + * one. + */ + TokenDescriptor(std::string token = std::string()) + : token(std::move(token)), special(false), id(Tokens::Empty) + { + } + + /** + * Constructor for special tokens. The token is set to an empty string and + * the special flag to true. + * + * @param id the id of the special token. + */ + TokenDescriptor(TokenId id) : special(true), id(id) {} + + /** + * Returns true if and only if neither a string nor an ID is given. + * + * @return true if and only if neither a string nor an ID is given. + */ + bool isEmpty() const { return token.empty() && id == Tokens::Empty; } +}; + +/** + * Class describing the user defined syntax for a StructuredClass, + * AnnotationClass or FieldDescriptor. + * + * This class is used during parsing of a Document. It is used to describe + * the tokens relevant for one Descriptor that could be created at this point + * during parsing. + */ +struct SyntaxDescriptor { + /** + * Possible start token or Tokens::Empty if no token is set. + */ + TokenId start; + + /** + * Possible end token or Tokens::Empty if no token is set. + */ + TokenId end; + + /** + * Possible representation token or Tokens::Empty if no token is set. + */ + TokenId shortForm; + + /* + * The Descriptor this SyntaxDescriptor belongs to. As this may be + * a FieldDescriptor as well as a class Descriptor (StructuredClass or + * AnnotationClass) we can only use the class Node as inner argument here. + */ + Rooted descriptor; + /* + * Given the current leaf in the parsed document the depth of a + * SyntaxDescriptor is defined as the number of transparent elements that + * would be needed to construct an instance of the referenced descriptor. + */ + ssize_t depth; + + /** + * Default constructor, sets all token ids to Tokens::Empty and the + * descriptor handle to nullptr. + */ + SyntaxDescriptor() + : start(Tokens::Empty), + end(Tokens::Empty), + shortForm(Tokens::Empty), + descriptor(nullptr), + depth(-1) + { + } + + /** + * Member initializer constructor. + * + * @param start is a possible start token. + * @param end is a possible end token. + * @param shortForm is a possible short form token. + * @param descriptor The Descriptor this SyntaxDescriptor belongs to. + * @param depth Given the current leaf in the parsed document the depth of a + * SyntaxDescriptor is defined as the number of transparent elements that + * would be needed to construct an instance of the referenced descriptor. + */ + SyntaxDescriptor(TokenId start, TokenId end, TokenId shortForm, + Handle descriptor, ssize_t depth) + : start(start), + end(end), + shortForm(shortForm), + descriptor(descriptor), + depth(depth) + { + } + + /** + * Inserts all tokens referenced in this SyntaxDescriptor into the + * given TokenSet. Skips token ids set to Tokens::Empty. + * + * @param set is the TokenSet instance into which the Tokens should be + * inserted. + */ + void insertIntoTokenSet(TokenSet &set) const; + + /** + * Returns true if and only if this SyntaxDescriptor belongs to an + * AnnotationClass. + * + * @return true if and only if this SyntaxDescriptor belongs to an + * AnnotationClass. + */ + bool isAnnotation() const; + + /** + * Returns true if and only if this SyntaxDescriptor belongs to a + * StrcturedClass. + * + * @return true if and only if this SyntaxDescriptor belongs to a + * StrcturedClass. + */ + bool isStruct() const; + + /** + * Returns true if and only if this SyntaxDescriptor belongs to a + * FieldDescriptor. + * + * @return true if and only if this SyntaxDescriptor belongs to a + * FieldDescriptor. + */ + bool isFieldDescriptor() const; + + /** + * Returns true if and only if this SyntaxDescriptor has only empty + * entries in start, end and short. + * + * @return true if and only if this SyntaxDescriptor has only empty + * entries in start, end and short. + */ + bool isEmpty() const; +}; +} +#endif \ No newline at end of file diff --git a/src/core/parser/stack/Callbacks.hpp b/src/core/parser/stack/Callbacks.hpp index d7b2547..e471881 100644 --- a/src/core/parser/stack/Callbacks.hpp +++ b/src/core/parser/stack/Callbacks.hpp @@ -34,6 +34,7 @@ #include #include +#include namespace ousia { @@ -96,7 +97,7 @@ public: * @param tokens is a list of TokenSyntaxDescriptor instances that should be * stored on the stack. */ - void pushTokens(const std::vector &tokens); + void pushTokens(const std::vector &tokens); /** * Removes the previously pushed list of tokens from the stack. diff --git a/src/core/parser/stack/Handler.cpp b/src/core/parser/stack/Handler.cpp index 734976a..12df0fd 100644 --- a/src/core/parser/stack/Handler.cpp +++ b/src/core/parser/stack/Handler.cpp @@ -74,7 +74,7 @@ Variant Handler::readData() return handlerData.callbacks.readData(); } -void Handler::pushTokens(const std::vector &tokens) +void Handler::pushTokens(const std::vector &tokens) { handlerData.callbacks.pushTokens(tokens); } diff --git a/src/core/parser/stack/Handler.hpp b/src/core/parser/stack/Handler.hpp index 848d395..19660d0 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 { @@ -200,7 +201,7 @@ protected: * @param tokens is a list of TokenSyntaxDescriptor instances that should be * stored on the stack. */ - void pushTokens(const std::vector &tokens); + void pushTokens(const std::vector &tokens); /** * Calls the corresponding function in the HandlerCallbacks instance. diff --git a/src/core/parser/stack/TokenStack.cpp b/src/core/parser/stack/TokenStack.cpp index 6afeaed..ac1d94e 100644 --- a/src/core/parser/stack/TokenStack.cpp +++ b/src/core/parser/stack/TokenStack.cpp @@ -21,7 +21,7 @@ namespace ousia { namespace parser_stack { -void TokenStack::pushTokens(const std::vector &tokens) +void TokenStack::pushTokens(const std::vector &tokens) { stack.push_back(tokens); } @@ -35,7 +35,7 @@ TokenSet TokenStack::tokens() const } TokenSet res; - for (const TokenSyntaxDescriptor &descr : stack.back()) { + for (const SyntaxDescriptor &descr : stack.back()) { descr.insertIntoTokenSet(res); } return res; diff --git a/src/core/parser/stack/TokenStack.hpp b/src/core/parser/stack/TokenStack.hpp index 9669f50..af734bb 100644 --- a/src/core/parser/stack/TokenStack.hpp +++ b/src/core/parser/stack/TokenStack.hpp @@ -32,6 +32,7 @@ #include #include +#include namespace ousia { namespace parser_stack { @@ -52,7 +53,7 @@ private: * Stack containing vectors of TokenSyntaxDescriptor instances as given by * the user. */ - std::vector> stack; + std::vector> stack; /** * Constructor of the TokenStack class. @@ -86,7 +87,7 @@ public: * @param tokens is a list of TokenSyntaxDescriptor instances that should be * stored on the stack. */ - void pushTokens(const std::vector &tokens); + void pushTokens(const std::vector &tokens); /** * Removes the previously pushed list of tokens from the stack. -- 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/Callbacks.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