Implemented constant type checking.

This commit is contained in:
Patrick Lühne 2016-06-08 01:14:39 +02:00
parent 32883910bb
commit 8db4b5a53e
3 changed files with 23 additions and 42 deletions

View File

@ -23,6 +23,7 @@ class Constant: public Expression
{
public:
static void parseTypedDeclaration(Context &context, Domain &domain);
static void parseTypedDeclarations(Context &context, Domain &domain);
static void parseTypedDeclaration(Context &context, Problem &problem);
static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext);
@ -35,8 +36,6 @@ class Constant: public Expression
const std::string &name() const;
const PrimitiveType *type() const;
bool isDeclared() const;
private:
static ConstantPointer parseDeclaration(Context &context);
static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants);
@ -48,12 +47,9 @@ class Constant: public Expression
void setDirty(bool isDirty = true);
bool isDirty() const;
void setDeclared();
void setType(const PrimitiveType *parentType);
bool m_isDirty;
bool m_isDeclared;
std::string m_name;

View File

@ -273,12 +273,7 @@ void Domain::parseConstantSection()
m_context.parser.skipWhiteSpace();
// Store constants
while (m_context.parser.currentCharacter() != ')')
{
expressions::Constant::parseTypedDeclaration(m_context, *this);
m_context.parser.skipWhiteSpace();
}
expressions::Constant::parseTypedDeclarations(m_context, *this);
m_context.parser.expect<std::string>(")");
}
@ -315,17 +310,6 @@ void Domain::parseActionSection()
void Domain::checkConsistency()
{
// Verify that all used constants have been declared
std::for_each(m_constants.cbegin(), m_constants.cend(),
[&](const auto &constant)
{
if (!constant->isDeclared())
throw ConsistencyException("Constant \"" + constant->name() + "\" used but never declared");
if (constant->type() == nullptr)
throw ConsistencyException("Constant \"" + constant->name() + "\" has an undeclared type");
});
// Verify that all used predicates have been declared
std::for_each(m_predicateDeclarations.cbegin(), m_predicateDeclarations.cend(),
[&](const auto &predicate)

View File

@ -26,7 +26,6 @@ namespace expressions
Constant::Constant()
: m_isDirty{false},
m_isDeclared{false},
m_type{nullptr}
{
}
@ -72,11 +71,6 @@ void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants
// Parse and store constant
constants.emplace_back(parseDeclaration(context));
const auto &constant = constants.back();
// Flag constant as correctly declared in the types section
constant->setDeclared();
context.parser.skipWhiteSpace();
// Check for typing information
@ -100,6 +94,27 @@ void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants
////////////////////////////////////////////////////////////////////////////////////////////////////
void Constant::parseTypedDeclarations(Context &context, Domain &domain)
{
while (context.parser.currentCharacter() != ')')
parseTypedDeclaration(context, domain);
if (domain.constants().empty())
return;
// Check correct use of typing requirement
const auto typingUsed = (domain.constants().back()->type() != nullptr);
const auto typingDeclared = domain.hasRequirement(Requirement::Type::Typing);
if (!typingUsed && typingDeclared)
throw utils::ParserException(context.parser, "Constant has undeclared type");
if (typingUsed && !typingDeclared)
throw utils::ParserException(context.parser, "Typing used but not declared as a requirement");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext)
{
context.parser.skipWhiteSpace();
@ -163,20 +178,6 @@ bool Constant::isDirty() const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Constant::setDeclared()
{
m_isDeclared = true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Constant::isDeclared() const
{
return m_isDeclared;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Constant::name() const
{
return m_name;