Added back support for parsing effects and even conditional effects.

This commit is contained in:
Patrick Lühne 2017-06-17 19:04:27 +02:00
parent 9c30e27875
commit 10e658a922
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
6 changed files with 237 additions and 41 deletions

View File

@ -173,6 +173,24 @@ using Preconditions = std::vector<Precondition>;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
class ConditionalEffect;
namespace detail
{
using ConditionalEffectT = Variant<
AtomicFormula,
AndPointer<ConditionalEffect>,
NotPointer<ConditionalEffect>,
UnsupportedPointer>;
}
class ConditionalEffect : public detail::ConditionalEffectT
{
using detail::ConditionalEffectT::ConditionalEffectT;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
class Effect; class Effect;
namespace detail namespace detail
@ -182,7 +200,7 @@ using EffectT = Variant<
AndPointer<Effect>, AndPointer<Effect>,
ForAllPointer<Effect>, ForAllPointer<Effect>,
NotPointer<Effect>, NotPointer<Effect>,
WhenPointer<Precondition, Effect>, WhenPointer<Precondition, ConditionalEffect>,
UnsupportedPointer>; UnsupportedPointer>;
} }

View File

@ -0,0 +1,27 @@
#ifndef __PDDL_PARSE__DETAIL__PARSING__EFFECT_H
#define __PDDL_PARSE__DETAIL__PARSING__EFFECT_H
#include <pddlparse/ASTForward.h>
#include <pddlparse/Context.h>
#include <pddlparse/detail/ASTContext.h>
#include <pddlparse/detail/VariableStack.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Effect
//
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::Effect> parseEffect(Context &context, ASTContext &astContext, VariableStack &variableStack);
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -18,6 +18,7 @@ namespace detail
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::Precondition> parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack); std::experimental::optional<ast::Precondition> parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack);
std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -3,8 +3,8 @@
#include <pddlparse/AST.h> #include <pddlparse/AST.h>
#include <pddlparse/detail/ASTContext.h> #include <pddlparse/detail/ASTContext.h>
#include <pddlparse/detail/VariableStack.h> #include <pddlparse/detail/VariableStack.h>
#include <pddlparse/detail/parsing/Effect.h>
#include <pddlparse/detail/parsing/Precondition.h> #include <pddlparse/detail/parsing/Precondition.h>
// TODO: remove
#include <pddlparse/detail/parsing/Utils.h> #include <pddlparse/detail/parsing/Utils.h>
#include <pddlparse/detail/parsing/VariableDeclaration.h> #include <pddlparse/detail/parsing/VariableDeclaration.h>
@ -159,26 +159,18 @@ void ActionParser::parsePreconditionSection(ast::Action &action)
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void ActionParser::parseEffectSection(ast::Action &) void ActionParser::parseEffectSection(ast::Action &action)
{ {
auto &tokenizer = m_context.tokenizer; auto &tokenizer = m_context.tokenizer;
tokenizer.expect<std::string>(":effect"); tokenizer.expect<std::string>(":effect");
tokenizer.expect<std::string>("(");
m_context.warningCallback(tokenizer.location(), "effect parser under construction, section is currently ignored"); VariableStack variableStack;
variableStack.push(&action.parameters);
// TODO: reimplement ASTContext astContext(m_domain);
//VariableStack variableStack;
//variableStack.push(&action.parameters);
//ASTContext astContext(m_domain); action.effect = parseEffect(m_context, astContext, variableStack);
//action.precondition = parseEffect(m_context, astContext, variableStack);
//tokenizer.expect<std::string>(")");
skipSection(tokenizer);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,154 @@
#include <pddlparse/detail/parsing/Effect.h>
#include <pddlparse/AST.h>
#include <pddlparse/detail/parsing/Expressions.h>
#include <pddlparse/detail/parsing/Precondition.h>
#include <pddlparse/detail/parsing/Predicate.h>
#include <pddlparse/detail/parsing/Unsupported.h>
#include <pddlparse/detail/parsing/Utils.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Effect
//
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::Effect> parseEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
std::experimental::optional<ast::ConditionalEffect> parseConditionalEffect(Context &context, ASTContext &astContext, VariableStack &variableStack);
std::experimental::optional<ast::ConditionalEffect> parseConditionalEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::Effect> parseEffect(Context &context, ASTContext &astContext, VariableStack &variableStack)
{
auto &tokenizer = context.tokenizer;
tokenizer.skipWhiteSpace();
std::experimental::optional<ast::Effect> effect;
if ((effect = parseAnd<ast::Effect>(context, astContext, variableStack, parseEffect))
|| (effect = parseForAll<ast::Effect>(context, astContext, variableStack, parseEffect))
|| (effect = parseWhen<ast::Precondition, ast::ConditionalEffect>(context, astContext, variableStack, parsePreconditionBody, parseConditionalEffect)))
{
return std::move(effect.value());
}
return parseEffectBody(context, astContext, variableStack);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::Effect> parseEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack)
{
auto &tokenizer = context.tokenizer;
tokenizer.skipWhiteSpace();
// Test unsupported expressions first
const auto position = tokenizer.position();
tokenizer.expect<std::string>("(");
tokenizer.skipWhiteSpace();
const auto expressionIdentifierPosition = tokenizer.position();
if (tokenizer.testIdentifierAndReturn("=")
|| tokenizer.testIdentifierAndReturn("assign")
|| tokenizer.testIdentifierAndReturn("scale-up")
|| tokenizer.testIdentifierAndReturn("scale-down")
|| tokenizer.testIdentifierAndReturn("increase")
|| tokenizer.testIdentifierAndReturn("decrease"))
{
tokenizer.seek(position);
return parseUnsupported(context);
}
tokenizer.seek(position);
// Now, test supported expressions
std::experimental::optional<ast::Effect> effect;
if ((effect = parseNot<ast::Effect>(context, astContext, variableStack, parsePredicate))
|| (effect = parsePredicate(context, astContext, variableStack)))
{
return std::move(effect.value());
}
tokenizer.seek(expressionIdentifierPosition);
const auto expressionIdentifier = tokenizer.getIdentifier();
tokenizer.seek(position);
throw tokenize::TokenizerException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in effect body");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::ConditionalEffect> parseConditionalEffect(Context &context, ASTContext &astContext, VariableStack &variableStack)
{
auto &tokenizer = context.tokenizer;
tokenizer.skipWhiteSpace();
std::experimental::optional<ast::ConditionalEffect> conditionalEffect;
if ((conditionalEffect = parseAnd<ast::ConditionalEffect>(context, astContext, variableStack, parseConditionalEffectBody)))
return std::move(conditionalEffect.value());
return parseConditionalEffectBody(context, astContext, variableStack);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::ConditionalEffect> parseConditionalEffectBody(Context &context, ASTContext &astContext, VariableStack &variableStack)
{
auto &tokenizer = context.tokenizer;
tokenizer.skipWhiteSpace();
// Test unsupported expressions first
const auto position = tokenizer.position();
tokenizer.expect<std::string>("(");
tokenizer.skipWhiteSpace();
const auto expressionIdentifierPosition = tokenizer.position();
if (tokenizer.testIdentifierAndReturn("=")
|| tokenizer.testIdentifierAndReturn("assign")
|| tokenizer.testIdentifierAndReturn("scale-up")
|| tokenizer.testIdentifierAndReturn("scale-down")
|| tokenizer.testIdentifierAndReturn("increase")
|| tokenizer.testIdentifierAndReturn("decrease"))
{
tokenizer.seek(position);
return parseUnsupported(context);
}
tokenizer.seek(position);
// Now, test supported expressions
std::experimental::optional<ast::ConditionalEffect> conditionalEffect;
if ((conditionalEffect = parseNot<ast::ConditionalEffect>(context, astContext, variableStack, parsePredicate))
|| (conditionalEffect = parsePredicate(context, astContext, variableStack)))
{
return std::move(conditionalEffect.value());
}
tokenizer.seek(expressionIdentifierPosition);
const auto expressionIdentifier = tokenizer.getIdentifier();
tokenizer.seek(position);
throw tokenize::TokenizerException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in conditional effect body");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -17,24 +17,13 @@ namespace detail
// //
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::Precondition> parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack) std::experimental::optional<ast::Precondition> parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack)
{ {
auto &tokenizer = context.tokenizer; auto &tokenizer = context.tokenizer;
tokenizer.skipWhiteSpace(); tokenizer.skipWhiteSpace();
std::experimental::optional<ast::Precondition> precondition; // Test unsupported expressions first
if ((precondition = parseAnd<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseForAll<ast::Precondition>(context, astContext, variableStack, parsePrecondition)))
{
return std::move(precondition.value());
}
const auto position = tokenizer.position(); const auto position = tokenizer.position();
tokenizer.expect<std::string>("("); tokenizer.expect<std::string>("(");
@ -45,6 +34,17 @@ std::experimental::optional<ast::Precondition> parsePrecondition(Context &contex
return parseUnsupported(context); return parseUnsupported(context);
} }
tokenizer.seek(position);
// Now, test supported expressions
std::experimental::optional<ast::Precondition> precondition;
if ((precondition = parseAnd<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseForAll<ast::Precondition>(context, astContext, variableStack, parsePrecondition)))
{
return std::move(precondition.value());
}
tokenizer.seek(position); tokenizer.seek(position);
return parsePreconditionBody(context, astContext, variableStack); return parsePreconditionBody(context, astContext, variableStack);
} }
@ -57,19 +57,7 @@ std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &co
tokenizer.skipWhiteSpace(); tokenizer.skipWhiteSpace();
std::experimental::optional<ast::Precondition> precondition; // Test unsupported expressions first
if ((precondition = parseAnd<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseOr<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseExists<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseForAll<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseNot<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseImply<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parsePredicate(context, astContext, variableStack)))
{
return std::move(precondition.value());
}
const auto position = tokenizer.position(); const auto position = tokenizer.position();
tokenizer.expect<std::string>("("); tokenizer.expect<std::string>("(");
@ -93,11 +81,27 @@ std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &co
return parseUnsupported(context); return parseUnsupported(context);
} }
tokenizer.seek(position);
// Now, test supported expressions
std::experimental::optional<ast::Precondition> precondition;
if ((precondition = parseAnd<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseOr<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseExists<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseForAll<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseNot<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parseImply<ast::Precondition>(context, astContext, variableStack, parsePrecondition))
|| (precondition = parsePredicate(context, astContext, variableStack)))
{
return std::move(precondition.value());
}
tokenizer.seek(expressionIdentifierPosition); tokenizer.seek(expressionIdentifierPosition);
const auto expressionIdentifier = tokenizer.getIdentifier(); const auto expressionIdentifier = tokenizer.getIdentifier();
tokenizer.seek(position); tokenizer.seek(position);
throw tokenize::TokenizerException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); throw tokenize::TokenizerException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in precondition body");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////