diff options
Diffstat (limited to 'src/core/parser/stack')
| -rw-r--r-- | src/core/parser/stack/DocumentHandler.cpp | 74 | ||||
| -rw-r--r-- | src/core/parser/stack/DomainHandler.cpp | 16 | ||||
| -rw-r--r-- | src/core/parser/stack/Stack.cpp | 20 | ||||
| -rw-r--r-- | src/core/parser/stack/TypesystemHandler.cpp | 20 | 
4 files changed, 89 insertions, 41 deletions
diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp index 35146b1..bb04bd3 100644 --- a/src/core/parser/stack/DocumentHandler.cpp +++ b/src/core/parser/stack/DocumentHandler.cpp @@ -47,7 +47,7 @@ bool DocumentHandler::start(Variant::mapType &args)  	return true;  } -void DocumentHandler::end() { scope().pop(); } +void DocumentHandler::end() { scope().pop(logger()); }  /* DocumentChildHandler */ @@ -98,6 +98,9 @@ void DocumentChildHandler::createPath(const NodeVector<Node> &path,  	    manager(), scope().getLeaf(),  	    parent->getDescriptor()->getFieldDescriptorIndex(), true)};  	scope().push(field); + +	// Generally allow explicit fields in the new field +	scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, false);  }  void DocumentChildHandler::createPath(const size_t &firstFieldIdx, @@ -113,6 +116,9 @@ void DocumentChildHandler::createPath(const size_t &firstFieldIdx,  	parent = static_cast<DocumentEntity *>(transparent.get());  	createPath(path, parent, 2); + +	// Generally allow explicit fields in the new field +	scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, false);  }  bool DocumentChildHandler::start(Variant::mapType &args) @@ -136,6 +142,14 @@ bool DocumentChildHandler::start(Variant::mapType &args)  		Rooted<StructuredEntity> entity;  		// handle the root note specifically.  		if (parentNode->isa(&RttiTypes::Document)) { +			// if we already have a root node, stop. +			if (parentNode.cast<Document>()->getRoot() != nullptr) { +				logger().warning( +				    "This document already has a root node. The additional " +				    "node is ignored.", +				    location()); +				return false; +			}  			Rooted<StructuredClass> strct = scope().resolve<StructuredClass>(  			    Utils::split(name(), ':'), logger());  			if (strct == nullptr) { @@ -170,12 +184,25 @@ bool DocumentChildHandler::start(Variant::mapType &args)  				ssize_t newFieldIdx =  				    parent->getDescriptor()->getFieldDescriptorIndex(name());  				if (newFieldIdx != -1) { -					Rooted<DocumentField> field{new DocumentField( -					    manager(), parentNode, newFieldIdx, false)}; -					field->setLocation(location()); -					scope().push(field); -					isExplicitField = true; -					return true; +					// Check whether explicit fields are allowed here, if not +					if (scope().getFlag(ParserFlag::POST_EXPLICIT_FIELDS)) { +						logger().note( +						    std::string( +						        "Data or structure commands have already been " +						        "given, command \"") + +						        name() + std::string( +						                     "\" is not interpreted explicit " +						                     "field. Move explicit field " +						                     "references to the beginning."), +						    location()); +					} else { +						Rooted<DocumentField> field{new DocumentField( +						    manager(), parentNode, newFieldIdx, false)}; +						field->setLocation(location()); +						scope().push(field); +						isExplicitField = true; +						return true; +					}  				}  			} @@ -200,9 +227,9 @@ bool DocumentChildHandler::start(Variant::mapType &args)  					// if we have transparent elements above us in the structure  					// tree we try to unwind them before we give up.  					// pop the implicit field. -					scope().pop(); +					scope().pop(logger());  					// pop the implicit element. -					scope().pop(); +					scope().pop(logger());  					continue;  				}  				throw LoggableException( @@ -218,11 +245,17 @@ bool DocumentChildHandler::start(Variant::mapType &args)  				    parent->getDescriptor()->getFieldDescriptorIndex();  			}  			// create the entity for the new element at last. -			//TODO: REMOVE +			// TODO: REMOVE  			strct_name = strct->getName();  			entity = parent->createChildStructuredEntity(strct, lastFieldIdx,  			                                             args, nameAttr);  		} + +		// We're past the region in which explicit fields can be defined in the +		// parent structure element +		scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, true); + +		// Bush the entity onto the stack  		entity->setLocation(location());  		scope().push(entity);  		return true; @@ -237,7 +270,7 @@ void DocumentChildHandler::end()  		return;  	}  	// pop the "main" element. -	scope().pop(); +	scope().pop(logger());  }  bool DocumentChildHandler::fieldStart(bool &isDefault, size_t fieldIdx) @@ -259,6 +292,9 @@ bool DocumentChildHandler::fieldStart(bool &isDefault, size_t fieldIdx)  	    parent->getDescriptor()->getFieldDescriptors();  	if (isDefault) { +		if(fields.empty()){ +			return false; +		}  		fieldIdx = fields.size() - 1;  	} else {  		if (fieldIdx >= fields.size()) { @@ -271,6 +307,10 @@ bool DocumentChildHandler::fieldStart(bool &isDefault, size_t fieldIdx)  	    new DocumentField(manager(), parentNode, fieldIdx, false)};  	field->setLocation(location());  	scope().push(field); + +	// Generally allow explicit fields in the new field +	scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, false); +  	return true;  } @@ -279,15 +319,15 @@ void DocumentChildHandler::fieldEnd()  	assert(scope().getLeaf()->isa(&RttiTypes::DocumentField));  	// pop the field from the stack. -	scope().pop(); +	scope().pop(logger());  	// pop all remaining transparent elements.  	while (scope().getLeaf()->isa(&RttiTypes::StructuredEntity) &&  	       scope().getLeaf().cast<StructuredEntity>()->isTransparent()) {  		// pop the transparent element. -		scope().pop(); +		scope().pop(logger());  		// pop the transparent field. -		scope().pop(); +		scope().pop(logger());  	}  } @@ -334,6 +374,10 @@ bool DocumentChildHandler::convertData(Handle<FieldDescriptor> field,  bool DocumentChildHandler::data(Variant &data)  { +	// We're past the region in which explicit fields can be defined in the +	// parent structure element +	scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, true); +  	Rooted<Node> parentField = scope().getLeaf();  	assert(parentField->isa(&RttiTypes::DocumentField)); @@ -427,4 +471,4 @@ namespace RttiTypes {  const Rtti DocumentField = RttiBuilder<ousia::parser_stack::DocumentField>(                                 "DocumentField").parent(&Node);  } -} +}
\ No newline at end of file diff --git a/src/core/parser/stack/DomainHandler.cpp b/src/core/parser/stack/DomainHandler.cpp index ddec1ee..aa18faa 100644 --- a/src/core/parser/stack/DomainHandler.cpp +++ b/src/core/parser/stack/DomainHandler.cpp @@ -53,7 +53,7 @@ bool DomainHandler::start(Variant::mapType &args)  	return true;  } -void DomainHandler::end() { scope().pop(); } +void DomainHandler::end() { scope().pop(logger()); }  /* DomainStructHandler */ @@ -85,7 +85,7 @@ bool DomainStructHandler::start(Variant::mapType &args)  	return true;  } -void DomainStructHandler::end() { scope().pop(); } +void DomainStructHandler::end() { scope().pop(logger()); }  /* DomainAnnotationHandler */  bool DomainAnnotationHandler::start(Variant::mapType &args) @@ -102,7 +102,7 @@ bool DomainAnnotationHandler::start(Variant::mapType &args)  	return true;  } -void DomainAnnotationHandler::end() { scope().pop(); } +void DomainAnnotationHandler::end() { scope().pop(logger()); }  /* DomainAttributesHandler */ @@ -118,7 +118,7 @@ bool DomainAttributesHandler::start(Variant::mapType &args)  	return true;  } -void DomainAttributesHandler::end() { scope().pop(); } +void DomainAttributesHandler::end() { scope().pop(logger()); }  /* DomainFieldHandler */ @@ -148,7 +148,7 @@ bool DomainFieldHandler::start(Variant::mapType &args)  	return true;  } -void DomainFieldHandler::end() { scope().pop(); } +void DomainFieldHandler::end() { scope().pop(logger()); }  /* DomainFieldRefHandler */ @@ -218,7 +218,7 @@ bool DomainPrimitiveHandler::start(Variant::mapType &args)  	return true;  } -void DomainPrimitiveHandler::end() { scope().pop(); } +void DomainPrimitiveHandler::end() { scope().pop(logger()); }  /* DomainChildHandler */ @@ -251,7 +251,7 @@ bool DomainParentHandler::start(Variant::mapType &args)  	return true;  } -void DomainParentHandler::end() { scope().pop(); } +void DomainParentHandler::end() { scope().pop(logger()); }  /* DomainParentFieldHandler */ @@ -414,4 +414,4 @@ namespace RttiTypes {  const Rtti DomainParent = RttiBuilder<ousia::parser_stack::DomainParent>(                                "DomainParent").parent(&Node);  } -}
\ No newline at end of file +} diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp index 08f86e5..5b67248 100644 --- a/src/core/parser/stack/Stack.cpp +++ b/src/core/parser/stack/Stack.cpp @@ -16,8 +16,6 @@      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ -#include <sstream> -  #include <core/common/Logger.hpp>  #include <core/common/Utils.hpp>  #include <core/common/Exceptions.hpp> @@ -256,7 +254,9 @@ void Stack::endCurrentHandler()  			// Make sure the fieldEnd handler is called if the element still  			// is in a field  			if (info.inField) { -				info.handler->fieldEnd(); +				if (info.inValidField) { +					info.handler->fieldEnd(); +				}  				info.fieldEnd();  			} @@ -300,8 +300,6 @@ bool Stack::ensureHandlerIsInField()  		// Try to start a new default field, abort if this did not work  		bool isDefault = true;  		if (!info.handler->fieldStart(isDefault, info.fieldIdx)) { -			info.handler->fieldEnd(); -			endCurrentHandler();  			return false;  		} @@ -505,10 +503,9 @@ void Stack::fieldStart(bool isDefault)  	// (the default field always is the last field) -- mark the command as  	// invalid  	if (info.hadDefaultField) { -		logger().error( -		    std::string("Got field start, but command \"") + -		    currentCommandName() + -		    std::string("\" does not have any more fields")); +		logger().error(std::string("Got field start, but command \"") + +		               currentCommandName() + +		               std::string("\" does not have any more fields"));  	}  	// Copy the isDefault flag to a local variable, the fieldStart method will @@ -559,7 +556,7 @@ void Stack::fieldEnd()  	// Only continue if the current handler stack is in a valid state, do not  	// call the fieldEnd function if something went wrong before -	if (handlersValid() && !info.hadDefaultField) { +	if (handlersValid() && !info.hadDefaultField && info.inValidField) {  		try {  			info.handler->fieldEnd();  		} @@ -587,5 +584,4 @@ void Stack::token(Variant token)  	// TODO  }  } -} - +}
\ No newline at end of file diff --git a/src/core/parser/stack/TypesystemHandler.cpp b/src/core/parser/stack/TypesystemHandler.cpp index 8fd9525..de8ee49 100644 --- a/src/core/parser/stack/TypesystemHandler.cpp +++ b/src/core/parser/stack/TypesystemHandler.cpp @@ -16,11 +16,13 @@      along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ -#include <core/model/Typesystem.hpp> +#include <core/model/Document.hpp>  #include <core/model/Domain.hpp> +#include <core/model/Typesystem.hpp>  #include <core/parser/ParserScope.hpp>  #include <core/parser/ParserContext.hpp> +#include "DocumentHandler.hpp"  #include "DomainHandler.hpp"  #include "State.hpp"  #include "TypesystemHandler.hpp" @@ -38,10 +40,16 @@ bool TypesystemHandler::start(Variant::mapType &args)  	typesystem->setLocation(location());  	// If the typesystem is defined inside a domain, add a reference to the -	// typesystem to the domain +	// typesystem to the domain -- do the same with a document, if no domain +	// is found  	Rooted<Domain> domain = scope().select<Domain>();  	if (domain != nullptr) {  		domain->reference(typesystem); +	} else { +		Rooted<Document> document = scope().select<Document>(); +		if (document != nullptr) { +			document->reference(typesystem); +		}  	}  	// Push the typesystem onto the scope, set the POST_HEAD flag to true @@ -51,7 +59,7 @@ bool TypesystemHandler::start(Variant::mapType &args)  	return true;  } -void TypesystemHandler::end() { scope().pop(); } +void TypesystemHandler::end() { scope().pop(logger()); }  /* TypesystemEnumHandler */ @@ -70,7 +78,7 @@ bool TypesystemEnumHandler::start(Variant::mapType &args)  	return true;  } -void TypesystemEnumHandler::end() { scope().pop(); } +void TypesystemEnumHandler::end() { scope().pop(logger()); }  /* TypesystemEnumEntryHandler */ @@ -112,7 +120,7 @@ bool TypesystemStructHandler::start(Variant::mapType &args)  	return true;  } -void TypesystemStructHandler::end() { scope().pop(); } +void TypesystemStructHandler::end() { scope().pop(logger()); }  /* TypesystemStructFieldHandler */ @@ -182,7 +190,7 @@ bool TypesystemConstantHandler::start(Variant::mapType &args)  namespace States {  const State Typesystem = StateBuilder() -                             .parents({&None, &Domain}) +                             .parents({&None, &Domain, &Document})                               .createdNodeType(&RttiTypes::Typesystem)                               .elementHandler(TypesystemHandler::create)                               .arguments({Argument::String("name", "")});  | 
