diff options
Diffstat (limited to 'src/core/parser/stack/Stack.hpp')
-rw-r--r-- | src/core/parser/stack/Stack.hpp | 195 |
1 files changed, 146 insertions, 49 deletions
diff --git a/src/core/parser/stack/Stack.hpp b/src/core/parser/stack/Stack.hpp index b106475..294f7ec 100644 --- a/src/core/parser/stack/Stack.hpp +++ b/src/core/parser/stack/Stack.hpp @@ -17,41 +17,126 @@ */ /** - * @file ParserStateStack.hpp + * @file Stack.hpp * * Helper classes for document or description parsers. Contains the - * ParserStateStack class, which is an pushdown automaton responsible for + * Stack class, which is an pushdown automaton responsible for * accepting commands in the correct order and calling specified handlers. * * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) */ -#ifndef _OUSIA_PARSER_STATE_STACK_HPP_ -#define _OUSIA_PARSER_STATE_STACK_HPP_ +#ifndef _OUSIA_PARSER_STACK_STACK_HPP_ +#define _OUSIA_PARSER_STACK_STACK_HPP_ #include <cstdint> #include <map> #include <memory> #include <set> -#include <stack> #include <vector> #include <core/common/Variant.hpp> -#include <core/common/Logger.hpp> -#include <core/common/Argument.hpp> - -#include "Parser.hpp" -#include "ParserContext.hpp" -#include "ParserState.hpp" +#include <core/parser/Parser.hpp> namespace ousia { +// Forward declarations +class ParserContext; + +namespace parser_stack { + +// Forward declarations +class Handler; +class State; + /** - * The ParserStateStack class is a pushdown automaton responsible for turning a - * command stream into a tree of Node instances. + * The HandlerInfo class is used internally by the stack to associate additional + * (mutable) data with a handler instance. */ -class ParserStateStack { +class HandlerInfo { +public: + /** + * Pointer pointing at the actual handler instance. + */ + std::shared_ptr<Handler> handler; + + /** + * Next field index to be passed to the "fieldStart" function of the Handler + * class. + */ + size_t fieldIdx; + + /** + * Set to true if the handler is valid (which is the case if the "start" + * method has returned true). If the handler is invalid, no more calls are + * directed at it until it can be removed from the stack. + */ + bool valid : 1; + + /** + * Set to true if the handler currently is in a filed. + */ + bool inField : 1; + + /** + * Set to true if the handler currently is in the default field. + */ + bool inDefaultField : 1; + + /** + * Set to true if the handler currently is in an implicitly started default + * field. + */ + bool inImplicitDefaultField : 1; + + /** + * Set to false if this field is only opened pro-forma and does not accept + * any data. Otherwise set to true. + */ + bool inValidField : 1; + + /** + * Set to true, if the default field was already started. + */ + bool hasDefaultField : 1; + + /** + * Default constructor of the HandlerInfo class. + */ + HandlerInfo(); + + /** + * Constructor of the HandlerInfo class, taking a shared_ptr to the handler + * to which additional information should be attached. + */ + HandlerInfo(std::shared_ptr<Handler> handler); + + /** + * Destructor of the HandlerInfo class (to allow Handler to be forward + * declared). + */ + ~HandlerInfo(); + + /** + * Updates the "field" flags according to a "fieldStart" event. + */ + void fieldStart(bool isDefault, bool isImplicit, bool isValid); + + /** + * Updates the "fields" flags according to a "fieldEnd" event. + */ + void fieldEnd(); +}; + + +/** + * The Stack class is a pushdown automaton responsible for turning a command + * stream into a tree of Node instances. It does so by following a state + * transition graph and creating a set of Handler instances, which are placed + * on the stack. + */ +class Stack { private: /** * Reference at the parser context. @@ -62,12 +147,12 @@ private: * Map containing all registered command names and the corresponding * state descriptors. */ - const std::multimap<std::string, const ParserState *> &states; + const std::multimap<std::string, const State *> &states; /** * Internal stack used for managing the currently active Handler instances. */ - std::stack<std::shared_ptr<Handler>> stack; + std::vector<HandlerInfo> stack; /** * Used internally to get all expected command names for the current state. @@ -83,44 +168,50 @@ private: * * @param name is the name of the requested command. * @return nullptr if no target state was found, a pointer at the target - *state - * otherwise. + * state otherwise. */ - const ParserState *findTargetState(const std::string &name); + const State *findTargetState(const std::string &name); + + /** + * Tries to reconstruct the parser state from the Scope instance of the + * ParserContext given in the constructor. This functionality is needed for + * including files,as the Parser of the included file needs to be brought to + * an equivalent state as the one in the including file. + */ + void deduceState(); + + /** + * Returns true if all handlers on the stack are currently valid, or false + * if at least one handler is invalid. + * + * @return true if all handlers on the stack are valid. + */ + bool handlersValid(); public: /** - * Creates a new instance of the ParserStateStack class. + * Creates a new instance of the Stack class. * * @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 ParserState instances. + * corresponding State instances. */ - ParserStateStack( + Stack( ParserContext &ctx, - const std::multimap<std::string, const ParserState *> &states); + const std::multimap<std::string, const State *> &states); /** - * Tries to reconstruct the parser state from the Scope instance of the - * ParserContext given in the constructor. This functionality is needed for - * including files,as the Parser of the included file needs to be brought to - + an equivalent state as the one in the including file. - * - * @param scope is the ParserScope instance from which the ParserState - * should be reconstructed. - * @param logger is the logger instance to which error messages should be - * written. - * @return true if the operation was sucessful, false otherwise. + * Destructor of the Stack class. */ - bool deduceState(); + ~Stack(); /** - * Returns the state the ParserStateStack instance currently is in. + * Returns the state the Stack instance currently is in. * * @return the state of the currently active Handler instance or STATE_NONE * if no handler is on the stack. */ - const ParserState ¤tState(); + const State ¤tState(); /** * Returns the command name that is currently being handled. @@ -135,30 +226,35 @@ public: * * @param name is the name of the command (including the namespace * separator ':') and its corresponding location. Must be a string variant. - * @param args is a map variant containing the arguments that were passed to - * the command. + * @param args is a map containing the arguments that were passed to the + * command. */ - void command(Variant name, Variant args); + void command(const Variant &name, const Variant::mapType &args); /** * Function that should be called whenever a new field starts. Fields of the - * same command may not be separated by calls to + * same command may not be separated by calls to data or annotations. Doing + * so will result in a LoggableException. + * + * @param isDefault should be set to true if the started field explicitly + * is the default field. */ - void fieldStart(); + void fieldStart(bool isDefault); /** - * Function that should be called whenever a field ends. + * Function that should be called whenever a field ends. Calling this + * function if there is no field to end will result in a LoggableException. */ void fieldEnd(); /** * Function that shuold be called whenever character data is found in the - * input stream. + * input stream. May only be called if the currently is a command on the + * stack. * - * @param data is a variant of any type containing the data that was parsed - * as data. + * @param data is a string variant containing the data that has been found. */ - void data(Variant data); + void data(const Variant &data); /** * Function that should be called whenever an annotation starts. @@ -167,7 +263,7 @@ public: * @param args is a map variant containing the arguments that were passed * to the annotation. */ - void annotationStart(Variant name, Variant args); + void annotationStart(const Variant &className, const Variant &args); /** * Function that should be called whenever an annotation ends. @@ -175,7 +271,7 @@ public: * @param name is the name of the annotation class that was ended. * @param annotationName is the name of the annotation that was ended. */ - void annotationEnd(Variant name, Variant annotationName); + void annotationEnd(const Variant &className, const Variant &elementName); /** * Function that should be called whenever a previously registered token @@ -186,6 +282,7 @@ public: void token(Variant token); }; } +} -#endif /* _OUSIA_PARSER_STATE_STACK_HPP_ */ +#endif /* _OUSIA_STACK_HPP_ */ |