Started refactoring Variables as expressions.
This commit is contained in:
@@ -37,7 +37,7 @@ Action &Action::parseDeclaration(utils::Parser &parser, Context &context)
|
||||
// Read parameters
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
Variable::parseTyped(parser, context, action->m_parameters);
|
||||
expressions::VariableExpression::parseTypedDeclaration(parser, context, action->m_parameters);
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
@@ -74,7 +74,7 @@ const std::string &Action::name() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Variables &Action::parameters() const
|
||||
const expressions::VariableExpressions &Action::parameters() const
|
||||
{
|
||||
return m_parameters;
|
||||
}
|
||||
|
@@ -19,9 +19,12 @@ namespace pddl
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<Expression> parseExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters);
|
||||
std::unique_ptr<Expression> parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters);
|
||||
std::unique_ptr<Expression> parsePredicateExpression(utils::Parser &parser, Context &context, const Variables ¶meters);
|
||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
|
||||
utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters);
|
||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
||||
utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters);
|
||||
ExpressionPointer parsePredicateExpression(utils::Parser &parser, Context &context,
|
||||
const expressions::VariableExpressions ¶meters);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -32,16 +35,20 @@ void throwUnsupported(const utils::Parser &parser, const std::string &expression
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<Expression> parsePreconditionExpression(utils::Parser &parser, Context &context, const Variables ¶meters)
|
||||
ExpressionPointer parsePreconditionExpression(utils::Parser &parser, Context &context,
|
||||
const expressions::VariableExpressions ¶meters)
|
||||
{
|
||||
parser.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
std::unique_ptr<Expression> expression;
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
expression = expressions::AndExpression::parse(parser, context, parameters, parsePreconditionExpression);
|
||||
{
|
||||
expression = expressions::AndExpression::parse(parser, context, parameters,
|
||||
parsePreconditionExpression);
|
||||
}
|
||||
else if (expressionIdentifier == "forall"
|
||||
|| expressionIdentifier == "preference")
|
||||
{
|
||||
@@ -57,7 +64,8 @@ std::unique_ptr<Expression> parsePreconditionExpression(utils::Parser &parser, C
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<Expression> parseExpression(utils::Parser &parser, Context &context, const Variables ¶meters)
|
||||
ExpressionPointer parseExpression(utils::Parser &parser, Context &context,
|
||||
const expressions::VariableExpressions ¶meters)
|
||||
{
|
||||
parser.expect<std::string>("(");
|
||||
|
||||
@@ -72,11 +80,12 @@ std::unique_ptr<Expression> parseExpression(utils::Parser &parser, Context &cont
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<Expression> parseExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters)
|
||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier,
|
||||
utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
std::unique_ptr<Expression> expression;
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
expression = expressions::AndExpression::parse(parser, context, parameters, parseExpression);
|
||||
@@ -122,13 +131,14 @@ std::unique_ptr<Expression> parseExpressionContent(const std::string &expression
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<Expression> parseEffectExpression(utils::Parser &parser, Context &context, const Variables ¶meters)
|
||||
ExpressionPointer parseEffectExpression(utils::Parser &parser, Context &context,
|
||||
const expressions::VariableExpressions ¶meters)
|
||||
{
|
||||
parser.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
std::unique_ptr<Expression> expression;
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
expression = expressions::AndExpression::parse(parser, context, parameters, parseEffectExpression);
|
||||
@@ -147,9 +157,10 @@ std::unique_ptr<Expression> parseEffectExpression(utils::Parser &parser, Context
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<Expression> parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters)
|
||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
||||
utils::Parser &parser, Context &context, const expressions::VariableExpressions ¶meters)
|
||||
{
|
||||
std::unique_ptr<Expression> expression;
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "not")
|
||||
expression = expressions::NotExpression::parse(parser, context, parameters, parsePredicateExpression);
|
||||
@@ -183,13 +194,14 @@ std::unique_ptr<Expression> parseEffectBodyExpressionContent(const std::string &
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<Expression> parsePredicateExpression(utils::Parser &parser, Context &context, const Variables ¶meters)
|
||||
ExpressionPointer parsePredicateExpression(utils::Parser &parser, Context &context,
|
||||
const expressions::VariableExpressions ¶meters)
|
||||
{
|
||||
parser.expect<std::string>("(");
|
||||
|
||||
const auto predicateName = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
std::unique_ptr<Expression> expression;
|
||||
ExpressionPointer expression;
|
||||
|
||||
// Check if predicate with that name exists
|
||||
const auto match = std::find_if(context.predicates.cbegin(), context.predicates.cend(),
|
||||
|
@@ -15,7 +15,8 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::unique_ptr<PredicateExpression> PredicateExpression::parse(std::string name, utils::Parser &parser, Context &context, const Variables ¶meters)
|
||||
PredicateExpressionPointer PredicateExpression::parse(std::string name, utils::Parser &parser,
|
||||
Context &context, const VariableExpressions ¶meters)
|
||||
{
|
||||
auto expression = std::make_unique<PredicateExpression>(PredicateExpression());
|
||||
|
||||
@@ -25,7 +26,7 @@ std::unique_ptr<PredicateExpression> PredicateExpression::parse(std::string name
|
||||
|
||||
// Parse arguments
|
||||
while (parser.currentCharacter() != ')')
|
||||
Variable::parseTyped(parser, context, expression->m_arguments);
|
||||
expression->m_arguments.emplace_back(VariableExpression::parse(parser, parameters));
|
||||
|
||||
// TODO: check that signature matches one of the declared ones
|
||||
|
||||
@@ -41,6 +42,13 @@ void PredicateExpression::accept(plasp::pddl::ExpressionVisitor &expressionVisit
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::vector<const VariableExpression *> &PredicateExpression::arguments() const
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
142
src/plasp/pddl/expressions/VariableExpression.cpp
Normal file
142
src/plasp/pddl/expressions/VariableExpression.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include <plasp/pddl/expressions/VariableExpression.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/ExpressionVisitor.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/utils/ParserException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// VariableExpression
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VariableExpression::VariableExpression()
|
||||
: m_isDirty{false}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VariableExpressionPointer VariableExpression::parseDeclaration(utils::Parser &parser)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
parser.expect<std::string>("?");
|
||||
|
||||
auto variable = std::make_unique<VariableExpression>(VariableExpression());
|
||||
|
||||
variable->m_name = parser.parseIdentifier(isIdentifier);
|
||||
variable->setDirty();
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableExpression::parseTypedDeclaration(utils::Parser &parser, Context &context,
|
||||
VariableExpressions &variableExpressions)
|
||||
{
|
||||
// Parse and store variable itself
|
||||
variableExpressions.emplace_back(parseDeclaration(parser));
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Check if the variable has a type declaration
|
||||
if (!parser.advanceIf('-'))
|
||||
return;
|
||||
|
||||
// Parse argument type
|
||||
const auto type = parseType(parser, context);
|
||||
|
||||
// Set the argument type for all previously flagged arguments
|
||||
std::for_each(variableExpressions.begin(), variableExpressions.end(),
|
||||
[&](auto &variable)
|
||||
{
|
||||
if (!variable->isDirty())
|
||||
return;
|
||||
|
||||
variable->setType(type);
|
||||
variable->setDirty(false);
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const VariableExpression *VariableExpression::parse(utils::Parser &parser,
|
||||
const VariableExpressions &variableExpressions)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
parser.expect<std::string>("?");
|
||||
|
||||
const auto variableName = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
const auto match = std::find_if(variableExpressions.cbegin(), variableExpressions.cend(),
|
||||
[&](const auto &variableExpression)
|
||||
{
|
||||
return variableExpression->name() == variableName;
|
||||
});
|
||||
|
||||
if (match == variableExpressions.cend())
|
||||
throw utils::ParserException(parser.row(), parser.column(), "Variable \"" + variableName + "\" used but never declared");
|
||||
|
||||
return match->get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableExpression::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
||||
{
|
||||
expressionVisitor.visit(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &VariableExpression::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypePtr VariableExpression::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableExpression::setDirty(bool isDirty)
|
||||
{
|
||||
m_isDirty = isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool VariableExpression::isDirty() const
|
||||
{
|
||||
return m_isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VariableExpression::setType(TypePtr type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user