diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-04-14 01:33:19 +0200 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2016-04-25 22:24:18 +0200 |
commit | f8bca0e161705fc99fffd248ed4be897e940b2df (patch) | |
tree | e53a3180e221e5bf251421390396aa9d99c47c18 /src/core/parser | |
parent | 866965ac772d7894eab39eba63074e08a86db976 (diff) |
Allow non-Greedy short form to eat normal commands.
E.g. with regrads to the math ontology, this change allows syntax like
\(a^\frac{1}{2}\)
which is also valid in TeX (added corresponding tests).
Diffstat (limited to 'src/core/parser')
-rw-r--r-- | src/core/parser/stack/Stack.cpp | 130 |
1 files changed, 57 insertions, 73 deletions
diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp index 75a4b49..2ad5c8b 100644 --- a/src/core/parser/stack/Stack.cpp +++ b/src/core/parser/stack/Stack.cpp @@ -119,7 +119,7 @@ public: /** * Set to true once data was passed to the handler. */ - bool hadData : 1; + bool hasContent : 1; /** * Set to false, if the handler is not greedy (true is the default value). @@ -130,19 +130,38 @@ public: /** * Default constructor of the HandlerInfo class. */ - HandlerInfo(); + HandlerInfo() : HandlerInfo(nullptr) {} /** - * Constructor of the HandlerInfo class, allows to set some flags manually. + * Constructor of the HandlerInfo class, taking a shared_ptr to the handler + * to which additional information should be attached. */ - HandlerInfo(bool implicit, bool inField, bool inDefaultField, - bool inImplicitDefaultField); + HandlerInfo(std::shared_ptr<Handler> handler) + : HandlerInfo(false, false, false, false, handler) + { + } /** - * Constructor of the HandlerInfo class, taking a shared_ptr to the handler - * to which additional information should be attached. + * Constructor of the HandlerInfo class, allows to set some flags manually. */ - HandlerInfo(std::shared_ptr<Handler> handler); + HandlerInfo(bool implicit, bool inField, bool inDefaultField, + bool inImplicitDefaultField, + std::shared_ptr<Handler> handler = nullptr) + : handler(handler), + fieldIdx(0), + closeToken(Tokens::Empty), + valid(true), + implicit(implicit), + range(false), + inField(inField), + inDefaultField(inDefaultField), + inImplicitDefaultField(inImplicitDefaultField), + inValidField(false), + hadDefaultField(false), + hasContent(false), + greedy(true) + { + } /** * Destructor of the HandlerInfo class (to allow Handler to be forward @@ -166,7 +185,10 @@ public: * * @return the current handler name. */ - std::string name() const; + std::string name() const + { + return handler == nullptr ? std::string{} : handler->name(); + } /** * Returns the type of the referenced handler or COMMAND if no handler is @@ -174,69 +196,23 @@ public: * * @return the current handler type. */ - HandlerType type() const; + HandlerType type() const + { + return handler == nullptr ? HandlerType::COMMAND : handler->type(); + } /** * Returns the current state the handler is on or States::None if no handler * is present. * - * @return the current state machine state. + * @return the current state machine statE. */ - const State &state() const; + const State &state() const + { + return handler == nullptr ? States::None : handler->state(); + } }; -HandlerInfo::HandlerInfo() : HandlerInfo(nullptr) {} - -HandlerInfo::HandlerInfo(std::shared_ptr<Handler> handler) - : handler(handler), - fieldIdx(0), - closeToken(Tokens::Empty), - valid(true), - implicit(false), - range(false), - inField(false), - inDefaultField(false), - inImplicitDefaultField(false), - inValidField(false), - hadDefaultField(false), - hadData(false), - greedy(true) -{ -} - -HandlerInfo::HandlerInfo(bool implicit, bool inField, bool inDefaultField, - bool inImplicitDefaultField) - : handler(nullptr), - fieldIdx(0), - closeToken(Tokens::Empty), - valid(true), - implicit(implicit), - range(false), - inField(inField), - inDefaultField(inDefaultField), - inImplicitDefaultField(inImplicitDefaultField), - inValidField(true), - hadDefaultField(false), - hadData(false), - greedy(true) -{ -} - -std::string HandlerInfo::name() const -{ - return handler == nullptr ? std::string{} : handler->name(); -} - -HandlerType HandlerInfo::type() const -{ - return handler == nullptr ? HandlerType::COMMAND : handler->type(); -} - -const State &HandlerInfo::state() const -{ - return handler == nullptr ? States::None : handler->state(); -} - HandlerInfo::~HandlerInfo() { // Do nothing @@ -467,11 +443,14 @@ private: * @param startImplicitDefaultFieldForNonGreedy is set to true, even starts * an implicit default field for greedy handlers. Otherwise these handlers * are ended. + * @param endNonGreedyHandlers if set to true, ends non-greedy handlers. + * This behaviour is needed to end non-greedy short form tokens if another + * token is found. * @return true if the current command is in a valid field. */ bool prepareCurrentHandler(bool startImplicitDefaultField = true, bool endHandlersWithoutDefaultField = true, - bool endNonGreedyHandlers = true); + bool endNonGreedyHandlers = false); /** * Returns true if all handlers on the stack are currently valid, or false @@ -795,7 +774,8 @@ bool StackImpl::prepareCurrentHandler(bool startImplicitDefaultField, // abort. Exception: If the handler is not greedy and currently is in // its default field, then continue. if (info.inField) { - if (!info.greedy && info.hadData && info.inImplicitDefaultField) { + if (!info.greedy && info.hasContent && + info.inImplicitDefaultField) { endCurrentField(); continue; } else { @@ -856,7 +836,7 @@ bool StackImpl::handleData() while (true) { // Prepare the stack -- make sure all overdue handlers are ended and // we currently are in an open field - if (stack.empty() || !prepareCurrentHandler(true, true, false)) { + if (stack.empty() || !prepareCurrentHandler(true, true)) { throw LoggableException("Did not expect any data here"); } @@ -898,9 +878,6 @@ bool StackImpl::handleData() loggerFork.log(ex); } - // Update the "hadData" flag - info.hadData = info.hadData || valid; - // Reset the logger instance of the handler as soon as possible info.handler->resetLogger(); @@ -912,6 +889,9 @@ bool StackImpl::handleData() continue; } + // Update the "hadData" flag + info.hasContent = true; + // Commit the content of the logger fork. Do not change the valid flag. loggerFork.commit(); return true; @@ -1113,6 +1093,7 @@ bool StackImpl::handleOpenTokens(Logger &logger, const Token &token, // End the handler again if an error occured if (!info.valid) { endCurrentHandler(); + continue; } // If this is not a short form token and the "close" descriptor is @@ -1169,9 +1150,11 @@ void StackImpl::handleToken(const Token &token) try { // Try to open an implicit default field and try to start the token // as short form or as start token - prepareCurrentHandler(); + prepareCurrentHandler(true, true, true); if (handleOpenTokens(loggerFork, token, true, descr.shortForm) || handleOpenTokens(loggerFork, token, false, descr.open)) { + // Mark the "hasContent" flag of the last info + lastInfo().hasContent = true; return; } } @@ -1393,6 +1376,7 @@ void StackImpl::commandStart(const Variant &name, const Variant::mapType &args, // 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. + parentInfo.hasContent = true; info.valid = parentInfo.valid && info.valid; info.range = range; loggerFork.commit(); @@ -1428,7 +1412,7 @@ void StackImpl::data(const TokenizedData &data) // Close all handlers that did already had or cannot have a default field // and are not currently inside a field (repeat this after each chunk of // data/text) - prepareCurrentHandler(false, false, false); + prepareCurrentHandler(false, false); // Peek a token from the reader, repeat until all tokens have been read Token token; @@ -1445,7 +1429,7 @@ void StackImpl::data(const TokenizedData &data) handleToken(token); reader.consumePeek(); } - prepareCurrentHandler(false, false, false); + prepareCurrentHandler(false, false); } } |