diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/parser/ParserScope.cpp | 21 | ||||
-rw-r--r-- | src/core/parser/ParserScope.hpp | 4 | ||||
-rw-r--r-- | src/core/resource/ResourceRequest.cpp | 10 | ||||
-rw-r--r-- | src/formats/osml/OsmlParser.cpp | 12 |
4 files changed, 39 insertions, 8 deletions
diff --git a/src/core/parser/ParserScope.cpp b/src/core/parser/ParserScope.cpp index ce3dc94..b0a4945 100644 --- a/src/core/parser/ParserScope.cpp +++ b/src/core/parser/ParserScope.cpp @@ -21,6 +21,7 @@ #include <core/common/VariantWriter.hpp> #include <core/model/Domain.hpp> #include <core/model/Typesystem.hpp> +#include <core/model/RootNode.hpp> #include "ParserScope.hpp" @@ -233,6 +234,13 @@ void ParserScope::pop() } flags.resize(newLen); + // Whenever a RootNode is popped from the stack, we have to perform deferred + // resolution -- however, postpone issuing error messages + if (nodes.back()->isa(&RttiTypes::RootNode)) { + Logger logger; + performDeferredResolution(logger, true); + } + // Remove the element from the stack nodes.pop_back(); } @@ -424,7 +432,7 @@ bool ParserScope::resolveTypeWithValue(const std::string &name, resultCallback); } -bool ParserScope::performDeferredResolution(Logger &logger) +bool ParserScope::performDeferredResolution(Logger &logger, bool postpone) { // Repeat the resolution process as long as something has changed in the // last iteration (resolving a node may cause other nodes to be resolvable). @@ -446,8 +454,9 @@ bool ParserScope::performDeferredResolution(Logger &logger) // Abort if nothing has changed in the last iteration if (!hasChange) { // In a last step, clear the "awaitingResolution" list to allow - // cyclical dependencies to be resolved - if (!awaitingResolution.empty()) { + // cyclical dependencies to be resolved -- if the postpone flag + // is set, do not do this + if (!awaitingResolution.empty() && !postpone) { awaitingResolution.clear(); } else { break; @@ -460,6 +469,12 @@ bool ParserScope::performDeferredResolution(Logger &logger) return true; } + // If the postpone flag is set to true, we'll abort here -- this function + // will be called again later + if (postpone) { + return false; + } + // Output error messages for all elements for which resolution did not // succeed. for (auto &failed : deferred) { diff --git a/src/core/parser/ParserScope.hpp b/src/core/parser/ParserScope.hpp index 185b845..24af6b8 100644 --- a/src/core/parser/ParserScope.hpp +++ b/src/core/parser/ParserScope.hpp @@ -797,8 +797,10 @@ public: * pending deferred resolutions is cleared after this function has run. * * @param logger is the logger instance into which errors should be logged. + * @param postpone if set to true, postpones issuing any error messages and + * waits for node resolution. */ - bool performDeferredResolution(Logger &logger); + bool performDeferredResolution(Logger &logger, bool postpone = false); }; } diff --git a/src/core/resource/ResourceRequest.cpp b/src/core/resource/ResourceRequest.cpp index 357f413..5e5bff3 100644 --- a/src/core/resource/ResourceRequest.cpp +++ b/src/core/resource/ResourceRequest.cpp @@ -152,6 +152,10 @@ bool ResourceRequest::deduce(Registry ®istry, Logger &logger) { bool ok = true; + // Check whether all node types are supported here -- this is indicated by + // supportedTypes containing the extremely general "Node" type. + bool supportsAllNodes = supportedTypes.count(&RttiTypes::Node) > 0U; + // Make sure the given file name is not empty if (path.empty()) { logger.error("Filename may not be empty"); @@ -227,7 +231,8 @@ bool ResourceRequest::deduce(Registry ®istry, Logger &logger) logger.error(std::string("Cannot parse files of type \"") + mimetype + std::string("\"")); ok = false; - } else if (!Rtti::setIsOneOf(supportedTypes, parserTypes)) { + } else if (!supportsAllNodes && + !Rtti::setIsOneOf(supportedTypes, parserTypes)) { logger.error(std::string("Resource of type \"") + mimetype + std::string("\" cannot be included here!")); ok = false; @@ -245,8 +250,7 @@ bool ResourceRequest::deduce(Registry ®istry, Logger &logger) std::string("\" cannot be included here")); ok = false; } - } else if (supportedTypes.size() != 1 || - *supportedTypes.begin() != &RttiTypes::Node) { + } else if (!supportsAllNodes) { logger.warning(std::string( "Ambiguous resource relationship, consider " "specifying one of ") + diff --git a/src/formats/osml/OsmlParser.cpp b/src/formats/osml/OsmlParser.cpp index c77da09..a24f091 100644 --- a/src/formats/osml/OsmlParser.cpp +++ b/src/formats/osml/OsmlParser.cpp @@ -17,9 +17,13 @@ */ #include <core/common/Logger.hpp> + +#include <core/model/Document.hpp> + #include <core/parser/stack/GenericParserStates.hpp> #include <core/parser/stack/Stack.hpp> #include <core/parser/ParserContext.hpp> +#include <core/parser/ParserScope.hpp> #include "OsmlParser.hpp" #include "OsmlStreamParser.hpp" @@ -40,6 +44,11 @@ private: Logger &logger; /** + * Reference at the parser context. + */ + ParserContext &ctx; + + /** * OsmlStreamParser instance responsible for converting the input stream * into a series of osml events that are relayed to the Stack class. */ @@ -62,6 +71,7 @@ public: */ OsmlParserImplementation(CharReader &reader, ParserContext &ctx) : logger(ctx.getLogger()), + ctx(ctx), parser(reader, logger), stack(ctx, GenericParserStates) { @@ -73,7 +83,7 @@ public: void parse() { // Flag set to true if a "document" element needs to be created - bool needsDocument = true; + bool needsDocument = ctx.getScope().select<Document>() == nullptr; while (true) { OsmlStreamParser::State state = parser.parse(); logger.setDefaultLocation(parser.getLocation()); |