From 082165d21269123f2658edc74aa1960669e306c8 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 1 Dec 2014 19:03:15 +0100 Subject: first version of the ParserStack class --- src/core/parser/XmlStates.cpp | 53 ++++++++ src/core/parser/XmlStates.hpp | 301 ++++++++++++++++++++++++++++++++++++++++++ src/plugins/xml/XmlStates.cpp | 53 -------- src/plugins/xml/XmlStates.hpp | 301 ------------------------------------------ 4 files changed, 354 insertions(+), 354 deletions(-) create mode 100644 src/core/parser/XmlStates.cpp create mode 100644 src/core/parser/XmlStates.hpp delete mode 100644 src/plugins/xml/XmlStates.cpp delete mode 100644 src/plugins/xml/XmlStates.hpp (limited to 'src') diff --git a/src/core/parser/XmlStates.cpp b/src/core/parser/XmlStates.cpp new file mode 100644 index 0000000..ec0f002 --- /dev/null +++ b/src/core/parser/XmlStates.cpp @@ -0,0 +1,53 @@ +/* + 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 "XmlStates.hpp" + +namespace ousia { +namespace parser { +namespace xml { + +std::set StateStack::expectedCommands(State state) +{ + std::set res; + for (const auto &v: handlers) { + if (v.second.parentStates.count(state)) { + res.insert(v.first); + } + } + return res; +} + +void StateStack::start(std::string tagName, char **attrs) { + // Fetch the current handler and the current state + const Handler *h = stack.empty() ? nullptr : stack.top(); + const State currentState = h ? State::NONE : h->state; + + // Fetch all handlers for the given tagName + auto range = handlers.equal_range(tagName); + if (range->first == handlers.end()) { + // There are no handlers registered for this tag name -- check whether + // the current handler supports arbitrary children + if (h && h->arbitraryChildren) + } +} + +} +} +} + diff --git a/src/core/parser/XmlStates.hpp b/src/core/parser/XmlStates.hpp new file mode 100644 index 0000000..70e95f4 --- /dev/null +++ b/src/core/parser/XmlStates.hpp @@ -0,0 +1,301 @@ +/* + 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 . +*/ + +#ifndef _OUSIA_XML_STATES_HPP_ +#define _OUSIA_XML_STATES_HPP_ + +#include + +#include +#include +#include +#include + +namespace ousia { +namespace parser { + +class Scope; +class Registry; +class Logger; + +namespace xml { + +/** + * The State class represents all states the XML parser can be in. These states + * mostly represent single tags. + */ +enum class State : uint8_t { + /* Meta states */ + ALL = -1, + + /* Start state */ + NONE, + + /* Special commands */ + INCLUDE, + INLINE, + + /* Document states */ + DOCUMENT, + HEAD, + BODY, + + /* Domain description states */ + DOMAIN, + + /* Type system states */ + TYPESYSTEM, + TYPE, + TYPE_ELEM +}; + +/** + * The handler class provides a context for handling an XML tag. It has to be + * overridden and registered in the StateStack class to form handlers for + * concrete XML tags. + */ +class Handler { +private: + Rooted node; + +protected: + void setNode(Handle node) { this->node = node; } + +public: + /** + * Reference to the ParserContext instance that should be used to resolve + * references to nodes in the Graph. + */ + const ParserContext &ctx; + + /** + * Contains the name of the tag that is being handled. + */ + const std::string name; + + /** + * Contains the current state of the state machine. + */ + const State state; + + /** + * Contains the state of the state machine when the parent node was handled. + */ + const State parentState; + + /** + * Set to true if the tag that is being handled is not the tag that was + * specified in the state machine but a child tag of that tag. + */ + const bool isChild; + + /** + * Constructor of the Handler class. + * + * @param ctx is the parser context the handler should be executed in. + * @param name is the name of the string. + * @param state is the state this handler was called for. + * @param parentState is the state of the parent command. + * @param isChild specifies whether this handler was called not for the + * command that was specified in the state machine but a child command. + */ + Handler(const ParserContext &ctx, std::string name, State state, + State parentState, bool isChild) + : ctx(ctx), + name(std::move(name)), + state(state), + parentState(parentState), + isChild(isChild){}; + + /** + * Virtual destructor. + */ + virtual ~Handler(); + + /** + * Returns the node instance that was created by the handler. + * + * @return the Node instance created by the handler. May be nullptr if no + * Node was created. + */ + Rooted getNode() { return node; } + + /** + * Called when the command that was specified in the constructor is + * instanciated. + * + * @param attrs contains the attributes that were specified for the command. + * TODO: Replace with StructInstance! + */ + virtual void start(char **attrs) = 0; + + /** + * Called whenever the command for which this handler + */ + virtual void end() = 0; + + /** + * Called whenever raw data (int the form of a string) is available for the + * Handler instance. + * + * TODO: Replace with std::string? + * + * @param data is a pointer at the character data that is available for the + * Handler instance. + */ + virtual void data(char *data, int len){}; + + /** + * Called whenever a direct child element was created and has ended. + * + * @param handler is a reference at the child Handler instance. + */ + virtual void child(Handler *handler){}; +}; + +/** + * HandlerConstructor is a function pointer type used to create concrete + * instances of the Handler class. + */ +using HandlerConstructor = Handler *(*)(const ParserContext &ctx, + std::string name, State state, + State parentState, bool isChild); + +/** + * The StateStack class is a pushdown automaton responsible for turning a + * command stream into a tree of Node instances. + */ +class StateStack { +public: + /** + * Used internlly by StateStack to store Handler instances and parameters + * from HandlerDescriptor that are not stored in the Handler instance + * itself. Instances of the HandlerInstance class can be created using the + * HandlerDescriptor "create" method. + */ + struct HandlerInstance { + /** + * Pointer at the actual handler instance. + */ + std::unique_ptr handler; + + /** + * Value of the arbitraryChildren flag stored in the HandlerDescriptor + * class. + */ + const bool arbitraryChildren; + + HandlerInstance(std::unique_ptr handler, + bool arbitraryChildren) + : handler(handler), arbitraryChildren(arbitraryChildren) + { + } + } + + /** + * Used internally by StateStack to store the pushdown automaton + * description. + */ + struct HandlerDescriptor { + /** + * The valid parent states. + */ + const std::set parentStates; + + /** + * Pointer at a function which creates a new concrete Handler instance. + */ + const HandlerConstructor ctor; + + /** + * The target state for the registered handler. + */ + const State targetState; + + /** + * Set to true if this handler instance allows arbitrary children as + * tags. + */ + const bool arbitraryChildren; + + HandlerDescriptor(std::set parentStates, HandlerConstructor ctor, + State targetState, bool arbitraryChildren = false) + : parentStates(std::move(parentStates)), + ctor(constructor), + targetState(targetState), + arbitraryChildren(arbitraryChildren) + { + } + + HandlerInstance create(const ParserContext &ctx, std::string name, + State parentState, bool isChild) + { + return HandlerInstance{ + ctor(ctx, name, targetState, parentState, isChild), + arbitraryChildren}; + } + }; + +private: + /** + * Map containing all registered command names and the corresponding + * handler + * descriptor. + */ + const std::multimap handlers; + + /** + * Reference at the parser context. + */ + const ParserContext &ctx; + + /** + * Internal stack used for managing the currently active Handler instances. + */ + std::stack stack; + + /** + * Used internally to get all expected command names for the given state + * (does not work if the current Handler instance allows arbitrary + * children). This function is used to build error messages. + * + * @param state is the state for which all expected command names should be + * returned. + */ + std::set expectedCommands(State state); + +public: + /** + * Creates a new instance of the StateStack class. + * + * @param handlers is a map containing the command names and the + * corresponding HandlerDescriptor instances. + */ + StateStack(const ParserContext &ctx, + std::multimap handlers) + : handlers(std::move(handlers)), + ctx(ctx), + currentState(State::NONE), + arbitraryChildren(false); +}; +} +} +} + +#endif /* _OUSIA_XML_STATES_HPP_ */ + diff --git a/src/plugins/xml/XmlStates.cpp b/src/plugins/xml/XmlStates.cpp deleted file mode 100644 index ec0f002..0000000 --- a/src/plugins/xml/XmlStates.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - 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 "XmlStates.hpp" - -namespace ousia { -namespace parser { -namespace xml { - -std::set StateStack::expectedCommands(State state) -{ - std::set res; - for (const auto &v: handlers) { - if (v.second.parentStates.count(state)) { - res.insert(v.first); - } - } - return res; -} - -void StateStack::start(std::string tagName, char **attrs) { - // Fetch the current handler and the current state - const Handler *h = stack.empty() ? nullptr : stack.top(); - const State currentState = h ? State::NONE : h->state; - - // Fetch all handlers for the given tagName - auto range = handlers.equal_range(tagName); - if (range->first == handlers.end()) { - // There are no handlers registered for this tag name -- check whether - // the current handler supports arbitrary children - if (h && h->arbitraryChildren) - } -} - -} -} -} - diff --git a/src/plugins/xml/XmlStates.hpp b/src/plugins/xml/XmlStates.hpp deleted file mode 100644 index 70e95f4..0000000 --- a/src/plugins/xml/XmlStates.hpp +++ /dev/null @@ -1,301 +0,0 @@ -/* - 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 . -*/ - -#ifndef _OUSIA_XML_STATES_HPP_ -#define _OUSIA_XML_STATES_HPP_ - -#include - -#include -#include -#include -#include - -namespace ousia { -namespace parser { - -class Scope; -class Registry; -class Logger; - -namespace xml { - -/** - * The State class represents all states the XML parser can be in. These states - * mostly represent single tags. - */ -enum class State : uint8_t { - /* Meta states */ - ALL = -1, - - /* Start state */ - NONE, - - /* Special commands */ - INCLUDE, - INLINE, - - /* Document states */ - DOCUMENT, - HEAD, - BODY, - - /* Domain description states */ - DOMAIN, - - /* Type system states */ - TYPESYSTEM, - TYPE, - TYPE_ELEM -}; - -/** - * The handler class provides a context for handling an XML tag. It has to be - * overridden and registered in the StateStack class to form handlers for - * concrete XML tags. - */ -class Handler { -private: - Rooted node; - -protected: - void setNode(Handle node) { this->node = node; } - -public: - /** - * Reference to the ParserContext instance that should be used to resolve - * references to nodes in the Graph. - */ - const ParserContext &ctx; - - /** - * Contains the name of the tag that is being handled. - */ - const std::string name; - - /** - * Contains the current state of the state machine. - */ - const State state; - - /** - * Contains the state of the state machine when the parent node was handled. - */ - const State parentState; - - /** - * Set to true if the tag that is being handled is not the tag that was - * specified in the state machine but a child tag of that tag. - */ - const bool isChild; - - /** - * Constructor of the Handler class. - * - * @param ctx is the parser context the handler should be executed in. - * @param name is the name of the string. - * @param state is the state this handler was called for. - * @param parentState is the state of the parent command. - * @param isChild specifies whether this handler was called not for the - * command that was specified in the state machine but a child command. - */ - Handler(const ParserContext &ctx, std::string name, State state, - State parentState, bool isChild) - : ctx(ctx), - name(std::move(name)), - state(state), - parentState(parentState), - isChild(isChild){}; - - /** - * Virtual destructor. - */ - virtual ~Handler(); - - /** - * Returns the node instance that was created by the handler. - * - * @return the Node instance created by the handler. May be nullptr if no - * Node was created. - */ - Rooted getNode() { return node; } - - /** - * Called when the command that was specified in the constructor is - * instanciated. - * - * @param attrs contains the attributes that were specified for the command. - * TODO: Replace with StructInstance! - */ - virtual void start(char **attrs) = 0; - - /** - * Called whenever the command for which this handler - */ - virtual void end() = 0; - - /** - * Called whenever raw data (int the form of a string) is available for the - * Handler instance. - * - * TODO: Replace with std::string? - * - * @param data is a pointer at the character data that is available for the - * Handler instance. - */ - virtual void data(char *data, int len){}; - - /** - * Called whenever a direct child element was created and has ended. - * - * @param handler is a reference at the child Handler instance. - */ - virtual void child(Handler *handler){}; -}; - -/** - * HandlerConstructor is a function pointer type used to create concrete - * instances of the Handler class. - */ -using HandlerConstructor = Handler *(*)(const ParserContext &ctx, - std::string name, State state, - State parentState, bool isChild); - -/** - * The StateStack class is a pushdown automaton responsible for turning a - * command stream into a tree of Node instances. - */ -class StateStack { -public: - /** - * Used internlly by StateStack to store Handler instances and parameters - * from HandlerDescriptor that are not stored in the Handler instance - * itself. Instances of the HandlerInstance class can be created using the - * HandlerDescriptor "create" method. - */ - struct HandlerInstance { - /** - * Pointer at the actual handler instance. - */ - std::unique_ptr handler; - - /** - * Value of the arbitraryChildren flag stored in the HandlerDescriptor - * class. - */ - const bool arbitraryChildren; - - HandlerInstance(std::unique_ptr handler, - bool arbitraryChildren) - : handler(handler), arbitraryChildren(arbitraryChildren) - { - } - } - - /** - * Used internally by StateStack to store the pushdown automaton - * description. - */ - struct HandlerDescriptor { - /** - * The valid parent states. - */ - const std::set parentStates; - - /** - * Pointer at a function which creates a new concrete Handler instance. - */ - const HandlerConstructor ctor; - - /** - * The target state for the registered handler. - */ - const State targetState; - - /** - * Set to true if this handler instance allows arbitrary children as - * tags. - */ - const bool arbitraryChildren; - - HandlerDescriptor(std::set parentStates, HandlerConstructor ctor, - State targetState, bool arbitraryChildren = false) - : parentStates(std::move(parentStates)), - ctor(constructor), - targetState(targetState), - arbitraryChildren(arbitraryChildren) - { - } - - HandlerInstance create(const ParserContext &ctx, std::string name, - State parentState, bool isChild) - { - return HandlerInstance{ - ctor(ctx, name, targetState, parentState, isChild), - arbitraryChildren}; - } - }; - -private: - /** - * Map containing all registered command names and the corresponding - * handler - * descriptor. - */ - const std::multimap handlers; - - /** - * Reference at the parser context. - */ - const ParserContext &ctx; - - /** - * Internal stack used for managing the currently active Handler instances. - */ - std::stack stack; - - /** - * Used internally to get all expected command names for the given state - * (does not work if the current Handler instance allows arbitrary - * children). This function is used to build error messages. - * - * @param state is the state for which all expected command names should be - * returned. - */ - std::set expectedCommands(State state); - -public: - /** - * Creates a new instance of the StateStack class. - * - * @param handlers is a map containing the command names and the - * corresponding HandlerDescriptor instances. - */ - StateStack(const ParserContext &ctx, - std::multimap handlers) - : handlers(std::move(handlers)), - ctx(ctx), - currentState(State::NONE), - arbitraryChildren(false); -}; -} -} -} - -#endif /* _OUSIA_XML_STATES_HPP_ */ - -- cgit v1.2.3