Started implementing clean, separate PDDL syntax tree and parser.

This commit is contained in:
Patrick Lühne 2017-05-09 21:12:30 +02:00
parent d2f9e55e68
commit d7db0d8ccd
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
11 changed files with 1212 additions and 0 deletions

View File

@ -25,6 +25,7 @@ if (CMAKE_GENERATOR STREQUAL "Ninja" AND
endif()
add_subdirectory(lib/parsebase)
add_subdirectory(lib/pddlparse)
add_subdirectory(src)
add_subdirectory(app)
if(PLASP_BUILD_TESTS)

View File

@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 2.6)
project(pddlparse)
option(PDDLPARSE_BUILD_TESTS "Build unit tests" OFF)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
if (CMAKE_GENERATOR STREQUAL "Ninja" AND
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)))
# Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support.
# Rationale in https://github.com/ninja-build/ninja/issues/814
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
endif()
add_subdirectory(src)
if(PDDLPARSE_BUILD_TESTS)
add_subdirectory(tests)
endif(PDDLPARSE_BUILD_TESTS)

View File

@ -0,0 +1,538 @@
#ifndef __PDDL_PARSE__AST_H
#define __PDDL_PARSE__AST_H
#include <limits>
#include <experimental/optional>
#include <set>
#include <type_traits>
#include <vector>
#include <parsebase/Stream.h>
#include <pddlparse/ASTForward.h>
namespace pddl
{
namespace ast
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// AST
//
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// Primitives
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Constant
{
explicit Constant(ConstantDeclaration *declaration)
: declaration{declaration}
{
}
Constant(const Constant &other) = delete;
Constant &operator=(const Constant &&other) = delete;
Constant(Constant &&other) = default;
Constant &operator=(Constant &&other) = default;
ConstantDeclaration *declaration{nullptr};
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct ConstantDeclaration
{
explicit ConstantDeclaration(std::string &&name, std::experimental::optional<Type> &&type = std::experimental::nullopt, bool isDirty = true)
: name{std::move(name)},
type{std::move(type)},
isDirty{isDirty}
{
}
ConstantDeclaration(const ConstantDeclaration &other) = delete;
ConstantDeclaration &operator=(const ConstantDeclaration &&other) = delete;
ConstantDeclaration(ConstantDeclaration &&other) = default;
ConstantDeclaration &operator=(ConstantDeclaration &&other) = default;
std::string name;
std::experimental::optional<Type> type;
bool isDirty{true};
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Dummy
{
explicit Dummy(std::string name)
: name{name}
{
}
Dummy(const Dummy &other) = delete;
Dummy &operator=(const Dummy &&other) = delete;
Dummy(Dummy &&other) = default;
Dummy &operator=(Dummy &&other) = default;
std::string name;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct PrimitiveType
{
explicit PrimitiveType(PrimitiveTypeDeclaration &declaration)
: declaration{declaration}
{
}
PrimitiveType(const PrimitiveType &other) = delete;
PrimitiveType &operator=(const PrimitiveType &&other) = delete;
PrimitiveType(PrimitiveType &&other) = default;
PrimitiveType &operator=(PrimitiveType &&other) = default;
PrimitiveTypeDeclaration &declaration;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct PrimitiveTypeDeclaration
{
explicit PrimitiveTypeDeclaration(std::string &&name)
: name{std::move(name)}
{
}
PrimitiveTypeDeclaration(const PrimitiveTypeDeclaration &other) = delete;
PrimitiveTypeDeclaration &operator=(const PrimitiveTypeDeclaration &&other) = delete;
PrimitiveTypeDeclaration(PrimitiveTypeDeclaration &&other) = default;
PrimitiveTypeDeclaration &operator=(PrimitiveTypeDeclaration &&other) = default;
std::string name;
std::vector<PrimitiveType> parentTypes;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Unsupported
{
explicit Unsupported() = default;
Unsupported(const Unsupported &other) = delete;
Unsupported &operator=(const Unsupported &&other) = delete;
Unsupported(Unsupported &&other) = default;
Unsupported &operator=(Unsupported &&other) = default;
std::string type;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Variable
{
explicit Variable(VariableDeclaration &declaration)
: declaration{declaration}
{
}
Variable(const Variable &other) = delete;
Variable &operator=(const Variable &&other) = delete;
Variable(Variable &&other) = default;
Variable &operator=(Variable &&other) = default;
VariableDeclaration &declaration;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct VariableDeclaration
{
explicit VariableDeclaration(std::string &&name, std::experimental::optional<Type> type = std::experimental::nullopt, bool isDirty = true)
: name{std::move(name)},
type{std::move(type)},
isDirty{isDirty}
{
}
VariableDeclaration(const VariableDeclaration &other) = delete;
VariableDeclaration &operator=(const VariableDeclaration &&other) = delete;
VariableDeclaration(VariableDeclaration &&other) = default;
VariableDeclaration &operator=(VariableDeclaration &&other) = default;
std::string name;
std::experimental::optional<Type> type;
bool isDirty{true};
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Compounds
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Predicate
{
explicit Predicate(PredicateDeclaration &declaration)
: declaration{declaration}
{
}
Predicate(const Predicate &other) = delete;
Predicate &operator=(const Predicate &&other) = delete;
Predicate(Predicate &&other) = default;
Predicate &operator=(Predicate &&other) = default;
std::string name;
Terms arguments;
PredicateDeclaration &declaration;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct PredicateDeclaration
{
explicit PredicateDeclaration(std::string &&name, VariableDeclarations &&parameters)
: name{std::move(name)},
parameters{std::move(parameters)}
{
}
PredicateDeclaration(const PredicateDeclaration &other) = delete;
PredicateDeclaration &operator=(const PredicateDeclaration &&other) = delete;
PredicateDeclaration(PredicateDeclaration &&other) = default;
PredicateDeclaration &operator=(PredicateDeclaration &&other) = default;
std::string name;
VariableDeclarations parameters;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Expressions: Base Classes
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived, class ArgumentLeft, class ArgumentRight = ArgumentLeft>
struct Binary
{
explicit Binary(ArgumentLeft &&argumentLeft, ArgumentRight &&argumentRight)
: argumentLeft{std::move(argumentLeft)},
argumentRight{std::move(argumentRight)}
{
}
Binary(const Binary &other) = delete;
Binary &operator=(const Binary &&other) = delete;
Binary(Binary &&other) = default;
Binary &operator=(Binary &&other) = default;
ArgumentLeft argumentLeft;
ArgumentRight argumentRight;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived, class Argument>
struct NAry
{
using Arguments = std::vector<Argument>;
explicit NAry(Arguments &&arguments) noexcept
: arguments{std::move(arguments)}
{
}
NAry(const NAry &other) = delete;
NAry &operator=(const NAry &&other) = delete;
NAry(NAry &&other) = default;
NAry &operator=(NAry &&other) = default;
Arguments arguments;
protected:
static Arguments copyArguments(const NAry<Derived, Argument> &other)
{
Arguments arguments;
arguments.reserve(other.arguments.size());
for (const auto &argument : other.arguments)
arguments.emplace_back(std::move(deepCopyVariant(argument)));
return arguments;
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Derived, class Argument>
struct Quantified
{
using Parameters = VariableDeclarations;
explicit Quantified(Parameters &&parameters, Argument &&argument)
: parameters{std::move(parameters)},
argument{std::move(argument)}
{
}
Quantified(const Quantified &other) = delete;
Quantified &operator=(const Quantified &&other) = delete;
Quantified(Quantified &&other) = default;
Quantified &operator=(Quantified &&other) = default;
Parameters parameters;
Argument argument;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Expressions
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct And: public NAry<And<Argument>, Argument>
{
using typename NAry<And<Argument>, Argument>::Arguments;
static constexpr const auto Identifier = "and";
explicit And(Arguments &&arguments) noexcept
: NAry<And<Argument>, Argument>(std::move(arguments))
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct At
{
static constexpr const auto TimePointStart = std::numeric_limits<std::size_t>::max();
static constexpr const auto TimePointEnd = std::numeric_limits<std::size_t>::max() - 1;
At(std::size_t timePoint, Argument &&argument)
: timePoint{timePoint},
argument{std::move(argument)}
{
}
At(const At &other) = delete;
At &operator=(const At &&other) = delete;
At(At &&other) = default;
At &operator=(At &&other) = default;
std::size_t timePoint;
Argument argument;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct Either: public NAry<Either<Argument>, Argument>
{
using typename NAry<Either<Argument>, Argument>::Arguments;
static constexpr const auto Identifier = "either";
explicit Either(Arguments &&arguments) noexcept
: NAry<Either<Argument>, Argument>(std::move(arguments))
{
}
Either(const Either &other)
: NAry<Either<Argument>, Argument>(this->copyArguments(other))
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct Exists: public Quantified<Exists<Argument>, Argument>
{
static constexpr const auto Identifier = "exists";
explicit Exists(VariableDeclarations &&parameters, Argument &&argument)
: Quantified<Exists<Argument>, Argument>(std::move(parameters), std::move(argument))
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct ForAll: public Quantified<ForAll<Argument>, Argument>
{
static constexpr const auto Identifier = "forall";
explicit ForAll(VariableDeclarations &&parameters, Argument &&argument)
: Quantified<ForAll<Argument>, Argument>(std::move(parameters), std::move(argument))
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct Imply: public Binary<Imply<Argument>, Argument>
{
static constexpr const auto Identifier = "imply";
// TODO: make noexcept consistent
explicit Imply(Argument &&argumentLeft, Argument &&argumentRight)
: Binary<Imply<Argument>, Argument>(std::move(argumentLeft), std::move(argumentRight))
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct Not
{
explicit Not(Argument &&argument)
: argument{std::move(argument)}
{
}
Not(const Not &other) = delete;
Not &operator=(const Not &&other) = delete;
Not(Not &&other) = default;
Not &operator=(Not &&other) = default;
Argument argument;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct Or: public NAry<Or<Argument>, Argument>
{
using typename NAry<Or<Argument>, Argument>::Arguments;
static constexpr const auto Identifier = "or";
explicit Or(Arguments &&arguments) noexcept
: NAry<Or<Argument>, Argument>(std::move(arguments))
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class ArgumentLeft, class ArgumentRight>
struct When: public Binary<When<ArgumentLeft, ArgumentRight>, ArgumentLeft, ArgumentRight>
{
static constexpr const auto Identifier = "when";
explicit When(ArgumentLeft &&argumentLeft, ArgumentRight &&argumentRight)
: Binary<When<ArgumentLeft, ArgumentRight>, ArgumentLeft, ArgumentRight>(std::move(argumentLeft), std::move(argumentRight))
{
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// PDDL Structure
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Action
{
Action(const Action &other) = delete;
Action &operator=(const Action &&other) = delete;
Action(Action &&other) = default;
Action &operator=(Action &&other) = default;
std::string name;
ast::VariableDeclarations parameters;
std::experimental::optional<ast::Precondition> precondition;
std::experimental::optional<ast::Effect> effect;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Domain
{
Domain(const Domain &other) = delete;
Domain &operator=(const Domain &&other) = delete;
Domain(Domain &&other) = default;
Domain &operator=(Domain &&other) = default;
std::string name;
Requirements requirements;
ast::PrimitiveTypeDeclarations types;
ast::ConstantDeclarations constants;
ast::PredicateDeclarations predicates;
std::vector<Action> actions;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct InitialState
{
InitialState(const InitialState &other) = delete;
InitialState &operator=(const InitialState &&other) = delete;
InitialState(InitialState &&other) = default;
InitialState &operator=(InitialState &&other) = default;
ast::Facts facts;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Problem
{
Problem(const Problem &other) = delete;
Problem &operator=(const Problem &&other) = delete;
Problem(Problem &&other) = default;
Problem &operator=(Problem &&other) = default;
Domain &domain;
std::string name;
Requirements requirements;
ast::ConstantDeclarations objects;
InitialState initialState;
std::experimental::optional<ast::Goal> goal;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
enum class Requirement
{
STRIPS,
Typing,
NegativePreconditions,
DisjunctivePreconditions,
Equality,
ExistentialPreconditions,
UniversalPreconditions,
QuantifiedPreconditions,
ConditionalEffects,
Fluents,
NumericFluents,
ObjectFluents,
ADL,
DurativeActions,
DurationInequalities,
ContinuousEffects,
DerivedPredicates,
TimedInitialLiterals,
Preferences,
Constraints,
ActionCosts,
GoalUtilities
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Description
{
Description(const Description &other) = delete;
Description &operator=(const Description &&other) = delete;
Description(Description &&other) = default;
Description &operator=(Description &&other) = default;
Domain domain;
std::experimental::optional<Problem> problem;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,194 @@
#ifndef __PDDL_PARSE__AST_FORWARD_H
#define __PDDL_PARSE__AST_FORWARD_H
#include <iosfwd>
#include <memory>
#include <experimental/optional>
#include <set>
#include <vector>
#include <pddlparse/Variant.h>
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// AST Forward Declarations
//
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace ast
{
////////////////////////////////////////////////////////////////////////////////////////////////////
// Primitives
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Constant;
struct ConstantDeclaration;
using ConstantDeclarations = std::vector<ConstantDeclaration>;
struct Dummy;
struct PrimitiveType;
using PrimitiveTypes = std::vector<PrimitiveType>;
struct PrimitiveTypeDeclaration;
using PrimitiveTypeDeclarations = std::vector<PrimitiveTypeDeclaration>;
struct Unsupported;
struct Variable;
using Variables = std::vector<Variable>;
struct VariableDeclaration;
using VariableDeclarations = std::vector<VariableDeclaration>;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Compounds
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Predicate;
using Predicates = std::vector<Predicate>;
struct PredicateDeclaration;
using PredicateDeclarations = std::vector<PredicateDeclaration>;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Expressions
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Argument>
struct And;
template<class Argument>
struct At;
template<class Argument>
struct Either;
template<class Argument>
struct Exists;
template<class Argument>
struct ForAll;
template<class Argument>
struct Imply;
template<class Argument>
struct Not;
template<class Argument>
struct Or;
template<class ArgumentLeft, class ArgumentRight>
struct When;
////////////////////////////////////////////////////////////////////////////////////////////////////
// PDDL Structure
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Description;
struct Domain;
struct Problem;
enum class Requirement;
using Requirements = std::vector<Requirement>;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Variants
////////////////////////////////////////////////////////////////////////////////////////////////////
using TermT = Variant<
Constant,
Variable>;
class Term : public TermT
{
using TermT::TermT;
};
using Terms = std::vector<Term>;
////////////////////////////////////////////////////////////////////////////////////////////////////
using AtomicFormulaT = Variant<
Predicate,
Unsupported>;
class AtomicFormula : public AtomicFormulaT
{
using AtomicFormulaT::AtomicFormulaT;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
class Precondition;
using PreconditionT = Variant<
AtomicFormula,
And<Precondition>,
Exists<Precondition>,
ForAll<Precondition>,
Imply<Precondition>,
Not<Precondition>,
Or<Precondition>,
Unsupported>;
class Precondition : public PreconditionT
{
using PreconditionT::PreconditionT;
};
using Preconditions = std::vector<Precondition>;
////////////////////////////////////////////////////////////////////////////////////////////////////
class Effect;
using EffectT = Variant<
AtomicFormula,
And<Effect>,
ForAll<Effect>,
Not<Effect>,
When<Precondition, Effect>,
Unsupported>;
class Effect : public EffectT
{
using EffectT::EffectT;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
using TypeT = Variant<
Either<PrimitiveType>,
PrimitiveType>;
class Type : public TypeT
{
using TypeT::TypeT;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
using LiteralT = Variant<
AtomicFormula,
Not<AtomicFormula>>;
class Literal : public LiteralT
{
using LiteralT::LiteralT;
};
using Literals = std::vector<Literal>;
////////////////////////////////////////////////////////////////////////////////////////////////////
using FactT = Variant<
AtomicFormula,
At<Literal>>;
class Fact : public FactT
{
using FactT::FactT;
};
using Facts = std::vector<Fact>;
////////////////////////////////////////////////////////////////////////////////////////////////////
using Goal = Precondition;
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,281 @@
#ifndef __PDDL_PARSE__VARIANT_H
#define __PDDL_PARSE__VARIANT_H
#include <memory>
#include <ostream>
#include <type_traits>
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 Optional {
public:
Optional() { }
Optional(T const &x) : data_(new T(x)) { }
Optional(T &x) : data_(new T(x)) { }
Optional(T &&x) : data_(new T(std::move(x))) { }
template <class... Args>
Optional(Args&&... x) : data_(new T{std::forward<Args>(x)...}) { }
Optional(Optional &&opt) noexcept : data_(opt.data_.release()) { }
Optional(Optional const &opt) : data_(opt ? new T(*opt.get()) : nullptr) { }
Optional &operator=(T const &x) {
clear();
data_.reset(new T(x));
}
Optional &operator=(T &x) {
clear();
data_.reset(new T(x));
}
Optional &operator=(T &&x) {
clear();
data_.reset(new T(std::move(x)));
}
Optional &operator=(Optional &&opt) noexcept {
data_ = std::move(opt.data_);
}
Optional &operator=(Optional const &opt) {
clear();
data_.reset(opt ? new T(*opt.get()) : nullptr);
}
T *get() { return data_.get(); }
T const *get() const { return data_.get(); }
T *operator->() { return get(); }
T const *operator->() const { return get(); }
T &operator*() & { return *get(); }
T const &operator*() const & { return *get(); }
T &&operator*() && { return std::move(*get()); }
T const &&operator*() const && { return std::move(*get()); }
template <class... Args>
void emplace(Args&&... x) {
clear();
data_(new T{std::forward<Args>(x)...});
}
void clear() { data_.reset(nullptr); }
explicit operator bool() const { return data_.get() != nullptr; }
private:
std::unique_ptr<T> data_;
};
template <class... T>
class Variant {
using Holder = detail::VariantHolder<1, T...>;
public:
Variant(Variant const &other) : Variant(other.data_) { }
Variant(Variant &&other) noexcept { data_.swap(other.data_); }
template <class U>
Variant(U &&u, typename std::enable_if<detail::TypeInList<U, T...>::value>::type * = nullptr) { emplace2<U>(std::forward<U>(u)); }
template <class U>
Variant(U &u, typename std::enable_if<detail::TypeInList<U, T...>::value>::type * = nullptr) { emplace2<U>(u); }
template <class U>
Variant(U const &u, typename std::enable_if<detail::TypeInList<U, T...>::value>::type * = nullptr) { emplace2<U>(u); }
template <class U, class... Args>
static Variant make(Args&& ...args) {
Variant<T...> x;
x.data_.emplace(static_cast<U*>(nullptr), std::forward<Args>(args)...);
return std::move(x);
}
~Variant() { data_.destroy(); }
Variant &operator=(Variant const &other) { return *this = other.data_; }
Variant &operator=(Variant &&other) noexcept { return *this = std::move(other.data_); }
template <class U>
typename std::enable_if<detail::TypeInList<U, T...>::value, Variant>::type &operator=(U &&u) {
emplace2<U>(std::forward<U>(u));
return *this;
}
template <class U>
typename std::enable_if<detail::TypeInList<U, T...>::value, Variant>::type &operator=(U &u) {
emplace2<U>(u);
return *this;
}
template <class U>
typename std::enable_if<detail::TypeInList<U, T...>::value, Variant>::type &operator=(U const &u) {
emplace2<U>(u);
return *this;
}
template <class U>
U &get() {
if (!data_.check_type(static_cast<U*>(nullptr))) { throw std::bad_cast(); }
return *static_cast<U*>(data_.data_);
}
template <class U>
U const &get() const {
if (!data_.check_type(static_cast<U*>(nullptr))) { throw std::bad_cast(); }
return *static_cast<U*>(data_.data_);
}
template <class U, class... Args>
void emplace(Args&& ...args) {
Variant<T...> x;
x.data_.emplace(static_cast<U*>(nullptr), std::forward<Args>(args)...);
data_.swap(x.data_);
}
template <class U>
bool is() const { return data_.check_type(static_cast<U*>(nullptr)); }
void swap(Variant &other) { data_.swap(other.data_); }
template <class V, class... Args>
typename Holder::template Ret_<V, Args...> accept(V &&visitor, Args &&... args) {
return data_.accept(std::forward<V>(visitor), std::forward<Args>(args)...);
}
template <class V, class... Args>
typename Holder::template ConstRet_<V, Args...> accept(V &&visitor, Args &&... args) const {
return data_.accept(std::forward<V>(visitor), std::forward<Args>(args)...);
}
friend std::ostream &operator<<(std::ostream &out, Variant const &x) {
x.data_.print(out);
return out;
}
private:
Variant() { }
Variant(Holder const &data) {
data_.copy(data);
}
Variant &operator=(Holder const &data) {
Variant x(data);
data_.swap(x.data_);
return *this;
}
Variant &operator=(Holder &&data) noexcept {
Holder x;
x.swap(data);
// Destroy the old data_ only after securing the new data
// Otherwise, data would be destroyed together with data_ if it was a descendant of data_
data_.destroy();
x.swap(data_);
return *this;
}
template <class U, class... Args>
void emplace2(Args&& ...args) {
Variant<T...> x;
x.data_.emplace2(static_cast<U*>(nullptr), std::forward<Args>(args)...);
data_.swap(x.data_);
}
private:
Holder data_;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
#endif

View File

@ -0,0 +1,56 @@
#ifndef __PDDL_PARSE__DETAIL__PARSER_H
#define __PDDL_PARSE__DETAIL__PARSER_H
#include <iostream>
#include <parsebase/Parser.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Parser
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class PDDLParserPolicy
{
public:
static char transformCharacter(char c) noexcept
{
return std::tolower(c);
}
static bool isWhiteSpaceCharacter(char c)
{
return std::iswspace(c);
}
static bool isBlankCharacter(char c)
{
return std::isblank(c);
}
static bool isIdentifierCharacter(char c)
{
return c != '?'
&& c != '('
&& c != ')'
&& c != ';'
&& std::isgraph(c);
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////
using Parser = parsebase::Parser<PDDLParserPolicy>;
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,32 @@
#ifndef __PDDL_PARSE__DETAIL__VARIABLE_STACK_H
#define __PDDL_PARSE__DETAIL__VARIABLE_STACK_H
#include <pddlparse/ASTForward.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// VariableStack
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class VariableStack
{
public:
void push(ast::VariableDeclarations *variables);
void pop();
private:
std::vector<ast::VariableDeclarations *> m_variableStack;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,28 @@
set(target pddlparse)
file(GLOB core_sources "pddlparse/*.cpp")
file(GLOB core_headers "../include/pddlparse/*.h")
file(GLOB detail_sources "pddlparse/detail/*.cpp")
file(GLOB detail_headers "../include/pddlparse/detail/*.h")
set(includes
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/../../lib/parsebase/include
)
set(sources
${core_sources}
${core_headers}
${detail_sources}
${detail_headers}
)
set(libraries
parsebase
)
add_library(${target} ${sources})
target_include_directories(${target} PRIVATE ${includes})
target_link_libraries(${target} ${libraries})

View File

@ -0,0 +1,31 @@
#include <pddlparse/detail/VariableStack.h>
#include <pddlparse/AST.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// VariableStack
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void VariableStack::push(ast::VariableDeclarations *variables)
{
m_variableStack.push_back(variables);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void VariableStack::pop()
{
m_variableStack.pop_back();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -0,0 +1,21 @@
set(target pddlparse-tests)
file(GLOB core_sources "*.cpp")
set(includes
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/../../lib/catch/single_include
)
set(libraries
pddlparse
)
add_executable(${target} ${core_sources})
target_include_directories(${target} PRIVATE ${includes})
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)

View File

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include <catch.hpp>