Turned exception about undeclared types into a consistency warning.

This commit is contained in:
Patrick Lühne 2016-06-04 15:04:18 +02:00
parent c93661f44e
commit feedb95295
5 changed files with 62 additions and 64 deletions

View File

@ -1,6 +1,7 @@
#ifndef __PLASP__PDDL__EXPRESSION__PRIMITIVE_TYPE_H #ifndef __PLASP__PDDL__EXPRESSION__PRIMITIVE_TYPE_H
#define __PLASP__PDDL__EXPRESSION__PRIMITIVE_TYPE_H #define __PLASP__PDDL__EXPRESSION__PRIMITIVE_TYPE_H
#include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/utils/Parser.h> #include <plasp/utils/Parser.h>
@ -25,8 +26,7 @@ class PrimitiveType: public Expression
static PrimitiveType *parseDeclaration(utils::Parser &parser, Context &context); static PrimitiveType *parseDeclaration(utils::Parser &parser, Context &context);
static void parseTypedDeclaration(utils::Parser &parser, Context &context); static void parseTypedDeclaration(utils::Parser &parser, Context &context);
template<class Container> static PrimitiveType *parseExisting(utils::Parser &parser, Context &context);
static PrimitiveType *parseExisting(utils::Parser &parser, Container &primitiveTypes);
// TODO: method for lazy creation if not existing // TODO: method for lazy creation if not existing
@ -38,6 +38,9 @@ class PrimitiveType: public Expression
bool isDeclared() const; bool isDeclared() const;
private:
static PrimitiveType *create(std::string name, Context &context);
private: private:
PrimitiveType(); PrimitiveType();
@ -56,50 +59,6 @@ class PrimitiveType: public Expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Container>
PrimitiveType *PrimitiveType::parseExisting(utils::Parser &parser,
Container &primitiveTypes)
{
parser.skipWhiteSpace();
const auto typeName = parser.parseIdentifier(isIdentifier);
BOOST_ASSERT(!typeName.empty());
// TODO: use hash map
const auto match = std::find_if(primitiveTypes.cbegin(), primitiveTypes.cend(),
[&](const auto &primitiveType)
{
return primitiveType->name() == typeName;
});
if (match == primitiveTypes.cend())
{
// Allow implicit type "object"
if (typeName == "object")
{
auto objectType = std::make_unique<PrimitiveType>(PrimitiveType());
objectType->m_name = typeName;
objectType->setDirty(false);
objectType->setDeclared();
// TODO: make std::vector-independent
primitiveTypes.emplace_back(std::move(objectType));
return primitiveTypes.back().get();
}
else
throw utils::ParserException(parser.row(), parser.column(), "Primitive type \"" + typeName + "\" used but never declared");
}
auto *type = match->get();
type->setDirty();
return type;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
} }
} }
} }

View File

@ -65,7 +65,7 @@ void Constant::parseTypedDeclaration(utils::Parser &parser, Context &context)
return; return;
// If existing, parse and store parent type // If existing, parse and store parent type
auto *type = PrimitiveType::parseExisting(parser, context.primitiveTypes); auto *type = PrimitiveType::parseExisting(parser, context);
// Assign parent type to all types that were previously flagged // Assign parent type to all types that were previously flagged
std::for_each(context.constants.begin(), context.constants.end(), std::for_each(context.constants.begin(), context.constants.end(),

View File

@ -26,6 +26,26 @@ PrimitiveType::PrimitiveType()
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveType *PrimitiveType::create(std::string name, Context &context)
{
// Create new primitive type if not already existing
auto type = std::make_unique<PrimitiveType>(PrimitiveType());
type->m_name = name;
BOOST_ASSERT(!type->m_name.empty());
// Flag type for potentially upcoming parent type declaration
type->setDirty();
// TODO: Store constant in hash map
context.primitiveTypes.emplace_back(std::move(type));
return context.primitiveTypes.back().get();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveType *PrimitiveType::parseDeclaration(utils::Parser &parser, Context &context) PrimitiveType *PrimitiveType::parseDeclaration(utils::Parser &parser, Context &context)
{ {
parser.skipWhiteSpace(); parser.skipWhiteSpace();
@ -49,20 +69,7 @@ PrimitiveType *PrimitiveType::parseDeclaration(utils::Parser &parser, Context &c
return type; return type;
} }
// Create new primitive type if not already existing return create(typeName, context);
auto type = std::make_unique<PrimitiveType>(PrimitiveType());
type->m_name = typeName;
BOOST_ASSERT(!type->m_name.empty());
// Flag type for potentially upcoming parent type declaration
type->setDirty();
// TODO: Store constant in hash map
context.primitiveTypes.emplace_back(std::move(type));
return context.primitiveTypes.back().get();
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -82,7 +89,7 @@ void PrimitiveType::parseTypedDeclaration(utils::Parser &parser, Context &contex
return; return;
// If existing, parse and store parent type // If existing, parse and store parent type
auto *parentType = parseExisting(parser, context.primitiveTypes); auto *parentType = parseExisting(parser, context);
parentType->setDirty(false); parentType->setDirty(false);
@ -103,6 +110,38 @@ void PrimitiveType::parseTypedDeclaration(utils::Parser &parser, Context &contex
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveType *PrimitiveType::parseExisting(utils::Parser &parser, Context &context)
{
parser.skipWhiteSpace();
const auto typeName = parser.parseIdentifier(isIdentifier);
BOOST_ASSERT(!typeName.empty());
// TODO: use hash map
const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(),
[&](const auto &primitiveType)
{
return primitiveType->name() == typeName;
});
if (match == context.primitiveTypes.cend())
{
// Primitive type "object" is implicitly declared
if (typeName != "object")
throw ConsistencyException("Primitive type \"" + typeName + "\" used but never declared");
return create(typeName, context);
}
auto *type = match->get();
type->setDirty();
return type;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void PrimitiveType::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const void PrimitiveType::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
{ {
expressionVisitor.visit(*this); expressionVisitor.visit(*this);

View File

@ -18,7 +18,7 @@ namespace expressions
ExpressionPointer parseExistingPrimitiveType(utils::Parser &parser, Context &context, const Variables &parameters) ExpressionPointer parseExistingPrimitiveType(utils::Parser &parser, Context &context, const Variables &parameters)
{ {
auto reference = std::make_unique<Reference<PrimitiveType>>(PrimitiveType::parseExisting(parser, context.primitiveTypes)); auto reference = std::make_unique<Reference<PrimitiveType>>(PrimitiveType::parseExisting(parser, context));
return reference; return reference;
} }

View File

@ -94,7 +94,7 @@ void Variable::parseTypedDeclaration(utils::Parser &parser, Context &context, Va
} }
// Parse primitive type // Parse primitive type
const auto *type = PrimitiveType::parseExisting(parser, context.primitiveTypes); const auto *type = PrimitiveType::parseExisting(parser, context);
setType(type); setType(type);
} }