patrick
/
plasp
Archived
1
0
Fork 0

Implemented multi-file input.

This commit is contained in:
Patrick Lühne 2016-06-07 15:54:01 +02:00
parent 64190ba55a
commit 4228ca01dc
13 changed files with 154 additions and 51 deletions

View File

@ -16,7 +16,7 @@ int main(int argc, char **argv)
description.add_options()
("help,h", "Display this help message.")
("version,v", "Display version information.")
("input,i", po::value<std::string>(), "Specify the SAS input file.")
("input,i", po::value<std::vector<std::string>>(), "Specify the SAS input file.")
("format,f", po::value<std::string>()->default_value("SAS"), "Specify the file format (SAS or PDDL).");
po::positional_options_description positionalOptionsDescription;
@ -66,10 +66,19 @@ int main(int argc, char **argv)
auto format = variablesMap["format"].as<std::string>();
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
const auto &inputFiles = variablesMap["input"].as<std::vector<std::string>>();
if (format == "sas")
{
if (inputFiles.size() > 0)
{
std::cerr << "Error: Only one input file allowed for SAS translation" << std::endl;
printHelp();
return EXIT_FAILURE;
}
const auto sasDescription = variablesMap.count("input")
? plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>())
? plasp::sas::Description::fromFile(inputFiles.front())
: plasp::sas::Description::fromStream(std::cin);
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
sasTranslator.translate(std::cout);
@ -77,7 +86,7 @@ int main(int argc, char **argv)
else if (format == "pddl")
{
const auto pddlDescription = variablesMap.count("input")
? plasp::pddl::Description::fromFile(variablesMap["input"].as<std::string>())
? plasp::pddl::Description::fromFiles(inputFiles)
: plasp::pddl::Description::fromStream(std::cin);
//std::cout << pddlDescription << std::endl;
}

View File

@ -22,7 +22,7 @@ class Description
{
public:
static Description fromStream(std::istream &istream);
static Description fromFile(const boost::filesystem::path &path);
static Description fromFiles(const std::vector<std::string> &paths);
public:
const Domain &domain() const;

View File

@ -30,9 +30,11 @@ class Domain
bool isDeclared() const;
void setName(std::string name);
const std::string &name() const;
const Requirements &requirements() const;
bool hasRequirement(Requirement::Type requirementType) const;
expressions::PrimitiveTypes &types();
const expressions::PrimitiveTypes &types() const;
@ -52,7 +54,6 @@ class Domain
void parseSection();
void parseRequirementSection();
bool hasRequirement(Requirement::Type requirementType) const;
void computeDerivedRequirements();
void parseTypeSection();

View File

@ -44,6 +44,8 @@ class Problem
bool hasRequirement(Requirement::Type requirementType) const;
void computeDerivedRequirements();
void parseDomainSection();
void parseObjectSection();
Context &m_context;

View File

@ -21,6 +21,11 @@ class Parser
public:
explicit Parser(std::istream &istream);
void setFileName(std::string fileName);
const std::string &fileName() const;
void resetPosition();
size_t row() const;
size_t column() const;
@ -60,6 +65,7 @@ class Parser
uint64_t parseIntegerBody();
std::istream &m_istream;
std::string m_fileName;
std::istreambuf_iterator<char> m_position;
size_t m_row;
@ -67,7 +73,7 @@ class Parser
bool m_isCaseSensitive;
bool m_endOfFile;
bool m_atEndOfFile;
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -31,7 +31,7 @@ class ParserException: public std::exception
}
explicit ParserException(const utils::Parser &parser, const std::string &message)
: m_message{std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + "\t" + message}
: m_message{parser.fileName() + ":" + std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + " " + message}
{
}

View File

@ -31,7 +31,7 @@ class ParserWarning: public std::exception
}
explicit ParserWarning(const utils::Parser &parser, const std::string &message)
: m_message{std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + "\t" + message}
: m_message{parser.fileName() + ":" + std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + " " + message}
{
}

View File

