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
#define __PLASP__PDDL__EXPRESSION__PRIMITIVE_TYPE_H
#include <plasp/pddl/ConsistencyException.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/utils/Parser.h>
@ -25,8 +26,7 @@ class PrimitiveType: public Expression
static PrimitiveType *parseDeclaration(utils::Parser &parser, Context &context);
static void parseTypedDeclaration(utils::Parser &parser, Context &context);
template<class Container>
static PrimitiveType *parseExisting(utils::Parser &parser, Container &primitiveTypes);
static PrimitiveType *parseExisting(utils::Parser &parser, Context &context);
// TODO: method for lazy creation if not existing
@ -38,6 +38,9 @@ class PrimitiveType: public Expression
bool isDeclared() const;
private:
static PrimitiveType *create(std::string name, Context &context);
private:
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;
// 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
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)
{
parser.skipWhiteSpace();
@ -49,20 +69,7 @@ PrimitiveType *PrimitiveType::parseDeclaration(utils::Parser &parser, Context &c
return type;
}
// Create new primitive type if not already existing
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();
return create(typeName, context);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -82,7 +89,7 @@ void PrimitiveType::parseTypedDeclaration(utils::Parser &parser, Context &contex
return;
// If existing, parse and store parent type
auto *parentType = parseExisting(parser, context.primitiveTypes);
auto *parentType = parseExisting(parser, context);
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
{
expressionVisitor.visit(*this);

View File

@ -18,7 +18,7 @@ namespace expressions
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;
}

View File

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