summaryrefslogtreecommitdiff
path: root/src/core/parser/stack
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-04-14 01:33:19 +0200
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2016-04-25 22:24:18 +0200
commitf8bca0e161705fc99fffd248ed4be897e940b2df (patch)
treee53a3180e221e5bf251421390396aa9d99c47c18 /src/core/parser/stack
parent866965ac772d7894eab39eba63074e08a86db976 (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/stack')
-rw-r--r--src/core/parser/stack/Stack.cpp130
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);
}
}