@ -20,7 +20,9 @@ namespace pddl
Description::Description(std::istream &istream)
: m_parser(istream),
m_context(m_parser)
m_context(m_parser),
m_domain{std::make_unique<Domain>(Domain(m_context))},
m_problem{std::make_unique<Problem>(Problem(m_context, *m_domain))}
{
m_parser.setCaseSensitive(false);
}
@ -31,19 +33,9 @@ Description Description::fromStream(std::istream &istream)
{
Description description(istream);
description.m_domain = std::make_unique<Domain>(Domain(description.m_context));
description.m_problem = std::make_unique<Problem>(Problem(description.m_context, *description.m_domain));
while (true)
{
description.m_context.parser.skipWhiteSpace();
if (description.m_context.parser.atEndOfFile())
break;
description.parseContent();
}
description.m_parser.setFileName("std::cin");
description.parseContent();
description.checkConsistency();
return description;
@ -51,14 +43,36 @@ Description Description::fromStream(std::istream &istream)
////////////////////////////////////////////////////////////////////////////////////////////////////
Description Description::fromFile(const boost::filesystem::path &path)
Description Description::fromFiles(const std::vector<std::string> &paths)
{
if (!boost::filesystem::is_regular_file(path))
throw std::runtime_error("File does not exist: \"" + path.string() + "\"");
BOOST_ASSERT(!paths.empty());
std::ifstream fileStream(path.string(), std::ios::in);
std::for_each(paths.cbegin(), paths.cend(),
[&](const auto &path)
{
if (!boost::filesystem::is_regular_file(path))
throw std::runtime_error("File does not exist: \"" + path + "\"");
});
return Description::fromStream(fileStream);
std::ifstream fileStream;
Description description(fileStream);
std::for_each(paths.cbegin(), paths.cend(),
[&](const auto &path)
{
fileStream.close();
fileStream.clear();
fileStream.open(path, std::ios::in);
description.m_parser.setFileName(path);
description.m_parser.resetPosition();
description.parseContent();
});
description.checkConsistency();
return description;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -74,12 +88,18 @@ const Domain &Description::domain() const
void Description::parseContent()
{
std::cout << "Parsing file content" << std::endl;
while (true)
{
m_context.parser.skipWhiteSpace();
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define");
parseSection();
m_context.parser.expect<std::string>(")");
if (m_context.parser.atEndOfFile())
return;
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define");
parseSection();
m_context.parser.expect<std::string>(")");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -91,8 +111,6 @@ void Description::parseSection()
const auto sectionIdentifier = m_context.parser.parse<std::string>();
std::cout << "Parsing section " << sectionIdentifier << std::endl;
if (sectionIdentifier == "domain")
{
BOOST_ASSERT(m_domain);
@ -119,6 +137,9 @@ void Description::parseSection()
void Description::checkConsistency()
{
if (!m_domain->isDeclared())
throw ConsistencyException("No PDDL domain specified");
m_domain->checkConsistency();
m_problem->checkConsistency();
}

View File

@ -32,7 +32,13 @@ Domain::Domain(Context &context)
void Domain::readPDDL()
{
m_name = m_context.parser.parseIdentifier(isIdentifier);
const auto domainName = m_context.parser.parseIdentifier(isIdentifier);
if (m_name.empty())
m_name = domainName;
// If the domain has previously been referenced, check that the name matches
else if (m_name != domainName)
throw utils::ParserException(m_context.parser, "Domains do not match (\"" + domainName + "\" and \"" + m_name + "\")");
std::cout << "Parsing domain " << m_name << std::endl;
@ -62,6 +68,13 @@ bool Domain::isDeclared() const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::setName(std::string name)
{
m_name = name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Domain::name() const
{
return m_name;
@ -334,11 +347,22 @@ void Domain::checkConsistency()
// Verify that typing requirement is correctly declared if used
if (!m_primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
{
throw ConsistencyException("Domain contains typing information but does not declare typing requirement");
m_context.logger.parserWarning(m_context.parser, "Domain contains typing information but does not declare typing requirement");
m_requirements.push_back(Requirement(Requirement::Type::Typing));
}
// Verify that all variables and constants have types
if (hasRequirement(Requirement::Type::Typing))
{
std::for_each(m_constants.cbegin(), m_constants.cend(),
[&](const auto &constant)
{
if (constant->type() == nullptr)
throw ConsistencyException("Constant \"" + constant->name() + "\" has no type");
});
}
// Verify that all used types have been declared
std::for_each(m_primitiveTypes.cbegin(), m_primitiveTypes.cend(),
[&](const auto &type)
@ -366,7 +390,6 @@ void Domain::checkConsistency()
throw ConsistencyException("Predicate \"" + predicate->name() + "\" used but never declared");
});
// Verify that all variables have types
// Verify that constants are unique
// Verify that all primitive types are unique
// Check for case-sensitivity issues

View File

@ -2,6 +2,7 @@
#include <algorithm>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Constant.h>
#include <plasp/utils/IO.h>
@ -134,7 +135,7 @@ void Problem::parseSection()
// TODO: check order of the sections
if (sectionIdentifier == "domain")
skipSection();
parseDomainSection();
else if (sectionIdentifier == "requirements")
parseRequirementSection();
else if (sectionIdentifier == "objects")
@ -155,6 +156,23 @@ void Problem::parseSection()
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::parseDomainSection()
{
m_context.parser.skipWhiteSpace();
const auto domainName = m_context.parser.parseIdentifier(isIdentifier);
if (m_domain.isDeclared() && m_domain.name() != domainName)
throw utils::ParserException(m_context.parser, "Domains do not match (\"" + m_domain.name() + "\" and \"" + domainName + "\")");
if (!m_domain.isDeclared())
m_domain.setName(domainName);
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::parseRequirementSection()
{
m_context.parser.skipWhiteSpace();
@ -238,7 +256,7 @@ void Problem::parseObjectSection()
// Store constants
while (m_context.parser.currentCharacter() != ')')
{
//expressions::Constant::parseTypedDeclaration(m_context);
expressions::Constant::parseTypedDeclaration(m_context, *this);
m_context.parser.skipWhiteSpace();
}
@ -250,6 +268,14 @@ void Problem::parseObjectSection()
void Problem::checkConsistency()
{
// Verify that all objects have types
if (hasRequirement(Requirement::Type::Typing) || m_domain.hasRequirement(Requirement::Type::Typing))
std::for_each(m_objects.cbegin(), m_objects.cend(),
[&](const auto &constant)
{
if (constant->type() == nullptr)
throw ConsistencyException("Object \"" + constant->name() + "\" has no type");
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -61,11 +61,13 @@ void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
auto *type = match->get();
type->setDirty();
type->setDeclared();
return;
}
types.emplace_back(std::make_unique<PrimitiveType>(typeName));
types.back()->setDeclared();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -77,11 +79,6 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
// Parse and store type
parseDeclaration(context, domain);
auto *type = types.back().get();
// Flag type as correctly declared in the types section
type->setDeclared();
context.parser.skipWhiteSpace();
// Check for type inheritance
@ -129,12 +126,8 @@ PrimitiveType *PrimitiveType::parseAndFindOrCreate(Context &context, Domain &dom
if (match == types.cend())
{
// Primitive type "object" is implicitly declared
if (typeName != "object")
context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" used but never declared");
// If necessary, insert new primitive type but don't declare it
types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
types.back()->setDeclared();
return types.back().get();
}

View File

@ -32,7 +32,7 @@ void Logger::parserWarning(const Parser &parser, const std::string &text)
if (m_isPedantic)
throw ParserWarning(parser, text);
std::cerr << "Warning: " << parser.row() << ":" << parser.column() << "\t" << text << std::endl;
std::cerr << "Warning: " << parser.fileName() << ":" << parser.row() << ":" << parser.column() << " " << text << std::endl;
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -27,14 +27,36 @@ Parser::Parser(std::istream &istream)
m_row{1},
m_column{1},
m_isCaseSensitive{true},
m_endOfFile{false}
m_atEndOfFile{false}
{
std::setlocale(LC_NUMERIC, "C");
// Dont skip whitespace
istream.exceptions(std::istream::badbit);
}
checkStream();
////////////////////////////////////////////////////////////////////////////////////////////////////
void Parser::setFileName(std::string fileName)
{
m_fileName = fileName;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &Parser::fileName() const
{
return m_fileName;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Parser::resetPosition()
{
m_row = 1;
m_column = 1;
m_atEndOfFile = false;
m_position = std::istreambuf_iterator<char>(m_istream);
}
////////////////////////////////////////////////////////////////////////////////////////////////////