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"]
|
||||
path = lib/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
|
||||
{
|
||||
explicit Constant(ConstantDeclaration &declaration)
|
||||
explicit Constant(ConstantDeclaration *declaration)
|
||||
: declaration{declaration}
|
||||
{
|
||||
}
|
||||
@ -36,7 +36,7 @@ struct Constant
|
||||
Constant(Constant &&other) = default;
|
||||
Constant &operator=(Constant &&other) = default;
|
||||
|
||||
ConstantDeclaration &declaration;
|
||||
ConstantDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -51,8 +51,8 @@ struct ConstantDeclaration
|
||||
|
||||
ConstantDeclaration(const ConstantDeclaration &other) = delete;
|
||||
ConstantDeclaration &operator=(const ConstantDeclaration &&other) = delete;
|
||||
ConstantDeclaration(ConstantDeclaration &&other) = default;
|
||||
ConstantDeclaration &operator=(ConstantDeclaration &&other) = default;
|
||||
ConstantDeclaration(ConstantDeclaration &&other) = delete;
|
||||
ConstantDeclaration &operator=(ConstantDeclaration &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
std::experimental::optional<Type> type;
|
||||
@ -79,7 +79,7 @@ struct Dummy
|
||||
|
||||
struct PrimitiveType
|
||||
{
|
||||
explicit PrimitiveType(PrimitiveTypeDeclaration &declaration)
|
||||
explicit PrimitiveType(PrimitiveTypeDeclaration *declaration)
|
||||
: declaration{declaration}
|
||||
{
|
||||
}
|
||||
@ -89,7 +89,7 @@ struct PrimitiveType
|
||||
PrimitiveType(PrimitiveType &&other) = default;
|
||||
PrimitiveType &operator=(PrimitiveType &&other) = default;
|
||||
|
||||
PrimitiveTypeDeclaration &declaration;
|
||||
PrimitiveTypeDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -103,11 +103,11 @@ struct PrimitiveTypeDeclaration
|
||||
|
||||
PrimitiveTypeDeclaration(const PrimitiveTypeDeclaration &other) = delete;
|
||||
PrimitiveTypeDeclaration &operator=(const PrimitiveTypeDeclaration &&other) = delete;
|
||||
PrimitiveTypeDeclaration(PrimitiveTypeDeclaration &&other) = default;
|
||||
PrimitiveTypeDeclaration &operator=(PrimitiveTypeDeclaration &&other) = default;
|
||||
PrimitiveTypeDeclaration(PrimitiveTypeDeclaration &&other) = delete;
|
||||
PrimitiveTypeDeclaration &operator=(PrimitiveTypeDeclaration &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
std::vector<PrimitiveType> parentTypes;
|
||||
std::vector<PrimitiveTypePointer> parentTypes;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -127,7 +127,7 @@ struct Unsupported
|
||||
|
||||
struct Variable
|
||||
{
|
||||
explicit Variable(VariableDeclaration &declaration)
|
||||
explicit Variable(VariableDeclaration *declaration)
|
||||
: declaration{declaration}
|
||||
{
|
||||
}
|
||||
@ -137,7 +137,7 @@ struct Variable
|
||||
Variable(Variable &&other) = default;
|
||||
Variable &operator=(Variable &&other) = default;
|
||||
|
||||
VariableDeclaration &declaration;
|
||||
VariableDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -152,8 +152,8 @@ struct VariableDeclaration
|
||||
|
||||
VariableDeclaration(const VariableDeclaration &other) = delete;
|
||||
VariableDeclaration &operator=(const VariableDeclaration &&other) = delete;
|
||||
VariableDeclaration(VariableDeclaration &&other) = default;
|
||||
VariableDeclaration &operator=(VariableDeclaration &&other) = default;
|
||||
VariableDeclaration(VariableDeclaration &&other) = delete;
|
||||
VariableDeclaration &operator=(VariableDeclaration &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
std::experimental::optional<Type> type;
|
||||
@ -165,7 +165,7 @@ struct VariableDeclaration
|
||||
|
||||
struct Predicate
|
||||
{
|
||||
explicit Predicate(PredicateDeclaration &declaration)
|
||||
explicit Predicate(PredicateDeclaration *declaration)
|
||||
: declaration{declaration}
|
||||
{
|
||||
}
|
||||
@ -176,8 +176,7 @@ struct Predicate
|
||||
Predicate &operator=(Predicate &&other) = default;
|
||||
|
||||
Terms arguments;
|
||||
|
||||
PredicateDeclaration &declaration;
|
||||
PredicateDeclaration *declaration;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -416,9 +415,9 @@ struct Action
|
||||
|
||||
std::string name;
|
||||
|
||||
ast::VariableDeclarations parameters;
|
||||
std::experimental::optional<ast::Precondition> precondition;
|
||||
std::experimental::optional<ast::Effect> effect;
|
||||
VariableDeclarations parameters;
|
||||
std::experimental::optional<Precondition> precondition;
|
||||
std::experimental::optional<Effect> effect;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -429,15 +428,15 @@ struct Domain
|
||||
|
||||
Domain(const Domain &other) = delete;
|
||||
Domain &operator=(const Domain &&other) = delete;
|
||||
Domain(Domain &&other) = default;
|
||||
Domain &operator=(Domain &&other) = default;
|
||||
Domain(Domain &&other) = delete;
|
||||
Domain &operator=(Domain &&other) = delete;
|
||||
|
||||
std::string name;
|
||||
Requirements requirements;
|
||||
ast::PrimitiveTypeDeclarations types;
|
||||
ast::ConstantDeclarations constants;
|
||||
ast::PredicateDeclarations predicates;
|
||||
std::vector<Action> actions;
|
||||
PrimitiveTypeDeclarations types;
|
||||
ConstantDeclarations constants;
|
||||
PredicateDeclarations predicates;
|
||||
Actions actions;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -451,7 +450,7 @@ struct InitialState
|
||||
InitialState(InitialState &&other) = default;
|
||||
InitialState &operator=(InitialState &&other) = default;
|
||||
|
||||
ast::Facts facts;
|
||||
Facts facts;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -460,17 +459,22 @@ struct Problem
|
||||
{
|
||||
Problem() = default;
|
||||
|
||||
Problem(Domain *domain)
|
||||
: domain{domain}
|
||||
{
|
||||
}
|
||||
|
||||
Problem(const Problem &other) = delete;
|
||||
Problem &operator=(const Problem &&other) = delete;
|
||||
Problem(Problem &&other) = default;
|
||||
Problem &operator=(Problem &&other) = default;
|
||||
|
||||
Domain &domain;
|
||||
Domain *domain;
|
||||
std::string name;
|
||||
Requirements requirements;
|
||||
ast::ConstantDeclarations objects;
|
||||
ConstantDeclarations objects;
|
||||
InitialState initialState;
|
||||
std::experimental::optional<ast::Goal> goal;
|
||||
std::experimental::optional<Goal> goal;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -512,8 +516,8 @@ struct Description
|
||||
Description(Description &&other) = default;
|
||||
Description &operator=(Description &&other) = default;
|
||||
|
||||
Domain domain;
|
||||
std::experimental::optional<Problem> problem;
|
||||
DomainPointer domain;
|
||||
std::experimental::optional<ProblemPointer> problem;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -26,27 +26,37 @@ namespace ast
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Constant;
|
||||
using ConstantPointer = std::unique_ptr<Constant>;
|
||||
struct ConstantDeclaration;
|
||||
using ConstantDeclarations = std::vector<ConstantDeclaration>;
|
||||
using ConstantDeclarationPointer = std::unique_ptr<ConstantDeclaration>;
|
||||
using ConstantDeclarations = std::vector<ConstantDeclarationPointer>;
|
||||
struct Dummy;
|
||||
using DummyPointer = std::unique_ptr<Dummy>;
|
||||
struct PrimitiveType;
|
||||
using PrimitiveTypes = std::vector<PrimitiveType>;
|
||||
using PrimitiveTypePointer = std::unique_ptr<PrimitiveType>;
|
||||
using PrimitiveTypes = std::vector<PrimitiveTypePointer>;
|
||||
struct PrimitiveTypeDeclaration;
|
||||
using PrimitiveTypeDeclarations = std::vector<PrimitiveTypeDeclaration>;
|
||||
using PrimitiveTypeDeclarationPointer = std::unique_ptr<PrimitiveTypeDeclaration>;
|
||||
using PrimitiveTypeDeclarations = std::vector<PrimitiveTypeDeclarationPointer>;
|
||||
struct Unsupported;
|
||||
using UnsupportedPointer = std::unique_ptr<Unsupported>;
|
||||
struct Variable;
|
||||
using Variables = std::vector<Variable>;
|
||||
using VariablePointer = std::unique_ptr<Variable>;
|
||||
using Variables = std::vector<VariablePointer>;
|
||||
struct VariableDeclaration;
|
||||
using VariableDeclarations = std::vector<VariableDeclaration>;
|
||||
using VariableDeclarationPointer = std::unique_ptr<VariableDeclaration>;
|
||||
using VariableDeclarations = std::vector<VariableDeclarationPointer>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compounds
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Predicate;
|
||||
using Predicates = std::vector<Predicate>;
|
||||
using PredicatePointer = std::unique_ptr<Predicate>;
|
||||
using Predicates = std::vector<PredicatePointer>;
|
||||
struct PredicateDeclaration;
|
||||
using PredicateDeclarations = std::vector<PredicateDeclaration>;
|
||||
using PredicateDeclarationPointer = std::unique_ptr<PredicateDeclaration>;
|
||||
using PredicateDeclarations = std::vector<PredicateDeclarationPointer>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Expressions
|
||||
@ -55,29 +65,53 @@ using PredicateDeclarations = std::vector<PredicateDeclaration>;
|
||||
template<class Argument>
|
||||
struct And;
|
||||
template<class Argument>
|
||||
using AndPointer = std::unique_ptr<And<Argument>>;
|
||||
template<class Argument>
|
||||
struct At;
|
||||
template<class Argument>
|
||||
using AtPointer = std::unique_ptr<At<Argument>>;
|
||||
template<class Argument>
|
||||
struct Either;
|
||||
template<class Argument>
|
||||
using EitherPointer = std::unique_ptr<Either<Argument>>;
|
||||
template<class Argument>
|
||||
struct Exists;
|
||||
template<class Argument>
|
||||
using ExistsPointer = std::unique_ptr<Exists<Argument>>;
|
||||
template<class Argument>
|
||||
struct ForAll;
|
||||
template<class Argument>
|
||||
using ForAllPointer = std::unique_ptr<ForAll<Argument>>;
|
||||
template<class Argument>
|
||||
struct Imply;
|
||||
template<class Argument>
|
||||
using ImplyPointer = std::unique_ptr<Imply<Argument>>;
|
||||
template<class Argument>
|
||||
struct Not;
|
||||
template<class Argument>
|
||||
using NotPointer = std::unique_ptr<Not<Argument>>;
|
||||
template<class Argument>
|
||||
struct Or;
|
||||
template<class Argument>
|
||||
using OrPointer = std::unique_ptr<Or<Argument>>;
|
||||
template<class ArgumentLeft, class ArgumentRight>
|
||||
struct When;
|
||||
template<class ArgumentLeft, class ArgumentRight>
|
||||
using WhenPointer = std::unique_ptr<When<ArgumentLeft, ArgumentRight>>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PDDL Structure
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Action;
|
||||
using ActionPointer = std::unique_ptr<Action>;
|
||||
using Actions = std::vector<ActionPointer>;
|
||||
struct Description;
|
||||
using DescriptionPointer = std::unique_ptr<Description>;
|
||||
struct Domain;
|
||||
using DomainPointer = std::unique_ptr<Domain>;
|
||||
struct Problem;
|
||||
using ProblemPointer = std::unique_ptr<Problem>;
|
||||
enum class Requirement;
|
||||
using Requirements = std::vector<Requirement>;
|
||||
|
||||
@ -88,8 +122,8 @@ using Requirements = std::vector<Requirement>;
|
||||
namespace detail
|
||||
{
|
||||
using TermT = Variant<
|
||||
Constant,
|
||||
Variable>;
|
||||
ConstantPointer,
|
||||
VariablePointer>;
|
||||
}
|
||||
|
||||
class Term : public detail::TermT
|
||||
@ -104,8 +138,8 @@ using Terms = std::vector<Term>;
|
||||
namespace detail
|
||||
{
|
||||
using AtomicFormulaT = Variant<
|
||||
Predicate,
|
||||
Unsupported>;
|
||||
PredicatePointer,
|
||||
UnsupportedPointer>;
|
||||
}
|
||||
|
||||
class AtomicFormula : public detail::AtomicFormulaT
|
||||
@ -121,13 +155,13 @@ namespace detail
|
||||
{
|
||||
using PreconditionT = Variant<
|
||||
AtomicFormula,
|
||||
And<Precondition>,
|
||||
Exists<Precondition>,
|
||||
ForAll<Precondition>,
|
||||
Imply<Precondition>,
|
||||
Not<Precondition>,
|
||||
Or<Precondition>,
|
||||
Unsupported>;
|
||||
AndPointer<Precondition>,
|
||||
ExistsPointer<Precondition>,
|
||||
ForAllPointer<Precondition>,
|
||||
ImplyPointer<Precondition>,
|
||||
NotPointer<Precondition>,
|
||||
OrPointer<Precondition>,
|
||||
UnsupportedPointer>;
|
||||
}
|
||||
|
||||
class Precondition : public detail::PreconditionT
|
||||
@ -145,11 +179,11 @@ namespace detail
|
||||
{
|
||||
using EffectT = Variant<
|
||||
AtomicFormula,
|
||||
And<Effect>,
|
||||
ForAll<Effect>,
|
||||
Not<Effect>,
|
||||
When<Precondition, Effect>,
|
||||
Unsupported>;
|
||||
AndPointer<Effect>,
|
||||
ForAllPointer<Effect>,
|
||||
NotPointer<Effect>,
|
||||
WhenPointer<Precondition, Effect>,
|
||||
UnsupportedPointer>;
|
||||
}
|
||||
|
||||
class Effect : public detail::EffectT
|
||||
@ -162,8 +196,8 @@ class Effect : public detail::EffectT
|
||||
namespace detail
|
||||
{
|
||||
using TypeT = Variant<
|
||||
Either<PrimitiveType>,
|
||||
PrimitiveType>;
|
||||
EitherPointer<PrimitiveTypePointer>,
|
||||
PrimitiveTypePointer>;
|
||||
}
|
||||
|
||||
class Type : public detail::TypeT
|
||||
@ -177,7 +211,7 @@ namespace detail
|
||||
{
|
||||
using LiteralT = Variant<
|
||||
AtomicFormula,
|
||||
Not<AtomicFormula>>;
|
||||
NotPointer<AtomicFormula>>;
|
||||
}
|
||||
|
||||
class Literal : public detail::LiteralT
|
||||
@ -193,7 +227,7 @@ namespace detail
|
||||
{
|
||||
using FactT = Variant<
|
||||
AtomicFormula,
|
||||
At<Literal>>;
|
||||
AtPointer<Literal>>;
|
||||
}
|
||||
|
||||
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
|
||||
#define __PDDL_PARSE__VARIANT_H
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
#include <mapbox/variant.hpp>
|
||||
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Variant (from clingo, written by Roland Kaminski)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail {
|
||||
|
||||
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_;
|
||||
};
|
||||
template<class... Types>
|
||||
using Variant = mapbox::util::variant<Types...>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/tokenize/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/variant/include
|
||||
)
|
||||
|
||||
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
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/catch/single_include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/tokenize/include
|
||||
${PROJECT_SOURCE_DIR}/../../lib/variant/include
|
||||
)
|
||||
|
||||
set(libraries
|
||||
@ -18,4 +20,4 @@ target_link_libraries(${target} ${libraries})
|
||||
add_custom_target(run-pddlparse-tests
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/pddlparse-tests
|
||||
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 <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