Started reimplementing problem parser.
This commit is contained in:
parent
06b9632b70
commit
a7c4fdb242
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
|||||||
[submodule "lib/catch"]
|
[submodule "lib/catch"]
|
||||||
path = lib/catch
|
path = lib/catch
|
||||||
url = https://github.com/philsquared/Catch
|
url = https://github.com/philsquared/Catch
|
||||||
|
[submodule "lib/variant"]
|
||||||
|
path = lib/variant
|
||||||
|
url = https://github.com/mapbox/variant
|
||||||
|
@ -26,7 +26,7 @@ namespace ast
|
|||||||
|
|
||||||
struct Constant
|
struct Constant
|
||||||
{
|
{
|
||||||
explicit Constant(ConstantDeclaration &declaration)
|
explicit Constant(ConstantDeclaration *declaration)
|
||||||
: declaration{declaration}
|
: declaration{declaration}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ struct Constant
|
|||||||
Constant(Constant &&other) = default;
|
Constant(Constant &&other) = default;
|
||||||
Constant &operator=(Constant &&other) = default;
|
Constant &operator=(Constant &&other) = default;
|
||||||
|
|
||||||
ConstantDeclaration &declaration;
|
ConstantDeclaration *declaration;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -51,8 +51,8 @@ struct ConstantDeclaration
|
|||||||
|
|
||||||
ConstantDeclaration(const ConstantDeclaration &other) = delete;
|
ConstantDeclaration(const ConstantDeclaration &other) = delete;
|
||||||
ConstantDeclaration &operator=(const ConstantDeclaration &&other) = delete;
|
ConstantDeclaration &operator=(const ConstantDeclaration &&other) = delete;
|
||||||
ConstantDeclaration(ConstantDeclaration &&other) = default;
|
ConstantDeclaration(ConstantDeclaration &&other) = delete;
|
||||||
ConstantDeclaration &operator=(ConstantDeclaration &&other) = default;
|
ConstantDeclaration &operator=(ConstantDeclaration &&other) = delete;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::experimental::optional<Type> type;
|
std::experimental::optional<Type> type;
|
||||||
@ -79,7 +79,7 @@ struct Dummy
|
|||||||
|
|
||||||
struct PrimitiveType
|
struct PrimitiveType
|
||||||
{
|
{
|
||||||
explicit PrimitiveType(PrimitiveTypeDeclaration &declaration)
|
explicit PrimitiveType(PrimitiveTypeDeclaration *declaration)
|
||||||
: declaration{declaration}
|
: declaration{declaration}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ struct PrimitiveType
|
|||||||
PrimitiveType(PrimitiveType &&other) = default;
|
PrimitiveType(PrimitiveType &&other) = default;
|
||||||
PrimitiveType &operator=(PrimitiveType &&other) = default;
|
PrimitiveType &operator=(PrimitiveType &&other) = default;
|
||||||
|
|
||||||
PrimitiveTypeDeclaration &declaration;
|
PrimitiveTypeDeclaration *declaration;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -103,11 +103,11 @@ struct PrimitiveTypeDeclaration
|
|||||||
|
|
||||||
PrimitiveTypeDeclaration(const PrimitiveTypeDeclaration &other) = delete;
|
PrimitiveTypeDeclaration(const PrimitiveTypeDeclaration &other) = delete;
|
||||||
PrimitiveTypeDeclaration &operator=(const PrimitiveTypeDeclaration &&other) = delete;
|
PrimitiveTypeDeclaration &operator=(const PrimitiveTypeDeclaration &&other) = delete;
|
||||||
PrimitiveTypeDeclaration(PrimitiveTypeDeclaration &&other) = default;
|
PrimitiveTypeDeclaration(PrimitiveTypeDeclaration &&other) = delete;
|
||||||
PrimitiveTypeDeclaration &operator=(PrimitiveTypeDeclaration &&other) = default;
|
PrimitiveTypeDeclaration &operator=(PrimitiveTypeDeclaration &&other) = delete;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<PrimitiveType> parentTypes;
|
std::vector<PrimitiveTypePointer> parentTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -127,7 +127,7 @@ struct Unsupported
|
|||||||
|
|
||||||
struct Variable
|
struct Variable
|
||||||
{
|
{
|
||||||
explicit Variable(VariableDeclaration &declaration)
|
explicit Variable(VariableDeclaration *declaration)
|
||||||
: declaration{declaration}
|
: declaration{declaration}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ struct Variable
|
|||||||
Variable(Variable &&other) = default;
|
Variable(Variable &&other) = default;
|
||||||
Variable &operator=(Variable &&other) = default;
|
Variable &operator=(Variable &&other) = default;
|
||||||
|
|
||||||
VariableDeclaration &declaration;
|
VariableDeclaration *declaration;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -152,8 +152,8 @@ struct VariableDeclaration
|
|||||||
|
|
||||||
VariableDeclaration(const VariableDeclaration &other) = delete;
|
VariableDeclaration(const VariableDeclaration &other) = delete;
|
||||||
VariableDeclaration &operator=(const VariableDeclaration &&other) = delete;
|
VariableDeclaration &operator=(const VariableDeclaration &&other) = delete;
|
||||||
VariableDeclaration(VariableDeclaration &&other) = default;
|
VariableDeclaration(VariableDeclaration &&other) = delete;
|
||||||
VariableDeclaration &operator=(VariableDeclaration &&other) = default;
|
VariableDeclaration &operator=(VariableDeclaration &&other) = delete;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::experimental::optional<Type> type;
|
std::experimental::optional<Type> type;
|
||||||
@ -165,7 +165,7 @@ struct VariableDeclaration
|
|||||||
|
|
||||||
struct Predicate
|
struct Predicate
|
||||||
{
|
{
|
||||||
explicit Predicate(PredicateDeclaration &declaration)
|
explicit Predicate(PredicateDeclaration *declaration)
|
||||||
: declaration{declaration}
|
: declaration{declaration}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -176,8 +176,7 @@ struct Predicate
|
|||||||
Predicate &operator=(Predicate &&other) = default;
|
Predicate &operator=(Predicate &&other) = default;
|
||||||
|
|
||||||
Terms arguments;
|
Terms arguments;
|
||||||
|
PredicateDeclaration *declaration;
|
||||||
PredicateDeclaration &declaration;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -416,9 +415,9 @@ struct Action
|
|||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
ast::VariableDeclarations parameters;
|
VariableDeclarations parameters;
|
||||||
std::experimental::optional<ast::Precondition> precondition;
|
std::experimental::optional<Precondition> precondition;
|
||||||
std::experimental::optional<ast::Effect> effect;
|
std::experimental::optional<Effect> effect;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -429,15 +428,15 @@ struct Domain
|
|||||||
|
|
||||||
Domain(const Domain &other) = delete;
|
Domain(const Domain &other) = delete;
|
||||||
Domain &operator=(const Domain &&other) = delete;
|
Domain &operator=(const Domain &&other) = delete;
|
||||||
Domain(Domain &&other) = default;
|
Domain(Domain &&other) = delete;
|
||||||
Domain &operator=(Domain &&other) = default;
|
Domain &operator=(Domain &&other) = delete;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
Requirements requirements;
|
Requirements requirements;
|
||||||
ast::PrimitiveTypeDeclarations types;
|
PrimitiveTypeDeclarations types;
|
||||||
ast::ConstantDeclarations constants;
|
ConstantDeclarations constants;
|
||||||
ast::PredicateDeclarations predicates;
|
PredicateDeclarations predicates;
|
||||||
std::vector<Action> actions;
|
Actions actions;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -451,7 +450,7 @@ struct InitialState
|
|||||||
InitialState(InitialState &&other) = default;
|
InitialState(InitialState &&other) = default;
|
||||||
InitialState &operator=(InitialState &&other) = default;
|
InitialState &operator=(InitialState &&other) = default;
|
||||||
|
|
||||||
ast::Facts facts;
|
Facts facts;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -460,17 +459,22 @@ struct Problem
|
|||||||
{
|
{
|
||||||
Problem() = default;
|
Problem() = default;
|
||||||
|
|
||||||
|
Problem(Domain *domain)
|
||||||
|
: domain{domain}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Problem(const Problem &other) = delete;
|
Problem(const Problem &other) = delete;
|
||||||
Problem &operator=(const Problem &&other) = delete;
|
Problem &operator=(const Problem &&other) = delete;
|
||||||
Problem(Problem &&other) = default;
|
Problem(Problem &&other) = default;
|
||||||
Problem &operator=(Problem &&other) = default;
|
Problem &operator=(Problem &&other) = default;
|
||||||
|
|
||||||
Domain &domain;
|
Domain *domain;
|
||||||
std::string name;
|
std::string name;
|
||||||
Requirements requirements;
|
Requirements requirements;
|
||||||
ast::ConstantDeclarations objects;
|
ConstantDeclarations objects;
|
||||||
InitialState initialState;
|
InitialState initialState;
|
||||||
std::experimental::optional<ast::Goal> goal;
|
std::experimental::optional<Goal> goal;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -512,8 +516,8 @@ struct Description
|
|||||||
Description(Description &&other) = default;
|
Description(Description &&other) = default;
|
||||||
Description &operator=(Description &&other) = default;
|
Description &operator=(Description &&other) = default;
|
||||||
|
|
||||||
Domain domain;
|
DomainPointer domain;
|
||||||
std::experimental::optional<Problem> problem;
|
std::experimental::optional<ProblemPointer> problem;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -26,27 +26,37 @@ namespace ast
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct Constant;
|
struct Constant;
|
||||||
|
using ConstantPointer = std::unique_ptr<Constant>;
|
||||||
struct ConstantDeclaration;
|
struct ConstantDeclaration;
|
||||||
using ConstantDeclarations = std::vector<ConstantDeclaration>;
|
using ConstantDeclarationPointer = std::unique_ptr<ConstantDeclaration>;
|
||||||
|
using ConstantDeclarations = std::vector<ConstantDeclarationPointer>;
|
||||||
struct Dummy;
|
struct Dummy;
|
||||||
|
using DummyPointer = std::unique_ptr<Dummy>;
|
||||||
struct PrimitiveType;
|
struct PrimitiveType;
|
||||||
using PrimitiveTypes = std::vector<PrimitiveType>;
|
using PrimitiveTypePointer = std::unique_ptr<PrimitiveType>;
|
||||||
|
using PrimitiveTypes = std::vector<PrimitiveTypePointer>;
|
||||||
struct PrimitiveTypeDeclaration;
|
struct PrimitiveTypeDeclaration;
|
||||||
using PrimitiveTypeDeclarations = std::vector<PrimitiveTypeDeclaration>;
|
using PrimitiveTypeDeclarationPointer = std::unique_ptr<PrimitiveTypeDeclaration>;
|
||||||
|
using PrimitiveTypeDeclarations = std::vector<PrimitiveTypeDeclarationPointer>;
|
||||||
struct Unsupported;
|
struct Unsupported;
|
||||||
|
using UnsupportedPointer = std::unique_ptr<Unsupported>;
|
||||||
struct Variable;
|
struct Variable;
|
||||||
using Variables = std::vector<Variable>;
|
using VariablePointer = std::unique_ptr<Variable>;
|
||||||
|
using Variables = std::vector<VariablePointer>;
|
||||||
struct VariableDeclaration;
|
struct VariableDeclaration;
|
||||||
using VariableDeclarations = std::vector<VariableDeclaration>;
|
using VariableDeclarationPointer = std::unique_ptr<VariableDeclaration>;
|
||||||
|
using VariableDeclarations = std::vector<VariableDeclarationPointer>;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Compounds
|
// Compounds
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct Predicate;
|
struct Predicate;
|
||||||
using Predicates = std::vector<Predicate>;
|
using PredicatePointer = std::unique_ptr<Predicate>;
|
||||||
|
using Predicates = std::vector<PredicatePointer>;
|
||||||
struct PredicateDeclaration;
|
struct PredicateDeclaration;
|
||||||
using PredicateDeclarations = std::vector<PredicateDeclaration>;
|
using PredicateDeclarationPointer = std::unique_ptr<PredicateDeclaration>;
|
||||||
|
using PredicateDeclarations = std::vector<PredicateDeclarationPointer>;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Expressions
|
// Expressions
|
||||||
@ -55,29 +65,53 @@ using PredicateDeclarations = std::vector<PredicateDeclaration>;
|
|||||||
template<class Argument>
|
template<class Argument>
|
||||||
struct And;
|
struct And;
|
||||||
template<class Argument>
|
template<class Argument>
|
||||||
|
using AndPointer = std::unique_ptr<And<Argument>>;
|
||||||
|
template<class Argument>
|
||||||
struct At;
|
struct At;
|
||||||
template<class Argument>
|
template<class Argument>
|
||||||
|
using AtPointer = std::unique_ptr<At<Argument>>;
|
||||||
|
template<class Argument>
|
||||||
struct Either;
|
struct Either;
|
||||||
template<class Argument>
|
template<class Argument>
|
||||||
|
using EitherPointer = std::unique_ptr<Either<Argument>>;
|
||||||
|
template<class Argument>
|
||||||
struct Exists;
|
struct Exists;
|
||||||
template<class Argument>
|
template<class Argument>
|
||||||
|
using ExistsPointer = std::unique_ptr<Exists<Argument>>;
|
||||||
|
template<class Argument>
|
||||||
struct ForAll;
|
struct ForAll;
|
||||||
template<class Argument>
|
template<class Argument>
|
||||||
|
using ForAllPointer = std::unique_ptr<ForAll<Argument>>;
|
||||||
|
template<class Argument>
|
||||||
struct Imply;
|
struct Imply;
|
||||||
template<class Argument>
|
template<class Argument>
|
||||||
|
using ImplyPointer = std::unique_ptr<Imply<Argument>>;
|
||||||
|
template<class Argument>
|
||||||
struct Not;
|
struct Not;
|
||||||
template<class Argument>
|
template<class Argument>
|
||||||
|
using NotPointer = std::unique_ptr<Not<Argument>>;
|
||||||
|
template<class Argument>
|
||||||
struct Or;
|
struct Or;
|
||||||
|
template<class Argument>
|
||||||
|
using OrPointer = std::unique_ptr<Or<Argument>>;
|
||||||
template<class ArgumentLeft, class ArgumentRight>
|
template<class ArgumentLeft, class ArgumentRight>
|
||||||
struct When;
|
struct When;
|
||||||
|
template<class ArgumentLeft, class ArgumentRight>
|
||||||
|
using WhenPointer = std::unique_ptr<When<ArgumentLeft, ArgumentRight>>;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// PDDL Structure
|
// PDDL Structure
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Action;
|
||||||
|
using ActionPointer = std::unique_ptr<Action>;
|
||||||
|
using Actions = std::vector<ActionPointer>;
|
||||||
struct Description;
|
struct Description;
|
||||||
|
using DescriptionPointer = std::unique_ptr<Description>;
|
||||||
struct Domain;
|
struct Domain;
|
||||||
|
using DomainPointer = std::unique_ptr<Domain>;
|
||||||
struct Problem;
|
struct Problem;
|
||||||
|
using ProblemPointer = std::unique_ptr<Problem>;
|
||||||
enum class Requirement;
|
enum class Requirement;
|
||||||
using Requirements = std::vector<Requirement>;
|
using Requirements = std::vector<Requirement>;
|
||||||
|
|
||||||
@ -88,8 +122,8 @@ using Requirements = std::vector<Requirement>;
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
using TermT = Variant<
|
using TermT = Variant<
|
||||||
Constant,
|
ConstantPointer,
|
||||||
Variable>;
|
VariablePointer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Term : public detail::TermT
|
class Term : public detail::TermT
|
||||||
@ -104,8 +138,8 @@ using Terms = std::vector<Term>;
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
using AtomicFormulaT = Variant<
|
using AtomicFormulaT = Variant<
|
||||||
Predicate,
|
PredicatePointer,
|
||||||
Unsupported>;
|
UnsupportedPointer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AtomicFormula : public detail::AtomicFormulaT
|
class AtomicFormula : public detail::AtomicFormulaT
|
||||||
@ -121,13 +155,13 @@ namespace detail
|
|||||||
{
|
{
|
||||||
using PreconditionT = Variant<
|
using PreconditionT = Variant<
|
||||||
AtomicFormula,
|
AtomicFormula,
|
||||||
And<Precondition>,
|
AndPointer<Precondition>,
|
||||||
Exists<Precondition>,
|
ExistsPointer<Precondition>,
|
||||||
ForAll<Precondition>,
|
ForAllPointer<Precondition>,
|
||||||
Imply<Precondition>,
|
ImplyPointer<Precondition>,
|
||||||
Not<Precondition>,
|
NotPointer<Precondition>,
|
||||||
Or<Precondition>,
|
OrPointer<Precondition>,
|
||||||
Unsupported>;
|
UnsupportedPointer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Precondition : public detail::PreconditionT
|
class Precondition : public detail::PreconditionT
|
||||||
@ -145,11 +179,11 @@ namespace detail
|
|||||||
{
|
{
|
||||||
using EffectT = Variant<
|
using EffectT = Variant<
|
||||||
AtomicFormula,
|
AtomicFormula,
|
||||||
And<Effect>,
|
AndPointer<Effect>,
|
||||||
ForAll<Effect>,
|
ForAllPointer<Effect>,
|
||||||
Not<Effect>,
|
NotPointer<Effect>,
|
||||||
When<Precondition, Effect>,
|
WhenPointer<Precondition, Effect>,
|
||||||
Unsupported>;
|
UnsupportedPointer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Effect : public detail::EffectT
|
class Effect : public detail::EffectT
|
||||||
@ -162,8 +196,8 @@ class Effect : public detail::EffectT
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
using TypeT = Variant<
|
using TypeT = Variant<
|
||||||
Either<PrimitiveType>,
|
EitherPointer<PrimitiveTypePointer>,
|
||||||
PrimitiveType>;
|
PrimitiveTypePointer>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Type : public detail::TypeT
|
class Type : public detail::TypeT
|
||||||
@ -177,7 +211,7 @@ namespace detail
|
|||||||
{
|
{
|
||||||
using LiteralT = Variant<
|
using LiteralT = Variant<
|
||||||
AtomicFormula,
|
AtomicFormula,
|
||||||
Not<AtomicFormula>>;
|
NotPointer<AtomicFormula>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Literal : public detail::LiteralT
|
class Literal : public detail::LiteralT
|
||||||
@ -193,7 +227,7 @@ namespace detail
|
|||||||
{
|
{
|
||||||
using FactT = Variant<
|
using FactT = Variant<
|
||||||
AtomicFormula,
|
AtomicFormula,
|
||||||
At<Literal>>;
|
AtPointer<Literal>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Fact : public detail::FactT
|
class Fact : public detail::FactT
|
||||||
|
49
lib/pddlparse/include/pddlparse/Context.h
Normal file
49
lib/pddlparse/include/pddlparse/Context.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef __PDDL_PARSE__CONTEXT_H
|
||||||
|
#define __PDDL_PARSE__CONTEXT_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <pddlparse/Tokenizer.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Context
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
constexpr static const char *auxiliaryPrefix()
|
||||||
|
{
|
||||||
|
return "__plasp_";
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: replace std::string with char *
|
||||||
|
using WarningCallback = std::function<void (tokenize::Location, const std::string &)>;
|
||||||
|
|
||||||
|
Context() = default;
|
||||||
|
~Context() = default;
|
||||||
|
|
||||||
|
explicit Context(Tokenizer &&tokenizer, WarningCallback warningCallback)
|
||||||
|
: tokenizer{std::move(tokenizer)},
|
||||||
|
warningCallback{warningCallback}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Context(const Context &other) = delete;
|
||||||
|
Context &operator=(const Context &other) = delete;
|
||||||
|
Context(Context &&other) = default;
|
||||||
|
Context &operator=(Context &&other) = default;
|
||||||
|
|
||||||
|
Tokenizer tokenizer;
|
||||||
|
WarningCallback warningCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
24
lib/pddlparse/include/pddlparse/Parse.h
Normal file
24
lib/pddlparse/include/pddlparse/Parse.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef __PDDL_PARSE__PARSE_H
|
||||||
|
#define __PDDL_PARSE__PARSE_H
|
||||||
|
|
||||||
|
#include <experimental/optional>
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Parse
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::Description parseDescription(Context &context);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,233 +1,20 @@
|
|||||||
#ifndef __PDDL_PARSE__VARIANT_H
|
#ifndef __PDDL_PARSE__VARIANT_H
|
||||||
#define __PDDL_PARSE__VARIANT_H
|
#define __PDDL_PARSE__VARIANT_H
|
||||||
|
|
||||||
#include <cassert>
|
#include <mapbox/variant.hpp>
|
||||||
#include <memory>
|
|
||||||
#include <ostream>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace pddl
|
namespace pddl
|
||||||
{
|
{
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Variant (from clingo, written by Roland Kaminski)
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace detail {
|
template<class... Types>
|
||||||
|
using Variant = mapbox::util::variant<Types...>;
|
||||||
template <class T, class... U>
|
|
||||||
struct TypeInList : std::false_type { };
|
|
||||||
|
|
||||||
template <class T, class... U>
|
|
||||||
struct TypeInList<T, T, U...> : std::true_type { };
|
|
||||||
|
|
||||||
template <class T, class V, class... U>
|
|
||||||
struct TypeInList<T, V, U...> : TypeInList<T, U...> { };
|
|
||||||
|
|
||||||
template <unsigned, class... U>
|
|
||||||
struct VariantHolder;
|
|
||||||
|
|
||||||
template <unsigned n>
|
|
||||||
struct VariantHolder<n> {
|
|
||||||
bool check_type() const { return type_ == 0; }
|
|
||||||
void emplace() { }
|
|
||||||
void emplace2() { }
|
|
||||||
void copy(VariantHolder const &) { }
|
|
||||||
void destroy() {
|
|
||||||
type_ = 0;
|
|
||||||
data_ = nullptr;
|
|
||||||
}
|
|
||||||
void print(std::ostream &) const { }
|
|
||||||
void swap(VariantHolder &other) {
|
|
||||||
std::swap(type_, other.type_);
|
|
||||||
std::swap(data_, other.data_);
|
|
||||||
}
|
|
||||||
unsigned type_ = 0;
|
|
||||||
void *data_ = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <unsigned n, class T, class... U>
|
|
||||||
struct VariantHolder<n, T, U...> : VariantHolder<n+1, U...>{
|
|
||||||
using Helper = VariantHolder<n+1, U...>;
|
|
||||||
using Helper::check_type;
|
|
||||||
using Helper::emplace;
|
|
||||||
using Helper::emplace2;
|
|
||||||
using Helper::data_;
|
|
||||||
using Helper::type_;
|
|
||||||
bool check_type(T *) const { return type_ == n; }
|
|
||||||
template <class... Args>
|
|
||||||
void emplace(T *, Args&& ...x) {
|
|
||||||
data_ = new T{std::forward<Args>(x)...};
|
|
||||||
type_ = n;
|
|
||||||
}
|
|
||||||
// NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467
|
|
||||||
template <class... Args>
|
|
||||||
void emplace2(T *, Args&& ...x) {
|
|
||||||
data_ = new T(std::forward<Args>(x)...);
|
|
||||||
type_ = n;
|
|
||||||
}
|
|
||||||
void copy(VariantHolder const &src) {
|
|
||||||
if (src.type_ == n) {
|
|
||||||
data_ = new T(*static_cast<T const*>(src.data_));
|
|
||||||
type_ = src.type_;
|
|
||||||
}
|
|
||||||
Helper::copy(src);
|
|
||||||
}
|
|
||||||
// NOTE: workaround for visual studio (C++14 can also simply use auto)
|
|
||||||
# define CLINGO_VARIANT_RETURN(Type) decltype(std::declval<V>().visit(std::declval<Type&>(), std::declval<Args>()...))
|
|
||||||
template <class V, class... Args>
|
|
||||||
using Ret_ = CLINGO_VARIANT_RETURN(T);
|
|
||||||
template <class V, class... Args>
|
|
||||||
using ConstRet_ = CLINGO_VARIANT_RETURN(T const);
|
|
||||||
// non-const
|
|
||||||
template <class V, class U1, class... U2, class... Args>
|
|
||||||
auto accept_(V &&visitor, Args &&... args) -> CLINGO_VARIANT_RETURN(T) {
|
|
||||||
static_assert(std::is_same<Ret_<V, Args...>, typename Helper::template Ret_<V, Args...>>::value, "");
|
|
||||||
return n == type_
|
|
||||||
? visitor.visit(*static_cast<T*>(data_), std::forward<Args>(args)...)
|
|
||||||
: Helper::template accept<V>(std::forward<V>(visitor), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
template <class V, class... Args>
|
|
||||||
auto accept_(V &&visitor, Args &&... args) -> CLINGO_VARIANT_RETURN(T) {
|
|
||||||
assert(n == type_);
|
|
||||||
return visitor.visit(*static_cast<T*>(data_), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
template <class V, class... Args>
|
|
||||||
auto accept(V &&visitor, Args &&... args) -> CLINGO_VARIANT_RETURN(T) {
|
|
||||||
return accept_<V, U...>(std::forward<V>(visitor), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
// const
|
|
||||||
template <class V, class U1, class... U2, class... Args>
|
|
||||||
auto accept_(V &&visitor, Args &&... args) const -> CLINGO_VARIANT_RETURN(T const) {
|
|
||||||
static_assert(std::is_same<ConstRet_<V, Args...>, typename Helper::template ConstRet_<V, Args...>>::value, "");
|
|
||||||
return n == type_
|
|
||||||
? visitor.visit(*static_cast<T const *>(data_), std::forward<Args>(args)...)
|
|
||||||
: Helper::template accept<V>(std::forward<V>(visitor), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
template <class V, class... Args>
|
|
||||||
auto accept_(V &&visitor, Args &&... args) const -> CLINGO_VARIANT_RETURN(T const) {
|
|
||||||
assert(n == type_);
|
|
||||||
return visitor.visit(*static_cast<T const *>(data_), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
template <class V, class... Args>
|
|
||||||
auto accept(V &&visitor, Args &&... args) const -> CLINGO_VARIANT_RETURN(T const) {
|
|
||||||
return accept_<V, U...>(std::forward<V>(visitor), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
# undef CLINGO_VARIANT_RETURN
|
|
||||||
void destroy() {
|
|
||||||
if (n == type_) { delete static_cast<T*>(data_); }
|
|
||||||
Helper::destroy();
|
|
||||||
}
|
|
||||||
void print(std::ostream &out) const {
|
|
||||||
if (n == type_) { out << *static_cast<T const*>(data_); }
|
|
||||||
Helper::print(out);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... T>
|
|
||||||
class Variant {
|
|
||||||
using Holder = detail::VariantHolder<1, T...>;
|
|
||||||
public:
|
|
||||||
Variant(Variant const &other) : Variant(other.data_) { }
|
|
||||||
Variant(Variant &&other) noexcept { data_.swap(other.data_); }
|
|
||||||
template <class U>
|
|
||||||
Variant(U &&u, typename std::enable_if<detail::TypeInList<U, T...>::value>::type * = nullptr) { emplace2<U>(std::forward<U>(u)); }
|
|
||||||
template <class U>
|
|
||||||
Variant(U &u, typename std::enable_if<detail::TypeInList<U, T...>::value>::type * = nullptr) { emplace2<U>(u); }
|
|
||||||
template <class U>
|
|
||||||
Variant(U const &u, typename std::enable_if<detail::TypeInList<U, T...>::value>::type * = nullptr) { emplace2<U>(u); }
|
|
||||||
template <class U, class... Args>
|
|
||||||
static Variant make(Args&& ...args) {
|
|
||||||
Variant<T...> x;
|
|
||||||
x.data_.emplace(static_cast<U*>(nullptr), std::forward<Args>(args)...);
|
|
||||||
return std::move(x);
|
|
||||||
}
|
|
||||||
~Variant() { data_.destroy(); }
|
|
||||||
Variant &operator=(Variant const &other) { return *this = other.data_; }
|
|
||||||
Variant &operator=(Variant &&other) noexcept { return *this = std::move(other.data_); }
|
|
||||||
template <class U>
|
|
||||||
typename std::enable_if<detail::TypeInList<U, T...>::value, Variant>::type &operator=(U &&u) {
|
|
||||||
emplace2<U>(std::forward<U>(u));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template <class U>
|
|
||||||
typename std::enable_if<detail::TypeInList<U, T...>::value, Variant>::type &operator=(U &u) {
|
|
||||||
emplace2<U>(u);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template <class U>
|
|
||||||
typename std::enable_if<detail::TypeInList<U, T...>::value, Variant>::type &operator=(U const &u) {
|
|
||||||
emplace2<U>(u);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template <class U>
|
|
||||||
U &get() {
|
|
||||||
if (!data_.check_type(static_cast<U*>(nullptr))) { throw std::bad_cast(); }
|
|
||||||
return *static_cast<U*>(data_.data_);
|
|
||||||
}
|
|
||||||
template <class U>
|
|
||||||
U const &get() const {
|
|
||||||
if (!data_.check_type(static_cast<U*>(nullptr))) { throw std::bad_cast(); }
|
|
||||||
return *static_cast<U*>(data_.data_);
|
|
||||||
}
|
|
||||||
template <class U, class... Args>
|
|
||||||
void emplace(Args&& ...args) {
|
|
||||||
Variant<T...> x;
|
|
||||||
x.data_.emplace(static_cast<U*>(nullptr), std::forward<Args>(args)...);
|
|
||||||
data_.swap(x.data_);
|
|
||||||
}
|
|
||||||
template <class U>
|
|
||||||
bool is() const { return data_.check_type(static_cast<U*>(nullptr)); }
|
|
||||||
void swap(Variant &other) { data_.swap(other.data_); }
|
|
||||||
template <class V, class... Args>
|
|
||||||
typename Holder::template Ret_<V, Args...> accept(V &&visitor, Args &&... args) {
|
|
||||||
return data_.accept(std::forward<V>(visitor), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
template <class V, class... Args>
|
|
||||||
typename Holder::template ConstRet_<V, Args...> accept(V &&visitor, Args &&... args) const {
|
|
||||||
return data_.accept(std::forward<V>(visitor), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
friend std::ostream &operator<<(std::ostream &out, Variant const &x) {
|
|
||||||
x.data_.print(out);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Variant() { }
|
|
||||||
Variant(Holder const &data) {
|
|
||||||
data_.copy(data);
|
|
||||||
}
|
|
||||||
Variant &operator=(Holder const &data) {
|
|
||||||
Variant x(data);
|
|
||||||
data_.swap(x.data_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Variant &operator=(Holder &&data) noexcept {
|
|
||||||
Holder x;
|
|
||||||
x.swap(data);
|
|
||||||
// Destroy the old data_ only after securing the new data
|
|
||||||
// Otherwise, data would be destroyed together with data_ if it was a descendant of data_
|
|
||||||
data_.destroy();
|
|
||||||
x.swap(data_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
template <class U, class... Args>
|
|
||||||
void emplace2(Args&& ...args) {
|
|
||||||
Variant<T...> x;
|
|
||||||
x.data_.emplace2(static_cast<U*>(nullptr), std::forward<Args>(args)...);
|
|
||||||
data_.swap(x.data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Holder data_;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
48
lib/pddlparse/include/pddlparse/detail/ASTContext.h
Normal file
48
lib/pddlparse/include/pddlparse/detail/ASTContext.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__AST_CONTEXT_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__AST_CONTEXT_H
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/detail/VariableStack.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ASTContext
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct ASTContext
|
||||||
|
{
|
||||||
|
ASTContext(ast::Description &description)
|
||||||
|
: domain{description.domain.get()},
|
||||||
|
problem{description.problem.value() ? std::experimental::optional<ast::Problem *>(description.problem.value().get()) : std::experimental::nullopt}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTContext(ast::Domain &domain)
|
||||||
|
: domain{&domain}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTContext(ast::Problem &problem)
|
||||||
|
: domain{problem.domain},
|
||||||
|
problem{&problem}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ast::Domain *domain;
|
||||||
|
std::experimental::optional<ast::Problem *> problem;
|
||||||
|
|
||||||
|
VariableStack variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
161
lib/pddlparse/include/pddlparse/detail/ASTCopy.h
Normal file
161
lib/pddlparse/include/pddlparse/detail/ASTCopy.h
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__AST_COPY_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__AST_COPY_H
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace ast
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ASTCopy
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Primitives
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline Constant deepCopy(Constant &other);
|
||||||
|
inline PrimitiveType deepCopy(PrimitiveType &other);
|
||||||
|
inline Variable deepCopy(Variable &other);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Expressions: Base Classes
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived, class ArgumentLeft, class ArgumentRight = ArgumentLeft>
|
||||||
|
inline Binary<Derived, ArgumentLeft, ArgumentRight> deepCopy(Binary<Derived, ArgumentLeft, ArgumentRight> &other);
|
||||||
|
template<class Derived, class Argument>
|
||||||
|
inline NAry<Derived, Argument> deepCopy(NAry<Derived, Argument> &other);
|
||||||
|
template<class Derived, class Argument>
|
||||||
|
inline Quantified<Derived, Argument> deepCopy(Quantified<Derived, Argument> &other);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Expressions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Argument>
|
||||||
|
inline At<Argument> deepCopy(At<Argument> &other);
|
||||||
|
template<class Argument>
|
||||||
|
inline Not<Argument> deepCopy(Not<Argument> &other);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Variants
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline ast::Term deepCopy(ast::Term &other);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Primitives
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Constant deepCopy(Constant &other)
|
||||||
|
{
|
||||||
|
return Constant(other.declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PrimitiveType deepCopy(PrimitiveType &other)
|
||||||
|
{
|
||||||
|
return PrimitiveType(other.declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Variable deepCopy(Variable &other)
|
||||||
|
{
|
||||||
|
return Variable(other.declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Expressions: Base Classes
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived, class ArgumentLeft, class ArgumentRight>
|
||||||
|
Binary<Derived, ArgumentLeft, ArgumentRight> deepCopy(Binary<Derived, ArgumentLeft, ArgumentRight> &other)
|
||||||
|
{
|
||||||
|
auto argumentLeft = deepCopy(other.argumentLeft);
|
||||||
|
auto argumentRight = deepCopy(other.argumentRight);
|
||||||
|
|
||||||
|
return Binary<Derived, ArgumentLeft, ArgumentRight>(std::move(argumentLeft), std::move(argumentRight));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived, class Argument>
|
||||||
|
NAry<Derived, Argument> deepCopy(NAry<Derived, Argument> &other)
|
||||||
|
{
|
||||||
|
typename NAry<Derived, Argument>::Arguments arguments;
|
||||||
|
arguments.reserve(other.arguments.size());
|
||||||
|
|
||||||
|
for (auto &argument : other.arguments)
|
||||||
|
arguments.emplace_back(deepCopy(argument));
|
||||||
|
|
||||||
|
return NAry<Derived, Argument>(std::move(arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived, class Argument>
|
||||||
|
Quantified<Derived, Argument> deepCopy(Quantified<Derived, Argument> &other)
|
||||||
|
{
|
||||||
|
auto argument = deepCopy(other.argument);
|
||||||
|
|
||||||
|
return Quantified<Derived, Argument>(std::move(argument));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Expressions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Argument>
|
||||||
|
At<Argument> deepCopy(At<Argument> &other)
|
||||||
|
{
|
||||||
|
auto argument = deepCopy(other.argument);
|
||||||
|
|
||||||
|
return At<Argument>(other.timePoint, std::move(argument));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Argument>
|
||||||
|
Not<Argument> deepCopy(Not<Argument> &other)
|
||||||
|
{
|
||||||
|
auto argument = deepCopy(other.argument);
|
||||||
|
|
||||||
|
return Not<Argument>(std::move(argument));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Variants
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct DeepCopyVisitor
|
||||||
|
{
|
||||||
|
template<class Argument>
|
||||||
|
Argument visit(Argument &other)
|
||||||
|
{
|
||||||
|
return deepCopy(other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Unique Pointers
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
std::unique_ptr<T> deepCopy(std::unique_ptr<T> &other)
|
||||||
|
{
|
||||||
|
return std::make_unique<T>(deepCopy(*other));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
33
lib/pddlparse/include/pddlparse/detail/Requirements.h
Normal file
33
lib/pddlparse/include/pddlparse/detail/Requirements.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__REQUIREMENTS_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__REQUIREMENTS_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
#include <pddlparse/detail/ASTContext.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Requirements
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool hasRequirement(const ast::Domain &domain, ast::Requirement requirement);
|
||||||
|
bool hasRequirement(const ast::Problem &problem, ast::Requirement requirement);
|
||||||
|
bool hasRequirement(const ASTContext &astContext, ast::Requirement requirement);
|
||||||
|
|
||||||
|
void checkRequirement(ast::Domain &domain, ast::Requirement requirement, Context &context);
|
||||||
|
void checkRequirement(ast::Problem &problem, ast::Requirement requirement, Context &context);
|
||||||
|
void checkRequirement(ASTContext &astContext, ast::Requirement requirement, Context &context);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
127
lib/pddlparse/include/pddlparse/detail/parsing/AST.h
Normal file
127
lib/pddlparse/include/pddlparse/detail/parsing/AST.h
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__AST_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__AST_H
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/detail/parsing/Parser.h>
|
||||||
|
#include <pddlparse/detail/parsing/Utils.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ParseAST
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Primitives
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Parser<ast::Constant>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Parser<ast::ConstantDeclaration>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Parser<ast::PrimitiveType>
|
||||||
|
{
|
||||||
|
std::experimental::optional<ast::PrimitiveType> parse(Context &context, ASTContext &astContext)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
auto &types = astContext.description.domain.types;
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
auto typeName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
if (typeName.empty())
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "no type supplied");
|
||||||
|
|
||||||
|
auto matchingType = std::find_if(types.begin(), types.end(),
|
||||||
|
[&](auto &primitiveTypeDeclaration)
|
||||||
|
{
|
||||||
|
return primitiveTypeDeclaration->name == typeName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingType == types.end())
|
||||||
|
{
|
||||||
|
// Only “object” is allowed as an implicit type
|
||||||
|
if (typeName == "object" || typeName == "objects")
|
||||||
|
{
|
||||||
|
context.warningCallback(tokenizer.location(), "primitive type “" + typeName + "” should be declared");
|
||||||
|
types.emplace_back(std::make_unique<ast::PrimitiveTypeDeclaration>(std::move(typeName)));
|
||||||
|
|
||||||
|
return ast::PrimitiveType(types.back());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "type “" + typeName + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &type = *matchingType;
|
||||||
|
|
||||||
|
return ast::PrimitiveType(type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Parser<ast::PrimitiveTypeDeclaration>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Parser<ast::Unsupported>
|
||||||
|
{
|
||||||
|
std::experimental::optional<ast::Unsupported> parse(Context &context, ASTContext &)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
|
||||||
|
ast::Unsupported unsupported;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
|
||||||
|
unsupported.type = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
context.warningCallback(tokenizer.location(), "expression type “" + unsupported.type + "” currently unsupported in this context");
|
||||||
|
|
||||||
|
skipSection(tokenizer);
|
||||||
|
|
||||||
|
return unsupported;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Expressions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Argument>
|
||||||
|
struct Parser<ast::And<Argument>>
|
||||||
|
{
|
||||||
|
template<typename ArgumentParser>
|
||||||
|
std::experimental::optional<ast::And<Argument>> parse(Context &context, ASTContext &astContext, ArgumentParser parseArgument)
|
||||||
|
{
|
||||||
|
return Parser<ast::NAry<ast::And<Argument>, Argument>>::parse(context, astContext, parseArgument);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
25
lib/pddlparse/include/pddlparse/detail/parsing/Action.h
Normal file
25
lib/pddlparse/include/pddlparse/detail/parsing/Action.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__ACTION_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__ACTION_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Action
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddAction(Context &context, ast::Domain &domain);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
lib/pddlparse/include/pddlparse/detail/parsing/Constant.h
Normal file
26
lib/pddlparse/include/pddlparse/detail/parsing/Constant.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__CONSTANT_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__CONSTANT_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Constant
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain);
|
||||||
|
ast::ConstantPointer parseConstant(Context &context, ast::Problem &problem);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__CONSTANT_DECLARATION_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__CONSTANT_DECLARATION_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ConstantDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddConstantDeclarations(Context &context, ast::Domain &domain);
|
||||||
|
void parseAndAddConstantDeclarations(Context &context, ast::Problem &problem);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
39
lib/pddlparse/include/pddlparse/detail/parsing/Description.h
Normal file
39
lib/pddlparse/include/pddlparse/detail/parsing/Description.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__DESCRIPTION_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__DESCRIPTION_H
|
||||||
|
|
||||||
|
#include <experimental/optional>
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Description
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class DescriptionParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DescriptionParser(Context &context);
|
||||||
|
ast::Description parse();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void findSections();
|
||||||
|
|
||||||
|
Context &m_context;
|
||||||
|
tokenize::Stream::Position m_domainPosition;
|
||||||
|
tokenize::Stream::Position m_problemPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
50
lib/pddlparse/include/pddlparse/detail/parsing/Domain.h
Normal file
50
lib/pddlparse/include/pddlparse/detail/parsing/Domain.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__DOMAIN_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__DOMAIN_H
|
||||||
|
|
||||||
|
#include <experimental/optional>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Domain
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class DomainParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DomainParser(Context &context);
|
||||||
|
ast::DomainPointer parse();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void findSections(ast::Domain &domain);
|
||||||
|
|
||||||
|
void parseRequirementSection(ast::Domain &domain);
|
||||||
|
void computeDerivedRequirements(ast::Domain &domain);
|
||||||
|
void parseTypeSection(ast::Domain &domain);
|
||||||
|
void parseConstantSection(ast::Domain &domain);
|
||||||
|
void parsePredicateSection(ast::Domain &domain);
|
||||||
|
void parseActionSection(ast::Domain &domain);
|
||||||
|
|
||||||
|
Context &m_context;
|
||||||
|
|
||||||
|
tokenize::Stream::Position m_requirementsPosition;
|
||||||
|
tokenize::Stream::Position m_typesPosition;
|
||||||
|
tokenize::Stream::Position m_constantsPosition;
|
||||||
|
tokenize::Stream::Position m_predicatesPosition;
|
||||||
|
std::vector<tokenize::Stream::Position> m_actionPositions;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__INITIAL_STATE_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__INITIAL_STATE_H
|
||||||
|
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
#include <pddlparse/detail/ASTContext.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// InitialState
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::InitialState parseInitialState(Context &context, ASTContext &expressionContext);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
43
lib/pddlparse/include/pddlparse/detail/parsing/Parser.h
Normal file
43
lib/pddlparse/include/pddlparse/detail/parsing/Parser.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSER_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSER_H
|
||||||
|
|
||||||
|
#include <experimental/optional>
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
#include <pddlparse/detail/ASTContext.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Parser
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct Parser
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, typename... ArgumentParser>
|
||||||
|
std::experimental::optional<T> parse(Context &context, ASTContext &astContext, ArgumentParser... argumentParsers)
|
||||||
|
{
|
||||||
|
return detail::Parser<T>().parse(context, astContext, argumentParsers...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
std::experimental::optional<T> parse(Context &context, ASTContext &astContext)
|
||||||
|
{
|
||||||
|
return detail::Parser<T>().parse(context, astContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__PREDICATE_DECLARATION_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__PREDICATE_DECLARATION_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PredicateDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddPredicateDeclarations(Context &context, ast::Domain &domain);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__PRIMITIVE_TYPE_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__PRIMITIVE_TYPE_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PrimitiveType
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::PrimitiveTypePointer parsePrimitiveType(Context &context, ast::Domain &domain);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__PRIMITIVE_TYPE_DECLARATION_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__PRIMITIVE_TYPE_DECLARATION_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PrimitiveTypeDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddPrimitiveTypeDeclarations(Context &context, ast::Domain &domain);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
51
lib/pddlparse/include/pddlparse/detail/parsing/Problem.h
Normal file
51
lib/pddlparse/include/pddlparse/detail/parsing/Problem.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__PROBLEM_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__PROBLEM_H
|
||||||
|
|
||||||
|
#include <experimental/optional>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Problem
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class ProblemParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProblemParser(Context &context, ast::Domain &domain);
|
||||||
|
ast::ProblemPointer parse();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void findSections(ast::Problem &problem);
|
||||||
|
|
||||||
|
void parseDomainSection(ast::Problem &problem);
|
||||||
|
void parseRequirementSection(ast::Problem &problem);
|
||||||
|
void computeDerivedRequirements(ast::Problem &problem);
|
||||||
|
void parseObjectSection(ast::Problem &problem);
|
||||||
|
void parseInitialStateSection(ast::Problem &problem);
|
||||||
|
void parseGoalSection(ast::Problem &problem);
|
||||||
|
|
||||||
|
Context &m_context;
|
||||||
|
ast::Domain &m_domain;
|
||||||
|
|
||||||
|
tokenize::Stream::Position m_domainPosition;
|
||||||
|
tokenize::Stream::Position m_requirementsPosition;
|
||||||
|
tokenize::Stream::Position m_objectsPosition;
|
||||||
|
tokenize::Stream::Position m_initialStatePosition;
|
||||||
|
tokenize::Stream::Position m_goalPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
lib/pddlparse/include/pddlparse/detail/parsing/Requirement.h
Normal file
26
lib/pddlparse/include/pddlparse/detail/parsing/Requirement.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__REQUIREMENT_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__REQUIREMENT_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Requirement
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::Requirement parseRequirement(Context &context);
|
||||||
|
const char *toString(const ast::Requirement &requirement);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
25
lib/pddlparse/include/pddlparse/detail/parsing/Variable.h
Normal file
25
lib/pddlparse/include/pddlparse/detail/parsing/Variable.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__VARIABLE_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__VARIABLE_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Variable
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::Variable parseVariable(Context &context, ast::Domain &domain);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef __PDDL_PARSE__DETAIL__PARSING__VARIABLE_DECLARATION_H
|
||||||
|
#define __PDDL_PARSE__DETAIL__PARSING__VARIABLE_DECLARATION_H
|
||||||
|
|
||||||
|
#include <pddlparse/ASTForward.h>
|
||||||
|
#include <pddlparse/Context.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// VariableDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::VariableDeclarations parseVariableDeclarations(Context &context, ast::Domain &domain);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -12,6 +12,7 @@ file(GLOB detail_parsing_headers "../include/pddlparse/detail/parsing/*.h")
|
|||||||
set(includes
|
set(includes
|
||||||
${PROJECT_SOURCE_DIR}/include
|
${PROJECT_SOURCE_DIR}/include
|
||||||
${PROJECT_SOURCE_DIR}/../../lib/tokenize/include
|
${PROJECT_SOURCE_DIR}/../../lib/tokenize/include
|
||||||
|
${PROJECT_SOURCE_DIR}/../../lib/variant/include
|
||||||
)
|
)
|
||||||
|
|
||||||
set(sources
|
set(sources
|
||||||
|
22
lib/pddlparse/src/pddlparse/Parse.cpp
Normal file
22
lib/pddlparse/src/pddlparse/Parse.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <pddlparse/Parse.h>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/detail/parsing/Description.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Parse
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::Description parseDescription(Context &context)
|
||||||
|
{
|
||||||
|
return detail::DescriptionParser(context).parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
92
lib/pddlparse/src/pddlparse/detail/Requirements.cpp
Normal file
92
lib/pddlparse/src/pddlparse/detail/Requirements.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include <pddlparse/detail/Requirements.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <pddlparse/detail/parsing/Requirement.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Requirements
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool hasRequirement(const ast::Domain &domain, ast::Requirement requirement)
|
||||||
|
{
|
||||||
|
const auto match = std::find_if(domain.requirements.cbegin(), domain.requirements.cend(),
|
||||||
|
[&](const auto &declaredRequirement)
|
||||||
|
{
|
||||||
|
return declaredRequirement == requirement;
|
||||||
|
});
|
||||||
|
|
||||||
|
return match != domain.requirements.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool hasRequirement(const ast::Problem &problem, ast::Requirement requirement)
|
||||||
|
{
|
||||||
|
const auto match = std::find_if(problem.requirements.cbegin(), problem.requirements.cend(),
|
||||||
|
[&](const auto &declaredRequirement)
|
||||||
|
{
|
||||||
|
return declaredRequirement == requirement;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (match != problem.requirements.cend())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return hasRequirement(problem.domain, requirement);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool hasRequirement(const ASTContext &astContext, ast::Requirement requirement)
|
||||||
|
{
|
||||||
|
if (astContext.problem)
|
||||||
|
return hasRequirement(*astContext.problem.value(), requirement);
|
||||||
|
|
||||||
|
return hasRequirement(*astContext.domain, requirement);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void checkRequirement(ast::Domain &domain, ast::Requirement requirement, Context &context)
|
||||||
|
{
|
||||||
|
if (hasRequirement(domain, requirement))
|
||||||
|
return;
|
||||||
|
|
||||||
|
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared");
|
||||||
|
|
||||||
|
domain.requirements.push_back(requirement);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void checkRequirement(ast::Problem &problem, ast::Requirement requirement, Context &context)
|
||||||
|
{
|
||||||
|
if (hasRequirement(problem, requirement))
|
||||||
|
return;
|
||||||
|
|
||||||
|
context.warningCallback(context.tokenizer.location(), "requirement “" + std::string(toString(requirement)) + "” used but never declared");
|
||||||
|
|
||||||
|
problem.requirements.push_back(requirement);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void checkRequirement(ASTContext &astContext, ast::Requirement requirement, Context &context)
|
||||||
|
{
|
||||||
|
if (astContext.problem)
|
||||||
|
checkRequirement(*astContext.problem.value(), requirement, context);
|
||||||
|
else
|
||||||
|
checkRequirement(*astContext.domain, requirement, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
68
lib/pddlparse/src/pddlparse/detail/parsing/Action.cpp
Normal file
68
lib/pddlparse/src/pddlparse/detail/parsing/Action.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <pddlparse/detail/parsing/Action.h>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
// TODO: remove
|
||||||
|
#include <pddlparse/detail/parsing/Utils.h>
|
||||||
|
#include <pddlparse/detail/parsing/VariableDeclaration.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Action
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddAction(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("action");
|
||||||
|
|
||||||
|
auto action = std::make_unique<ast::Action>();
|
||||||
|
action->name = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(":parameters");
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
|
||||||
|
// Read parameters
|
||||||
|
action->parameters = parseVariableDeclarations(context, domain);
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
|
||||||
|
// TODO: reimplement
|
||||||
|
skipSection(tokenizer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Parse preconditions and effects
|
||||||
|
while (!tokenizer.testAndReturn(')'))
|
||||||
|
{
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
|
||||||
|
if (tokenizer.testIdentifierAndSkip("precondition"))
|
||||||
|
// TODO: reimplement
|
||||||
|
//action->precondition = parsePreconditionExpression(context, expressionContext);
|
||||||
|
skipSection(tokenizer);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("effect"))
|
||||||
|
// TODO: reimplement
|
||||||
|
//action->effect = parseEffectExpression(context, expressionContext);
|
||||||
|
skipSection(tokenizer);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Store new action
|
||||||
|
domain.actions.emplace_back(std::move(action));
|
||||||
|
|
||||||
|
//tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
69
lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp
Normal file
69
lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include <pddlparse/detail/parsing/Constant.h>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Constant
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::experimental::optional<ast::ConstantPointer> findConstant(const std::string &constantName, ast::ConstantDeclarations &constantDeclarations)
|
||||||
|
{
|
||||||
|
const auto matchingConstant = std::find_if(constantDeclarations.begin(), constantDeclarations.end(),
|
||||||
|
[&](const auto &constantDeclaration)
|
||||||
|
{
|
||||||
|
return constantDeclaration->name == constantName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingConstant == constantDeclarations.end())
|
||||||
|
return std::experimental::nullopt;
|
||||||
|
|
||||||
|
return std::make_unique<ast::Constant>(matchingConstant->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
const auto constantName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
auto constant = findConstant(constantName, domain.constants);
|
||||||
|
|
||||||
|
if (constant)
|
||||||
|
return std::move(constant.value());
|
||||||
|
|
||||||
|
throw ParserException(tokenizer.location(), "constant “" + constantName + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::ConstantPointer parseConstant(Context &context, ast::Problem &problem)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
const auto constantName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
auto constant = findConstant(constantName, problem.domain->constants);
|
||||||
|
|
||||||
|
if (constant)
|
||||||
|
return std::move(constant.value());
|
||||||
|
|
||||||
|
auto object = findConstant(constantName, problem.objects);
|
||||||
|
|
||||||
|
if (object)
|
||||||
|
return std::move(object.value());
|
||||||
|
|
||||||
|
throw ParserException(tokenizer.location(), "constant “" + constantName + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
#include <pddlparse/detail/parsing/ConstantDeclaration.h>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/ASTCopy.h>
|
||||||
|
#include <pddlparse/detail/parsing/PrimitiveType.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ConstantDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddUntypedConstantDeclaration(Context &context, ast::ConstantDeclarations &constantDeclarations)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
auto constantName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
assert(constantName != "-");
|
||||||
|
|
||||||
|
constantDeclarations.emplace_back(std::make_unique<ast::ConstantDeclaration>(std::move(constantName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddConstantDeclarations(Context &context, ast::Domain &domain, ast::ConstantDeclarations &constantDeclarations)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Index on the first element of the current inheritance list
|
||||||
|
size_t inheritanceIndex = 0;
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parseAndAddUntypedConstantDeclaration(context, constantDeclarations);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
if (!tokenizer.testAndSkip<char>('-'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If existing, parse and store parent type
|
||||||
|
auto parentType = parsePrimitiveType(context, domain);
|
||||||
|
|
||||||
|
for (size_t i = inheritanceIndex; i < constantDeclarations.size(); i++)
|
||||||
|
constantDeclarations[i]->type = ast::deepCopy(parentType);
|
||||||
|
|
||||||
|
// All types up to now are labeled with their parent types
|
||||||
|
inheritanceIndex = constantDeclarations.size() + 1;
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddConstantDeclarations(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
parseAndAddConstantDeclarations(context, domain, domain.constants);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddConstantDeclarations(Context &context, ast::Problem &problem)
|
||||||
|
{
|
||||||
|
parseAndAddConstantDeclarations(context, *problem.domain, problem.objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
107
lib/pddlparse/src/pddlparse/detail/parsing/Description.cpp
Normal file
107
lib/pddlparse/src/pddlparse/detail/parsing/Description.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include <pddlparse/detail/parsing/Description.h>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/parsing/Domain.h>
|
||||||
|
#include <pddlparse/detail/parsing/Problem.h>
|
||||||
|
#include <pddlparse/detail/parsing/Utils.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Description
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DescriptionParser::DescriptionParser(Context &context)
|
||||||
|
: m_context{context},
|
||||||
|
m_domainPosition{-1},
|
||||||
|
m_problemPosition{-1}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::Description DescriptionParser::parse()
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
tokenizer.removeComments(";", "\n", false);
|
||||||
|
|
||||||
|
findSections();
|
||||||
|
|
||||||
|
if (m_domainPosition == -1)
|
||||||
|
throw ParserException("no PDDL domain specified");
|
||||||
|
|
||||||
|
tokenizer.seek(m_domainPosition);
|
||||||
|
|
||||||
|
auto domain = DomainParser(m_context).parse();
|
||||||
|
|
||||||
|
// If no problem is given, return just the domain
|
||||||
|
if (m_problemPosition == -1)
|
||||||
|
return {std::move(domain), std::experimental::nullopt};
|
||||||
|
|
||||||
|
tokenizer.seek(m_problemPosition);
|
||||||
|
|
||||||
|
auto problem = ProblemParser(m_context, *domain).parse();
|
||||||
|
|
||||||
|
// TODO: check consistency
|
||||||
|
// * check typing requirement
|
||||||
|
// * check that typing is used consistently
|
||||||
|
// * check that constants, variables, and predicates aren't declared twice
|
||||||
|
// * check section order
|
||||||
|
// * check that preconditions and effects are well-formed
|
||||||
|
return {std::move(domain), std::move(problem)};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DescriptionParser::findSections()
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (!tokenizer.atEnd())
|
||||||
|
{
|
||||||
|
const auto position = tokenizer.position();
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>("define");
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
|
||||||
|
if (tokenizer.testAndSkip<std::string>("domain"))
|
||||||
|
{
|
||||||
|
if (m_domainPosition != -1)
|
||||||
|
throw ParserException(tokenizer.location(), "PDDL description may not contain two domains");
|
||||||
|
|
||||||
|
m_domainPosition = position;
|
||||||
|
skipSection(tokenizer);
|
||||||
|
skipSection(tokenizer);
|
||||||
|
}
|
||||||
|
else if (m_context.tokenizer.testAndSkip<std::string>("problem"))
|
||||||
|
{
|
||||||
|
if (m_problemPosition != -1)
|
||||||
|
throw ParserException("PDDL description may not contain two problems currently");
|
||||||
|
|
||||||
|
m_problemPosition = position;
|
||||||
|
skipSection(tokenizer);
|
||||||
|
skipSection(tokenizer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = tokenizer.get<std::string>();
|
||||||
|
throw ParserException(tokenizer.location(), "unknown PDDL section “" + sectionIdentifier + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
300
lib/pddlparse/src/pddlparse/detail/parsing/Domain.cpp
Normal file
300
lib/pddlparse/src/pddlparse/detail/parsing/Domain.cpp
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
#include <pddlparse/detail/parsing/Domain.h>
|
||||||
|
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/Requirements.h>
|
||||||
|
#include <pddlparse/detail/parsing/Action.h>
|
||||||
|
#include <pddlparse/detail/parsing/ConstantDeclaration.h>
|
||||||
|
#include <pddlparse/detail/parsing/PredicateDeclaration.h>
|
||||||
|
#include <pddlparse/detail/parsing/PrimitiveTypeDeclaration.h>
|
||||||
|
#include <pddlparse/detail/parsing/Requirement.h>
|
||||||
|
#include <pddlparse/detail/parsing/Utils.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Domain
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DomainParser::DomainParser(Context &context)
|
||||||
|
: m_context{context},
|
||||||
|
m_requirementsPosition{-1},
|
||||||
|
m_typesPosition{-1},
|
||||||
|
m_constantsPosition{-1},
|
||||||
|
m_predicatesPosition{-1}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::DomainPointer DomainParser::parse()
|
||||||
|
{
|
||||||
|
auto domain = std::make_unique<ast::Domain>();
|
||||||
|
|
||||||
|
findSections(*domain);
|
||||||
|
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
if (m_requirementsPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(m_requirementsPosition);
|
||||||
|
parseRequirementSection(*domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_typesPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(m_typesPosition);
|
||||||
|
parseTypeSection(*domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_constantsPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(m_constantsPosition);
|
||||||
|
parseConstantSection(*domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_predicatesPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(m_predicatesPosition);
|
||||||
|
parsePredicateSection(*domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_actionPositions.size(); i++)
|
||||||
|
if (m_actionPositions[i] != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(m_actionPositions[i]);
|
||||||
|
parseActionSection(*domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
computeDerivedRequirements(*domain);
|
||||||
|
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DomainParser::findSections(ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>("define");
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>("domain");
|
||||||
|
|
||||||
|
domain.name = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
|
||||||
|
const auto setSectionPosition =
|
||||||
|
[&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false)
|
||||||
|
{
|
||||||
|
if (unique && sectionPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(value);
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "only one “:" + sectionName + "” section allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionPosition = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Find sections
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
const auto position = tokenizer.position();
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
|
||||||
|
const auto sectionIdentifierPosition = tokenizer.position();
|
||||||
|
|
||||||
|
// Save the parser position of the individual sections for later parsing
|
||||||
|
if (tokenizer.testIdentifierAndSkip("requirements"))
|
||||||
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("types"))
|
||||||
|
setSectionPosition("types", m_typesPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("constants"))
|
||||||
|
setSectionPosition("constants", m_constantsPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("predicates"))
|
||||||
|
setSectionPosition("predicates", m_predicatesPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("action"))
|
||||||
|
{
|
||||||
|
m_actionPositions.emplace_back(-1);
|
||||||
|
setSectionPosition("action", m_actionPositions.back(), position);
|
||||||
|
}
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("functions")
|
||||||
|
|| tokenizer.testIdentifierAndSkip("constraints")
|
||||||
|
|| tokenizer.testIdentifierAndSkip("durative-action")
|
||||||
|
|| tokenizer.testIdentifierAndSkip("derived"))
|
||||||
|
{
|
||||||
|
tokenizer.seek(sectionIdentifierPosition);
|
||||||
|
|
||||||
|
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
m_context.warningCallback(tokenizer.location(), "section type “" + sectionIdentifier + "” currently unsupported");
|
||||||
|
|
||||||
|
tokenizer.seek(sectionIdentifierPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.seek(position);
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "unknown domain section “" + sectionIdentifier + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip section for now and parse it later
|
||||||
|
skipSection(tokenizer);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DomainParser::parseRequirementSection(ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("requirements");
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
|
||||||
|
domain.requirements.emplace_back(parseRequirement(m_context));
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do this check only once the problem is parsed
|
||||||
|
// If no requirements are specified, assume STRIPS
|
||||||
|
if (domain.requirements.empty())
|
||||||
|
domain.requirements.emplace_back(ast::Requirement::STRIPS);
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DomainParser::computeDerivedRequirements(ast::Domain &domain)
|
||||||
|
{
|
||||||
|
const auto addRequirementUnique =
|
||||||
|
[&](auto requirement)
|
||||||
|
{
|
||||||
|
if (hasRequirement(domain, requirement))
|
||||||
|
return;
|
||||||
|
|
||||||
|
domain.requirements.push_back(requirement);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (hasRequirement(domain, ast::Requirement::ADL))
|
||||||
|
{
|
||||||
|
addRequirementUnique(ast::Requirement::STRIPS);
|
||||||
|
addRequirementUnique(ast::Requirement::Typing);
|
||||||
|
addRequirementUnique(ast::Requirement::NegativePreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::DisjunctivePreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::Equality);
|
||||||
|
addRequirementUnique(ast::Requirement::QuantifiedPreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::ConditionalEffects);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(domain, ast::Requirement::QuantifiedPreconditions))
|
||||||
|
{
|
||||||
|
addRequirementUnique(ast::Requirement::ExistentialPreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::UniversalPreconditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(domain, ast::Requirement::Fluents))
|
||||||
|
{
|
||||||
|
addRequirementUnique(ast::Requirement::NumericFluents);
|
||||||
|
addRequirementUnique(ast::Requirement::ObjectFluents);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(domain, ast::Requirement::TimedInitialLiterals))
|
||||||
|
addRequirementUnique(ast::Requirement::DurativeActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DomainParser::parseTypeSection(ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("types");
|
||||||
|
|
||||||
|
checkRequirement(domain, ast::Requirement::Typing, m_context);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Store types and their parent types
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
if (tokenizer.currentCharacter() == '(')
|
||||||
|
throw ParserException(tokenizer.location(), "only primitive types are allowed in type section");
|
||||||
|
|
||||||
|
parseAndAddPrimitiveTypeDeclarations(m_context, domain);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DomainParser::parseConstantSection(ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("constants");
|
||||||
|
|
||||||
|
// Store constants
|
||||||
|
parseAndAddConstantDeclarations(m_context, domain);
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DomainParser::parsePredicateSection(ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("predicates");
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Store predicates
|
||||||
|
parseAndAddPredicateDeclarations(m_context, domain);
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void DomainParser::parseActionSection(ast::Domain &domain)
|
||||||
|
{
|
||||||
|
parseAndAddAction(m_context, domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
79
lib/pddlparse/src/pddlparse/detail/parsing/InitialState.cpp
Normal file
79
lib/pddlparse/src/pddlparse/detail/parsing/InitialState.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include <pddlparse/detail/parsing/InitialState.h>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
// TODO: remove
|
||||||
|
#include <pddlparse/detail/parsing/Utils.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// InitialState
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::InitialState parseInitialState(Context &context, ASTContext &)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
|
||||||
|
ast::InitialState initialState;
|
||||||
|
|
||||||
|
// TODO: reimplement
|
||||||
|
/*const auto parseInitialStateElement =
|
||||||
|
[&]() -> ExpressionPointer
|
||||||
|
{
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
// TODO: do not allow negative initial state literals
|
||||||
|
if ((expression = parseLiteral(context, expressionContext))
|
||||||
|
|| (expression = expressions::At::parse(context, expressionContext, parseLiteral)))
|
||||||
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto position = tokenizer.position();
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = tokenizer.position();
|
||||||
|
|
||||||
|
if (tokenizer.testIdentifierAndSkip("="))
|
||||||
|
{
|
||||||
|
tokenizer.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.seek(position);
|
||||||
|
return expressions::Unsupported::parse(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenizer.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.seek(position);
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
ast::Expression expression;
|
||||||
|
|
||||||
|
if ((expression = parseInitialStateElement()))
|
||||||
|
initialState->m_facts.emplace_back(std::move(expression));
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
skipSection(tokenizer);
|
||||||
|
|
||||||
|
return initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
#include <pddlparse/detail/parsing/PredicateDeclaration.h>
|
||||||
|
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/ASTContext.h>
|
||||||
|
#include <pddlparse/detail/parsing/VariableDeclaration.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PredicateDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddPredicateDeclaration(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
|
||||||
|
auto name = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Parse parameters
|
||||||
|
auto parameters = parseVariableDeclarations(context, domain);
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
|
||||||
|
domain.predicates.emplace_back(std::make_unique<ast::PredicateDeclaration>(std::move(name), std::move(parameters)));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddPredicateDeclarations(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parseAndAddPredicateDeclaration(context, domain);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
55
lib/pddlparse/src/pddlparse/detail/parsing/PrimitiveType.cpp
Normal file
55
lib/pddlparse/src/pddlparse/detail/parsing/PrimitiveType.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include <pddlparse/detail/parsing/PrimitiveType.h>
|
||||||
|
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/Requirements.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PrimitiveType
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::PrimitiveTypePointer parsePrimitiveType(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
auto &types = domain.types;
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
auto typeName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
if (typeName.empty())
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "no type supplied");
|
||||||
|
|
||||||
|
auto matchingType = std::find_if(types.begin(), types.end(),
|
||||||
|
[&](auto &primitiveTypeDeclaration)
|
||||||
|
{
|
||||||
|
return primitiveTypeDeclaration->name == typeName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingType == types.end())
|
||||||
|
{
|
||||||
|
// Only “object” is allowed as an implicit type
|
||||||
|
if (typeName == "object" || typeName == "objects")
|
||||||
|
{
|
||||||
|
context.warningCallback(tokenizer.location(), "primitive type “" + typeName + "” should be declared");
|
||||||
|
types.emplace_back(std::make_unique<ast::PrimitiveTypeDeclaration>(std::move(typeName)));
|
||||||
|
|
||||||
|
return std::make_unique<ast::PrimitiveType>(types.back().get());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "type “" + typeName + "” used but never declared");
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<ast::PrimitiveType>(matchingType->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
#include <pddlparse/detail/parsing/PrimitiveTypeDeclaration.h>
|
||||||
|
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/ASTCopy.h>
|
||||||
|
#include <pddlparse/detail/parsing/PrimitiveType.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PrimitiveTypeDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::PrimitiveTypeDeclarationPointer &parseAndAddUntypedPrimitiveTypeDeclaration(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
auto typeName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
auto &types = domain.types;
|
||||||
|
|
||||||
|
const auto matchingPrimitiveType = std::find_if(types.begin(), types.end(),
|
||||||
|
[&](const auto &primitiveType)
|
||||||
|
{
|
||||||
|
return primitiveType->name == typeName;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return existing primitive type
|
||||||
|
if (matchingPrimitiveType != types.cend())
|
||||||
|
return *matchingPrimitiveType;
|
||||||
|
|
||||||
|
types.emplace_back(std::make_unique<ast::PrimitiveTypeDeclaration>(std::move(typeName)));
|
||||||
|
|
||||||
|
return types.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddPrimitiveTypeDeclarations(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Index on the first element of the current inheritance list
|
||||||
|
size_t inheritanceIndex = 0;
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parseAndAddUntypedPrimitiveTypeDeclaration(context, domain);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
if (!tokenizer.testAndSkip<char>('-'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If existing, parse and store parent type
|
||||||
|
auto parentType = parsePrimitiveType(context, domain);
|
||||||
|
|
||||||
|
auto &types = domain.types;
|
||||||
|
|
||||||
|
for (size_t i = inheritanceIndex; i < types.size(); i++)
|
||||||
|
types[i]->parentTypes.emplace_back(ast::deepCopy(parentType));
|
||||||
|
|
||||||
|
// All types up to now are labeled with their parent types
|
||||||
|
inheritanceIndex = types.size() + 1;
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
297
lib/pddlparse/src/pddlparse/detail/parsing/Problem.cpp
Normal file
297
lib/pddlparse/src/pddlparse/detail/parsing/Problem.cpp
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
#include <pddlparse/detail/parsing/Problem.h>
|
||||||
|
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/Requirements.h>
|
||||||
|
#include <pddlparse/detail/parsing/ConstantDeclaration.h>
|
||||||
|
#include <pddlparse/detail/parsing/InitialState.h>
|
||||||
|
#include <pddlparse/detail/parsing/Requirement.h>
|
||||||
|
#include <pddlparse/detail/parsing/Utils.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Problem
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ProblemParser::ProblemParser(Context &context, ast::Domain &domain)
|
||||||
|
: m_context{context},
|
||||||
|
m_domain{domain},
|
||||||
|
m_domainPosition{-1},
|
||||||
|
m_requirementsPosition{-1},
|
||||||
|
m_objectsPosition{-1},
|
||||||
|
m_initialStatePosition{-1},
|
||||||
|
m_goalPosition{-1}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::ProblemPointer ProblemParser::parse()
|
||||||
|
{
|
||||||
|
auto problem = std::make_unique<ast::Problem>(&m_domain);
|
||||||
|
|
||||||
|
findSections(*problem);
|
||||||
|
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
if (m_domainPosition == -1)
|
||||||
|
throw ParserException(tokenizer.location(), "problem description does not specify a corresponding domain");
|
||||||
|
|
||||||
|
tokenizer.seek(m_domainPosition);
|
||||||
|
parseDomainSection(*problem);
|
||||||
|
|
||||||
|
if (m_requirementsPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(m_requirementsPosition);
|
||||||
|
parseRequirementSection(*problem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_objectsPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(m_objectsPosition);
|
||||||
|
parseObjectSection(*problem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_initialStatePosition == -1)
|
||||||
|
throw ParserException(tokenizer.location(), "problem description does not specify an initial state");
|
||||||
|
|
||||||
|
tokenizer.seek(m_initialStatePosition);
|
||||||
|
parseInitialStateSection(*problem);
|
||||||
|
|
||||||
|
if (m_goalPosition == -1)
|
||||||
|
throw ParserException(tokenizer.location(), "problem description does not specify a goal");
|
||||||
|
|
||||||
|
tokenizer.seek(m_goalPosition);
|
||||||
|
parseGoalSection(*problem);
|
||||||
|
|
||||||
|
return problem;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ProblemParser::findSections(ast::Problem &problem)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>("define");
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>("problem");
|
||||||
|
|
||||||
|
problem.name = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
|
||||||
|
const auto setSectionPosition =
|
||||||
|
[&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false)
|
||||||
|
{
|
||||||
|
if (unique && sectionPosition != -1)
|
||||||
|
{
|
||||||
|
tokenizer.seek(value);
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "only one “:" + sectionName + "” section allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionPosition = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
const auto position = tokenizer.position();
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
|
||||||
|
const auto sectionIdentifierPosition = tokenizer.position();
|
||||||
|
|
||||||
|
if (tokenizer.testIdentifierAndSkip("domain"))
|
||||||
|
setSectionPosition("domain", m_domainPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("requirements"))
|
||||||
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("objects"))
|
||||||
|
setSectionPosition("objects", m_objectsPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("init"))
|
||||||
|
setSectionPosition("init", m_initialStatePosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("goal"))
|
||||||
|
setSectionPosition("goal", m_goalPosition, position, true);
|
||||||
|
else if (tokenizer.testIdentifierAndSkip("constraints")
|
||||||
|
|| tokenizer.testIdentifierAndSkip("metric")
|
||||||
|
|| tokenizer.testIdentifierAndSkip("length"))
|
||||||
|
{
|
||||||
|
tokenizer.seek(sectionIdentifierPosition);
|
||||||
|
|
||||||
|
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
m_context.warningCallback(tokenizer.location(), "section type “" + sectionIdentifier + "” currently unsupported");
|
||||||
|
|
||||||
|
tokenizer.seek(sectionIdentifierPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
tokenizer.seek(position);
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "unknown problem section “" + sectionIdentifier + "”");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip section for now and parse it later
|
||||||
|
skipSection(tokenizer);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ProblemParser::parseDomainSection(ast::Problem &problem)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("domain");
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto domainName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
if (problem.domain->name != domainName)
|
||||||
|
throw tokenize::TokenizerException(tokenizer.location(), "domains do not match (“" + problem.domain->name + "” and “" + domainName + "”)");
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ProblemParser::parseRequirementSection(ast::Problem &problem)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("requirements");
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
|
||||||
|
problem.requirements.emplace_back(parseRequirement(m_context));
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do this check only once the problem is parsed
|
||||||
|
// If no requirements are specified, assume STRIPS
|
||||||
|
if (problem.requirements.empty())
|
||||||
|
problem.requirements.emplace_back(ast::Requirement::STRIPS);
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// TODO: refactor, exists identically in DomainParser
|
||||||
|
void ProblemParser::computeDerivedRequirements(ast::Problem &problem)
|
||||||
|
{
|
||||||
|
const auto addRequirementUnique =
|
||||||
|
[&](const auto requirement)
|
||||||
|
{
|
||||||
|
if (hasRequirement(problem, requirement))
|
||||||
|
return;
|
||||||
|
|
||||||
|
problem.requirements.push_back(ast::Requirement(requirement));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (hasRequirement(problem, ast::Requirement::ADL))
|
||||||
|
{
|
||||||
|
addRequirementUnique(ast::Requirement::STRIPS);
|
||||||
|
addRequirementUnique(ast::Requirement::Typing);
|
||||||
|
addRequirementUnique(ast::Requirement::NegativePreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::DisjunctivePreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::Equality);
|
||||||
|
addRequirementUnique(ast::Requirement::QuantifiedPreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::ConditionalEffects);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(problem, ast::Requirement::QuantifiedPreconditions))
|
||||||
|
{
|
||||||
|
addRequirementUnique(ast::Requirement::ExistentialPreconditions);
|
||||||
|
addRequirementUnique(ast::Requirement::UniversalPreconditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(problem, ast::Requirement::Fluents))
|
||||||
|
{
|
||||||
|
addRequirementUnique(ast::Requirement::NumericFluents);
|
||||||
|
addRequirementUnique(ast::Requirement::ObjectFluents);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequirement(problem, ast::Requirement::TimedInitialLiterals))
|
||||||
|
addRequirementUnique(ast::Requirement::DurativeActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ProblemParser::parseObjectSection(ast::Problem &problem)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("objects");
|
||||||
|
|
||||||
|
// Store constants
|
||||||
|
parseAndAddConstantDeclarations(m_context, problem);
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ProblemParser::parseInitialStateSection(ast::Problem &problem)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("init");
|
||||||
|
|
||||||
|
ASTContext astContext(problem);
|
||||||
|
|
||||||
|
// TODO: reimplement
|
||||||
|
//problem.initialState = parseInitialState(m_context, astContext);
|
||||||
|
//tokenizer.expect<std::string>(")");
|
||||||
|
|
||||||
|
skipSection(tokenizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ProblemParser::parseGoalSection(ast::Problem &problem)
|
||||||
|
{
|
||||||
|
auto &tokenizer = m_context.tokenizer;
|
||||||
|
|
||||||
|
tokenizer.expect<std::string>("(");
|
||||||
|
tokenizer.expect<std::string>(":");
|
||||||
|
tokenizer.expect<std::string>("goal");
|
||||||
|
|
||||||
|
ASTContext expressionContext(problem);
|
||||||
|
|
||||||
|
// TODO: reimplement
|
||||||
|
//problem.goal = parsePreconditionExpression(m_context, expressionContext);
|
||||||
|
//tokenizer.expect<std::string>(")");
|
||||||
|
|
||||||
|
skipSection(tokenizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
102
lib/pddlparse/src/pddlparse/detail/parsing/Requirement.cpp
Normal file
102
lib/pddlparse/src/pddlparse/detail/parsing/Requirement.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include <pddlparse/detail/parsing/Requirement.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Requirement
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct CompareStrings
|
||||||
|
{
|
||||||
|
bool operator()(const char *lhs, const char *rhs) const
|
||||||
|
{
|
||||||
|
return std::strcmp(lhs, rhs) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
using RequirementNameMap = std::map<const char *, ast::Requirement, CompareStrings>;
|
||||||
|
static const RequirementNameMap requirementNameMap =
|
||||||
|
{
|
||||||
|
{"strips", ast::Requirement::STRIPS},
|
||||||
|
{"typing", ast::Requirement::Typing},
|
||||||
|
{"negative-preconditions", ast::Requirement::NegativePreconditions},
|
||||||
|
{"disjunctive-preconditions", ast::Requirement::DisjunctivePreconditions},
|
||||||
|
{"equality", ast::Requirement::Equality},
|
||||||
|
{"existential-preconditions", ast::Requirement::ExistentialPreconditions},
|
||||||
|
{"universal-preconditions", ast::Requirement::UniversalPreconditions},
|
||||||
|
{"quantified-preconditions", ast::Requirement::QuantifiedPreconditions},
|
||||||
|
{"conditional-effects", ast::Requirement::ConditionalEffects},
|
||||||
|
{"fluents", ast::Requirement::Fluents},
|
||||||
|
{"numeric-fluents", ast::Requirement::NumericFluents},
|
||||||
|
{"object-fluents", ast::Requirement::ObjectFluents},
|
||||||
|
{"adl", ast::Requirement::ADL},
|
||||||
|
{"durative-actions", ast::Requirement::DurativeActions},
|
||||||
|
{"duration-inequalities", ast::Requirement::DurationInequalities},
|
||||||
|
{"continuous-effects", ast::Requirement::ContinuousEffects},
|
||||||
|
{"derived-predicates", ast::Requirement::DerivedPredicates},
|
||||||
|
{"timed-initial-literals", ast::Requirement::TimedInitialLiterals},
|
||||||
|
{"preferences", ast::Requirement::Preferences},
|
||||||
|
{"constraints", ast::Requirement::Constraints},
|
||||||
|
{"action-costs", ast::Requirement::ActionCosts},
|
||||||
|
{"goal-utilities", ast::Requirement::GoalUtilities},
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::Requirement parseRequirement(Tokenizer &tokenizer)
|
||||||
|
{
|
||||||
|
const auto requirementName = tokenizer.getIdentifier();
|
||||||
|
const auto matchingRequirement = requirementNameMap.find(requirementName.c_str());
|
||||||
|
|
||||||
|
if (matchingRequirement == requirementNameMap.cend())
|
||||||
|
throw ParserException(tokenizer.location(), "unknown PDDL requirement “" + requirementName + "”");
|
||||||
|
|
||||||
|
return matchingRequirement->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::Requirement parseRequirement(Context &context)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
|
||||||
|
auto requirement = parseRequirement(tokenizer);
|
||||||
|
|
||||||
|
if (requirement == ast::Requirement::GoalUtilities)
|
||||||
|
context.warningCallback(tokenizer.location(), "requirement “goal-utilities” is not part of the PDDL 3.1 specification");
|
||||||
|
|
||||||
|
return requirement;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const char *toString(const ast::Requirement &requirement)
|
||||||
|
{
|
||||||
|
const auto matchingRequirement = std::find_if(requirementNameMap.cbegin(), requirementNameMap.cend(),
|
||||||
|
[&](const auto &requirementNamePair)
|
||||||
|
{
|
||||||
|
return requirementNamePair.second == requirement;
|
||||||
|
});
|
||||||
|
|
||||||
|
assert(matchingRequirement != requirementNameMap.cend());
|
||||||
|
|
||||||
|
return matchingRequirement->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
#include <pddlparse/detail/parsing/VariableDeclaration.h>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/ParserException.h>
|
||||||
|
#include <pddlparse/detail/ASTCopy.h>
|
||||||
|
#include <pddlparse/detail/parsing/PrimitiveType.h>
|
||||||
|
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// VariableDeclaration
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void parseAndAddUntypedVariableDeclaration(Context &context, ast::VariableDeclarations &variableDeclarations)
|
||||||
|
{
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
tokenizer.expect<std::string>("?");
|
||||||
|
auto variableName = tokenizer.getIdentifier();
|
||||||
|
|
||||||
|
assert(variableName != "-");
|
||||||
|
|
||||||
|
variableDeclarations.emplace_back(std::make_unique<ast::VariableDeclaration>(std::move(variableName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ast::VariableDeclarations parseVariableDeclarations(Context &context, ast::Domain &domain)
|
||||||
|
{
|
||||||
|
ast::VariableDeclarations variableDeclarations;
|
||||||
|
|
||||||
|
auto &tokenizer = context.tokenizer;
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
// Index on the first element of the current inheritance list
|
||||||
|
size_t inheritanceIndex = 0;
|
||||||
|
|
||||||
|
while (tokenizer.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
parseAndAddUntypedVariableDeclaration(context, variableDeclarations);
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
|
||||||
|
if (!tokenizer.testAndSkip<char>('-'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If existing, parse and store parent type
|
||||||
|
auto parentType = parsePrimitiveType(context, domain);
|
||||||
|
|
||||||
|
for (size_t i = inheritanceIndex; i < variableDeclarations.size(); i++)
|
||||||
|
variableDeclarations[i]->type = ast::deepCopy(parentType);
|
||||||
|
|
||||||
|
// All types up to now are labeled with their parent types
|
||||||
|
inheritanceIndex = variableDeclarations.size() + 1;
|
||||||
|
|
||||||
|
tokenizer.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return variableDeclarations;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ file(GLOB core_sources "*.cpp")
|
|||||||
set(includes
|
set(includes
|
||||||
${PROJECT_SOURCE_DIR}/include
|
${PROJECT_SOURCE_DIR}/include
|
||||||
${PROJECT_SOURCE_DIR}/../../lib/catch/single_include
|
${PROJECT_SOURCE_DIR}/../../lib/catch/single_include
|
||||||
|
${PROJECT_SOURCE_DIR}/../../lib/tokenize/include
|
||||||
|
${PROJECT_SOURCE_DIR}/../../lib/variant/include
|
||||||
)
|
)
|
||||||
|
|
||||||
set(libraries
|
set(libraries
|
||||||
@ -18,4 +20,4 @@ target_link_libraries(${target} ${libraries})
|
|||||||
add_custom_target(run-pddlparse-tests
|
add_custom_target(run-pddlparse-tests
|
||||||
COMMAND ${CMAKE_BINARY_DIR}/bin/pddlparse-tests
|
COMMAND ${CMAKE_BINARY_DIR}/bin/pddlparse-tests
|
||||||
DEPENDS ${target}
|
DEPENDS ${target}
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests)
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/../../tests)
|
||||||
|
90
lib/pddlparse/tests/TestParser.cpp
Normal file
90
lib/pddlparse/tests/TestParser.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*#include <catch.hpp>
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/Parse.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TEST_CASE("[parser] The Blocksworld domain is parsed correctly", "[parser]")
|
||||||
|
{
|
||||||
|
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||||
|
|
||||||
|
pddl::Tokenizer tokenizer;
|
||||||
|
tokenizer.read("data/blocksworld-domain.pddl");
|
||||||
|
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||||
|
|
||||||
|
const auto description = pddl::parseDescription(context);
|
||||||
|
|
||||||
|
REQUIRE_NOTHROW(description.domain());
|
||||||
|
|
||||||
|
const auto &domain = description.domain();
|
||||||
|
|
||||||
|
// Name
|
||||||
|
CHECK(domain.name() == "blocks");
|
||||||
|
|
||||||
|
// Requirements
|
||||||
|
REQUIRE(domain.requirements().size() == 2u);
|
||||||
|
CHECK(domain.requirements()[0].type() == Requirement::Type::STRIPS);
|
||||||
|
CHECK(domain.requirements()[1].type() == Requirement::Type::Typing);
|
||||||
|
|
||||||
|
// Types
|
||||||
|
REQUIRE(domain.types().size() == 1u);
|
||||||
|
|
||||||
|
const auto &block = *domain.types()[0];
|
||||||
|
|
||||||
|
CHECK(block.name() == "block");
|
||||||
|
REQUIRE(block.parentTypes().size() == 0u);
|
||||||
|
|
||||||
|
// Predicates
|
||||||
|
REQUIRE(domain.predicates().size() == 5u);
|
||||||
|
|
||||||
|
const auto &on = *domain.predicates()[0];
|
||||||
|
|
||||||
|
CHECK(on.name() == "on");
|
||||||
|
REQUIRE(on.parameters().size() == 2u);
|
||||||
|
CHECK(on.parameters()[0]->name() == "x");
|
||||||
|
const auto &onArgument0Type = on.parameters()[0]->type()->as<expressions::PrimitiveType>();
|
||||||
|
CHECK(&onArgument0Type == &block);
|
||||||
|
CHECK(on.parameters()[1]->name() == "y");
|
||||||
|
const auto &onArgument1Type = on.parameters()[1]->type()->as<expressions::PrimitiveType>();
|
||||||
|
CHECK(&onArgument1Type == &block);
|
||||||
|
|
||||||
|
const auto &handempty = *domain.predicates()[3];
|
||||||
|
|
||||||
|
CHECK(handempty.name() == "handempty");
|
||||||
|
CHECK(handempty.parameters().empty());
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
REQUIRE(domain.actions().size() == 4u);
|
||||||
|
|
||||||
|
const auto &pickUp = *domain.actions()[0];
|
||||||
|
|
||||||
|
CHECK(pickUp.name() == "pick-up");
|
||||||
|
REQUIRE(pickUp.parameters().size() == 1u);
|
||||||
|
CHECK(pickUp.parameters()[0]->name() == "x");
|
||||||
|
CHECK(pickUp.parameters()[0]->type() == &block);
|
||||||
|
|
||||||
|
const auto &pickUpPre = pickUp.precondition()->as<expressions::And>();
|
||||||
|
REQUIRE(pickUpPre.arguments().size() == 3u);
|
||||||
|
const auto &pickUpPre0 = pickUpPre.arguments()[0]->as<expressions::Predicate>();
|
||||||
|
CHECK(pickUpPre0.name() == "clear");
|
||||||
|
REQUIRE(pickUpPre0.arguments().size() == 1u);
|
||||||
|
const auto &pickUpPre00 = pickUpPre0.arguments()[0]->as<expressions::Variable>();
|
||||||
|
CHECK(pickUpPre00.name() == "x");
|
||||||
|
CHECK(pickUpPre00.type() == &block);
|
||||||
|
CHECK(&pickUpPre00 == pickUp.parameters()[0].get());
|
||||||
|
const auto &pickUpPre2 = pickUpPre.arguments()[2]->as<expressions::Predicate>();
|
||||||
|
CHECK(pickUpPre2.name() == "handempty");
|
||||||
|
CHECK(pickUpPre2.arguments().empty());
|
||||||
|
|
||||||
|
const auto &pickUpEff = pickUp.effect()->as<expressions::And>();
|
||||||
|
REQUIRE(pickUpEff.arguments().size() == 4u);
|
||||||
|
const auto &pickUpEff0 = pickUpEff.arguments()[0]->as<expressions::Not>();
|
||||||
|
const auto &pickUpEff00 = pickUpEff0.argument()->as<expressions::Predicate>();
|
||||||
|
CHECK(pickUpEff00.name() == "ontable");
|
||||||
|
REQUIRE(pickUpEff00.arguments().size() == 1u);
|
||||||
|
const auto &pickUpEff000 = pickUpEff00.arguments()[0]->as<expressions::Variable>();
|
||||||
|
CHECK(pickUpEff000.name() == "x");
|
||||||
|
CHECK(pickUpEff000.type() == &block);
|
||||||
|
}
|
||||||
|
*/
|
@ -1,2 +1,22 @@
|
|||||||
#define CATCH_CONFIG_MAIN
|
/*#define CATCH_CONFIG_MAIN
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pddlparse/AST.h>
|
||||||
|
#include <pddlparse/Parse.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const pddl::Context::WarningCallback ignoreWarnings = [](const auto &, const auto &){};
|
||||||
|
|
||||||
|
pddl::Tokenizer tokenizer;
|
||||||
|
tokenizer.read("data/blocksworld-domain.pddl");
|
||||||
|
tokenizer.read("data/blocksworld-problem.pddl");
|
||||||
|
pddl::Context context(std::move(tokenizer), ignoreWarnings);
|
||||||
|
|
||||||
|
const auto description = pddl::parseDescription(context);
|
||||||
|
|
||||||
|
std::cout << description.domain->requirements.size() << std::endl;
|
||||||
|
}
|
||||||
|
1
lib/variant
Submodule
1
lib/variant
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit d2588a8f1d6b5d480d228e6d8a906ce634bdea9a
|
Reference in New Issue
Block a user