Implemented compatibility mode to support old instances.
This commit is contained in:
parent
dde277cc3e
commit
615167e7cd
@ -3,6 +3,7 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <pddlparse/Mode.h>
|
||||
#include <pddlparse/Tokenizer.h>
|
||||
|
||||
namespace pddl
|
||||
@ -27,9 +28,10 @@ struct Context
|
||||
Context() = default;
|
||||
~Context() = default;
|
||||
|
||||
explicit Context(Tokenizer &&tokenizer, WarningCallback warningCallback)
|
||||
explicit Context(Tokenizer &&tokenizer, WarningCallback warningCallback, Mode mode = Mode::Strict)
|
||||
: tokenizer{std::move(tokenizer)},
|
||||
warningCallback{warningCallback}
|
||||
warningCallback{warningCallback},
|
||||
mode{mode}
|
||||
{
|
||||
}
|
||||
|
||||
@ -40,6 +42,8 @@ struct Context
|
||||
|
||||
Tokenizer tokenizer;
|
||||
WarningCallback warningCallback;
|
||||
|
||||
Mode mode;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
27
lib/pddlparse/include/pddlparse/Mode.h
Normal file
27
lib/pddlparse/include/pddlparse/Mode.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef __PDDL_PARSE__MODE_H
|
||||
#define __PDDL_PARSE__MODE_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <pddlparse/Tokenizer.h>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Mode
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class Mode
|
||||
{
|
||||
Strict,
|
||||
Compatibility
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <pddlparse/Exception.h>
|
||||
#include <pddlparse/detail/parsing/Requirement.h>
|
||||
|
||||
namespace pddl
|
||||
@ -59,7 +60,10 @@ void checkRequirement(ast::Domain &domain, ast::Requirement requirement, Context
|
||||
if (hasRequirement(domain, requirement))
|
||||
return;
|
||||
|
||||
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared, silently adding requirement");
|
||||
if (context.mode == Mode::Compatibility)
|
||||
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared, silently adding requirement");
|
||||
else
|
||||
throw ParserException(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared");
|
||||
|
||||
domain.requirements.push_back(requirement);
|
||||
}
|
||||
@ -71,7 +75,10 @@ void checkRequirement(ast::Problem &problem, ast::Requirement requirement, Conte
|
||||
if (hasRequirement(problem, requirement))
|
||||
return;
|
||||
|
||||
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared, silently adding requirement");
|
||||
if (context.mode == Mode::Compatibility)
|
||||
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared, silently adding requirement");
|
||||
else
|
||||
throw ParserException(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared");
|
||||
|
||||
problem.requirements.push_back(requirement);
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ void ActionParser::findSections(ast::Action &action)
|
||||
setSectionPosition("precondition", m_preconditionPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("effect"))
|
||||
setSectionPosition("effect", m_effectPosition, position, true);
|
||||
else if (tokenizer.testIdentifierAndSkip("vars"))
|
||||
else if (m_context.mode == Mode::Compatibility && tokenizer.testIdentifierAndSkip("vars"))
|
||||
setSectionPosition("vars", m_varsPosition, position, true);
|
||||
else
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ void DescriptionParser::findSections()
|
||||
|
||||
tokenizer.expect<std::string>("(");
|
||||
|
||||
if (tokenizer.testAndReturn<std::string>("in-package"))
|
||||
if (m_context.mode == Mode::Compatibility && tokenizer.testAndReturn<std::string>("in-package"))
|
||||
{
|
||||
m_context.warningCallback(tokenizer.location(), "“in-package” section is not part of the PDDL 3.1 specification, ignoring section");
|
||||
|
||||
|
@ -35,6 +35,9 @@ ast::PrimitiveTypePointer parsePrimitiveType(Context &context, ast::Domain &doma
|
||||
// If the type has not been declared yet, add it but issue a warning
|
||||
if (matchingType == types.end())
|
||||
{
|
||||
if (context.mode != Mode::Compatibility)
|
||||
throw ParserException(tokenizer.location(), "primitive type “" + typeName + "” used without or before declaration");
|
||||
|
||||
context.warningCallback(tokenizer.location(), "primitive type “" + typeName + "” used without or before declaration, silently adding declaration");
|
||||
|
||||
types.emplace_back(std::make_unique<ast::PrimitiveTypeDeclaration>(std::move(typeName)));
|
||||
|
@ -66,7 +66,7 @@ std::experimental::optional<ast::Requirement> parseRequirement(Context &context)
|
||||
if (matchingRequirement != requirementNameMap.cend())
|
||||
return matchingRequirement->second;
|
||||
|
||||
if (requirementName == "goal-utilities" || requirementName == "domain-axioms")
|
||||
if (context.mode == Mode::Compatibility && (requirementName == "goal-utilities" || requirementName == "domain-axioms"))
|
||||
context.warningCallback(tokenizer.location(), "“" + requirementName + "” requirement is not part of the PDDL 3.1 specification, ignoring requirement");
|
||||
|
||||
return std::experimental::nullopt;
|
||||
|
@ -33,7 +33,7 @@ TEST_CASE("[PDDL parser acceptance] All official PDDL domains are parsed without
|
||||
{
|
||||
pddl::Tokenizer tokenizer;
|
||||
tokenizer.read(domainFile);
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings, pddl::Mode::Compatibility);
|
||||
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
@ -67,7 +67,7 @@ TEST_CASE("[PDDL parser acceptance] The first instance for all official PDDL dom
|
||||
pddl::Tokenizer tokenizer;
|
||||
tokenizer.read(domainFile);
|
||||
tokenizer.read(instanceFile);
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||
pddl::Context context(std::move(tokenizer), ignoreWarnings, pddl::Mode::Compatibility);
|
||||
|
||||
CHECK_NOTHROW(pddl::parseDescription(context));
|
||||
}
|
||||
|
@ -188,6 +188,8 @@ TEST_CASE("[PDDL parser] The official PDDL instances are parsed correctly", "[PD
|
||||
|
||||
SECTION("“either” type in zenotravel domain")
|
||||
{
|
||||
context.mode = pddl::Mode::Compatibility;
|
||||
|
||||
const auto domainFile = pddlInstanceBasePath / "ipc-2002" / "domains" / "zenotravel-numeric-hand-coded" / "domain.pddl";
|
||||
context.tokenizer.read(domainFile);
|
||||
auto description = pddl::parseDescription(context);
|
||||
|
Reference in New Issue
Block a user