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", "")}); |