diff options
| author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-04-12 17:40:32 +0200 | 
|---|---|---|
| committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2016-04-25 22:24:16 +0200 | 
| commit | bed013e617130f7afd1f90ba57afc160b43c71df (patch) | |
| tree | bb5d335132a522e24351e5a3239355f7a9ca2070 /src | |
| parent | 84ab3caa172fc3f4ec7085135964173c8eed5f84 (diff) | |
Implement non-greedy behaviour for short tokens
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/parser/stack/DocumentHandler.cpp | 18 | ||||
| -rw-r--r-- | src/core/parser/stack/Stack.cpp | 39 | 
2 files changed, 39 insertions, 18 deletions
| diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp index aa9a28f..7564fad 100644 --- a/src/core/parser/stack/DocumentHandler.cpp +++ b/src/core/parser/stack/DocumentHandler.cpp @@ -145,6 +145,11 @@ void DocumentChildHandler::pushScopeTokens()  	// List containing the unfiltered syntax descriptors  	std::vector<SyntaxDescriptor> descrs; +	// Skip the DocumentField and the curresponding StructuredEntity +	// if we're currently in the implicit default field of a non-greedy +	// structure. +	size_t explicitSkipCount = (!isGreedy && inImplicitDefaultField) ? 2 : 0; +  	// Fetch the current scope stack and search the first non-transparent field  	// or structure  	const ManagedVector<Node> &stack = scope().getStack(); @@ -157,6 +162,10 @@ void DocumentChildHandler::pushScopeTokens()  		if (nd->isa(&RttiTypes::DocumentField)) {  			Rooted<DocumentField> field = nd.cast<DocumentField>();  			if (!field->transparent) { +				if (explicitSkipCount > 0) { +					explicitSkipCount--; +					continue; +				}  				descrs = field->getDescriptor()->getPermittedTokens();  				break;  			} @@ -166,6 +175,10 @@ void DocumentChildHandler::pushScopeTokens()  		if (nd->isa(&RttiTypes::StructuredEntity)) {  			Rooted<StructuredEntity> entity = nd.cast<StructuredEntity>();  			if (!entity->isTransparent()) { +				if (explicitSkipCount > 0) { +					explicitSkipCount--; +					continue; +				}  				descrs = entity->getDescriptor()->getPermittedTokens();  				break;  			} @@ -591,12 +604,13 @@ bool DocumentChildHandler::startToken(Handle<Node> node, bool greedy)  	}  } -EndTokenResult DocumentChildHandler::endToken(Handle<Node> node, size_t maxStackDepth) +EndTokenResult DocumentChildHandler::endToken(Handle<Node> node, +                                              size_t maxStackDepth)  {  	// Fetch the current scope stack  	const ManagedVector<Node> &stack = scope().getStack(); -	bool found = false;            // true once the given node has been found +	bool found = false;  // true once the given node has been found  	bool repeat = false;  	size_t scopeStackDepth = 0;    // # of elems on the scope stack  	size_t currentStackDepth = 0;  // # of "explicit" elems on the parser stack diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp index ef503f7..cc1eb23 100644 --- a/src/core/parser/stack/Stack.cpp +++ b/src/core/parser/stack/Stack.cpp @@ -464,10 +464,14 @@ private:  	 * startImplicitDefaultField is set to false. If false, prevents this method  	 * from ending a handler if it potentially can have a default field, but did  	 * not have one yet. +	 * @param startImplicitDefaultFieldForNonGreedy is set to true, even starts +	 * an implicit default field for greedy handlers. Otherwise these handlers +	 * are ended.  	 * @return true if the current command is in a valid field.  	 */  	bool prepareCurrentHandler(bool startImplicitDefaultField = true, -	                           bool endHandlersWithoutDefaultField = true); +	                           bool endHandlersWithoutDefaultField = true, +	                           bool endNonGreedyHandlers = true);  	/**  	 * Returns true if all handlers on the stack are currently valid, or false @@ -779,7 +783,8 @@ bool StackImpl::endCurrentHandler()  }  bool StackImpl::prepareCurrentHandler(bool startImplicitDefaultField, -                                      bool endHandlersWithoutDefaultField) +                                      bool endHandlersWithoutDefaultField, +                                      bool endNonGreedyHandlers)  {  	// Repeat until a valid handler is found on the stack  	while (!stack.empty()) { @@ -787,9 +792,15 @@ bool StackImpl::prepareCurrentHandler(bool startImplicitDefaultField,  		HandlerInfo &info = currentInfo();  		// If the current Handler is in a field, there is nothing to be done, -		// abort +		// abort. Exception: If the handler is not greedy and currently is in +		// its default field, then continue.  		if (info.inField) { -			return true; +			if (!info.greedy && info.hadData && info.inImplicitDefaultField) { +				endCurrentField(); +				continue; +			} else { +				return true; +			}  		}  		// If the current field already had a default field or is not valid, @@ -798,7 +809,7 @@ bool StackImpl::prepareCurrentHandler(bool startImplicitDefaultField,  		    info.type() == HandlerType::COMMAND ||  		    info.type() == HandlerType::TOKEN ||  		    (info.type() == HandlerType::ANNOTATION_START && info.range); -		if (info.hadDefaultField || +		if (info.hadDefaultField || (!info.greedy && endNonGreedyHandlers) ||  		    (!startImplicitDefaultField && endHandlersWithoutDefaultField) ||  		    !info.valid || !canHaveImplicitDefaultField) {  			// We cannot end the command if it is marked as "range" command @@ -845,7 +856,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()) { +		if (stack.empty() || !prepareCurrentHandler(true, true, false)) {  			throw LoggableException("Did not expect any data here");  		} @@ -948,8 +959,8 @@ static void strayTokenError(const Token &token, TokenDescriptor &descr,  }  static void checkTokensAreUnambiguous(const Token &token, -                                     const TokenDescriptor &descr, -                                     Logger &logger) +                                      const TokenDescriptor &descr, +                                      Logger &logger)  {  	// Some helper functions and constants  	constexpr ssize_t MAX_DEPTH = std::numeric_limits<ssize_t>::max(); @@ -1158,7 +1169,7 @@ 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(true); +			prepareCurrentHandler();  			if (handleOpenTokens(loggerFork, token, true, descr.shortForm) ||  			    handleOpenTokens(loggerFork, token, false, descr.open)) {  				return; @@ -1417,7 +1428,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); +	prepareCurrentHandler(false, false, false);  	// Peek a token from the reader, repeat until all tokens have been read  	Token token; @@ -1434,7 +1445,7 @@ void StackImpl::data(const TokenizedData &data)  			handleToken(token);  			reader.consumePeek();  		} -		prepareCurrentHandler(false, false); +		prepareCurrentHandler(false, false, false);  	}  } @@ -1511,11 +1522,7 @@ void StackImpl::pushTokens(const std::vector<SyntaxDescriptor> &tokens)  	tokenStack.pushTokens(tokens);  } -void StackImpl::popTokens() -{ -	// Pop the last set of tokens from the token stack. -	tokenStack.popTokens(); -} +void StackImpl::popTokens() { tokenStack.popTokens(); }  bool StackImpl::readToken(Token &token)  { | 
