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;
namespace detail
@ -182,7 +200,7 @@ using EffectT = Variant<
AndPointer<Effect>,
ForAllPointer<Effect>,
NotPointer<Effect>,
WhenPointer<Precondition, Effect>,
WhenPointer<Precondition, ConditionalEffect>,
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> parsePreconditionBody(Context &context, ASTContext &astContext, VariableStack &variableStack);
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -3,8 +3,8 @@
#include <pddlparse/AST.h>
#include <pddlparse/detail/ASTContext.h>
#include <pddlparse/detail/VariableStack.h>
#include <pddlparse/detail/parsing/Effect.h>
#include <pddlparse/detail/parsing/Precondition.h>
// TODO: remove
#include <pddlparse/detail/parsing/Utils.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;
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
//VariableStack variableStack;
//variableStack.push(&action.parameters);
ASTContext astContext(m_domain);
//ASTContext astContext(m_domain);
//action.precondition = parseEffect(m_context, astContext, variableStack);
//tokenizer.expect<std::string>(")");
skipSection(tokenizer);
action.effect = parseEffect(m_context, astContext, variableStack);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

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)
{
auto &tokenizer = context.tokenizer;
tokenizer.skipWhiteSpace();
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());
}
// Test unsupported expressions first
const auto position = tokenizer.position();
tokenizer.expect<std::string>("(");
@ -45,6 +34,17 @@ std::experimental::optional<ast::Precondition> parsePrecondition(Context &contex
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);
return parsePreconditionBody(context, astContext, variableStack);
}
@ -57,19 +57,7 @@ std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &co
tokenizer.skipWhiteSpace();
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());
}
// Test unsupported expressions first
const auto position = tokenizer.position();
tokenizer.expect<std::string>("(");
@ -93,11 +81,27 @@ std::experimental::optional<ast::Precondition> parsePreconditionBody(Context &co
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);
const auto expressionIdentifier = tokenizer.getIdentifier();
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");
}
////////////////////////////////////////////////////////////////////////////////////////////////////