Implemented constant type checking.
This commit is contained in:
parent
32883910bb
commit
8db4b5a53e
@ -23,6 +23,7 @@ class Constant: public Expression
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void parseTypedDeclaration(Context &context, Domain &domain);
|
static void parseTypedDeclaration(Context &context, Domain &domain);
|
||||||
|
static void parseTypedDeclarations(Context &context, Domain &domain);
|
||||||
static void parseTypedDeclaration(Context &context, Problem &problem);
|
static void parseTypedDeclaration(Context &context, Problem &problem);
|
||||||
|
|
||||||
static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext);
|
static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext);
|
||||||
@ -35,8 +36,6 @@ class Constant: public Expression
|
|||||||
const std::string &name() const;
|
const std::string &name() const;
|
||||||
const PrimitiveType *type() const;
|
const PrimitiveType *type() const;
|
||||||
|
|
||||||
bool isDeclared() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ConstantPointer parseDeclaration(Context &context);
|
static ConstantPointer parseDeclaration(Context &context);
|
||||||
static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants);
|
static void parseTypedDeclaration(Context &context, Domain &domain, Constants &constants);
|
||||||
@ -48,12 +47,9 @@ class Constant: public Expression
|
|||||||
void setDirty(bool isDirty = true);
|
void setDirty(bool isDirty = true);
|
||||||
bool isDirty() const;
|
bool isDirty() const;
|
||||||
|
|
||||||
void setDeclared();
|
|
||||||
|
|
||||||
void setType(const PrimitiveType *parentType);
|
void setType(const PrimitiveType *parentType);
|
||||||
|
|
||||||
bool m_isDirty;
|
bool m_isDirty;
|
||||||
bool m_isDeclared;
|
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
|
@ -273,12 +273,7 @@ void Domain::parseConstantSection()
|
|||||||
m_context.parser.skipWhiteSpace();
|
m_context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
// Store constants
|
// Store constants
|
||||||
while (m_context.parser.currentCharacter() != ')')
|
expressions::Constant::parseTypedDeclarations(m_context, *this);
|
||||||
{
|
|
||||||
expressions::Constant::parseTypedDeclaration(m_context, *this);
|
|
||||||
|
|
||||||
m_context.parser.skipWhiteSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_context.parser.expect<std::string>(")");
|
m_context.parser.expect<std::string>(")");
|
||||||
}
|
}
|
||||||
@ -315,17 +310,6 @@ void Domain::parseActionSection()
|
|||||||
|
|
||||||
void Domain::checkConsistency()
|
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
|
// Verify that all used predicates have been declared
|
||||||
std::for_each(m_predicateDeclarations.cbegin(), m_predicateDeclarations.cend(),
|
std::for_each(m_predicateDeclarations.cbegin(), m_predicateDeclarations.cend(),
|
||||||
[&](const auto &predicate)
|
[&](const auto &predicate)
|
||||||
|
@ -26,7 +26,6 @@ namespace expressions
|
|||||||
|
|
||||||
Constant::Constant()
|
Constant::Constant()
|
||||||
: m_isDirty{false},
|
: m_isDirty{false},
|
||||||
m_isDeclared{false},
|
|
||||||
m_type{nullptr}
|
m_type{nullptr}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -72,11 +71,6 @@ void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants
|
|||||||
// Parse and store constant
|
// Parse and store constant
|
||||||
constants.emplace_back(parseDeclaration(context));
|
constants.emplace_back(parseDeclaration(context));
|
||||||
|
|
||||||
const auto &constant = constants.back();
|
|
||||||
|
|
||||||
// Flag constant as correctly declared in the types section
|
|
||||||
constant->setDeclared();
|
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
// Check for typing information
|
// 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)
|
Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
context.parser.skipWhiteSpace();
|
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
|
const std::string &Constant::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
|
Reference in New Issue
Block a user