Started implementing PDDL domain parser.
This commit is contained in:
parent
42fda5925d
commit
40547691a0
@ -1,7 +1,10 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <plasp/pddl/Description.h>
|
||||
#include <plasp/sas/Description.h>
|
||||
#include <plasp/sas/TranslatorASP.h>
|
||||
|
||||
@ -13,7 +16,8 @@ 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::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;
|
||||
positionalOptionsDescription.add("input", -1);
|
||||
@ -59,11 +63,24 @@ int main(int argc, char **argv)
|
||||
|
||||
try
|
||||
{
|
||||
const auto sasDescription = variablesMap.count("input")
|
||||
? plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>())
|
||||
: plasp::sas::Description::fromStream(std::cin);
|
||||
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
|
||||
sasTranslator.translate(std::cout);
|
||||
auto format = variablesMap["format"].as<std::string>();
|
||||
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
|
||||
|
||||
if (format == "sas")
|
||||
{
|
||||
const auto sasDescription = variablesMap.count("input")
|
||||
? plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>())
|
||||
: plasp::sas::Description::fromStream(std::cin);
|
||||
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
|
||||
sasTranslator.translate(std::cout);
|
||||
}
|
||||
else if (format == "pddl")
|
||||
{
|
||||
const auto pddlDescription = variablesMap.count("input")
|
||||
? plasp::pddl::Description::fromFile(variablesMap["input"].as<std::string>())
|
||||
: plasp::pddl::Description::fromStream(std::cin);
|
||||
//std::cout << pddlDescription << std::endl;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
|
43
include/plasp/pddl/Description.h
Normal file
43
include/plasp/pddl/Description.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef __PLASP__PDDL__DESCRIPTION_H
|
||||
#define __PLASP__PDDL__DESCRIPTION_H
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/utils/Parser.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Description
|
||||
{
|
||||
public:
|
||||
static Description fromStream(std::istream &istream);
|
||||
static Description fromFile(const boost::filesystem::path &path);
|
||||
|
||||
public:
|
||||
|
||||
private:
|
||||
Description() = default;
|
||||
|
||||
void parseContent(utils::Parser &parser);
|
||||
void parseSection(utils::Parser &parser);
|
||||
|
||||
std::unique_ptr<Domain> m_domain;
|
||||
//std::unique_ptr<Problem> m_problem;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
35
include/plasp/pddl/Domain.h
Normal file
35
include/plasp/pddl/Domain.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __PLASP__PDDL__DOMAIN_H
|
||||
#define __PLASP__PDDL__DOMAIN_H
|
||||
|
||||
#include <plasp/utils/Parser.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Domain
|
||||
{
|
||||
public:
|
||||
static Domain fromPDDL(utils::Parser &parser);
|
||||
|
||||
private:
|
||||
Domain() = default;
|
||||
|
||||
void parseSection(utils::Parser &parser);
|
||||
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
32
include/plasp/pddl/Identifier.h
Normal file
32
include/plasp/pddl/Identifier.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __PLASP__PDDL__IDENTIFIER_H
|
||||
#define __PLASP__PDDL__IDENTIFIER_H
|
||||
|
||||
#include <cctype>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Identifier
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const auto isIdentifier =
|
||||
[](const auto character)
|
||||
{
|
||||
return character != '?'
|
||||
&& character != '('
|
||||
&& character != ')'
|
||||
&& character != ';'
|
||||
&& std::isgraph(character);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -28,12 +28,17 @@ class Parser
|
||||
size_t column() const;
|
||||
|
||||
CharacterType currentCharacter() const;
|
||||
void advance();
|
||||
bool atEndOfFile() const;
|
||||
|
||||
template<typename Type>
|
||||
Type parse();
|
||||
|
||||
template<class WhiteSpacePredicate, class CharacterPredicate>
|
||||
std::string parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate);
|
||||
template<class CharacterPredicate, class WhiteSpacePredicate>
|
||||
std::string parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate);
|
||||
|
||||
template<class CharacterPredicate>
|
||||
std::string parseIdentifier(CharacterPredicate characterPredicate);
|
||||
|
||||
template<typename Type>
|
||||
void expect(const Type &expectedValue);
|
||||
@ -51,7 +56,6 @@ class Parser
|
||||
|
||||
private:
|
||||
void checkStream() const;
|
||||
void advance();
|
||||
|
||||
bool advanceIf(CharacterType expectedCharacter);
|
||||
|
||||
@ -68,8 +72,8 @@ class Parser
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class WhiteSpacePredicate, class CharacterPredicate>
|
||||
std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate)
|
||||
template<class CharacterPredicate, class WhiteSpacePredicate>
|
||||
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate)
|
||||
{
|
||||
skipWhiteSpace(whiteSpacePredicate);
|
||||
|
||||
@ -89,12 +93,24 @@ std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, Cha
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class CharacterPredicate>
|
||||
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate)
|
||||
{
|
||||
return parseIdentifier(characterPredicate,
|
||||
[&](const auto character)
|
||||
{
|
||||
return std::isspace(character);
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class WhiteSpacePredicate>
|
||||
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
|
||||
{
|
||||
checkStream();
|
||||
|
||||
while (whiteSpacePredicate(*m_position))
|
||||
while (m_position != EndOfFile && whiteSpacePredicate(*m_position))
|
||||
advance();
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,9 @@ set(target plasp)
|
||||
file(GLOB core_sources "plasp/*.cpp")
|
||||
file(GLOB core_headers "../include/plasp/*.h")
|
||||
|
||||
file(GLOB pddl_sources "plasp/pddl/*.cpp")
|
||||
file(GLOB pddl_headers "../include/plasp/pddl/*.h")
|
||||
|
||||
file(GLOB sas_sources "plasp/sas/*.cpp")
|
||||
file(GLOB sas_headers "../include/plasp/sas/*.h")
|
||||
|
||||
@ -21,6 +24,9 @@ set(sources
|
||||
${core_sources}
|
||||
${core_headers}
|
||||
|
||||
${pddl_sources}
|
||||
${pddl_headers}
|
||||
|
||||
${sas_sources}
|
||||
${sas_headers}
|
||||
|
||||
|
87
src/plasp/pddl/Description.cpp
Normal file
87
src/plasp/pddl/Description.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include <plasp/pddl/Description.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <plasp/utils/ParserException.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Description
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Description Description::fromStream(std::istream &istream)
|
||||
{
|
||||
Description description;
|
||||
|
||||
utils::Parser parser(istream);
|
||||
|
||||
while (true)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
if (parser.atEndOfFile())
|
||||
break;
|
||||
|
||||
description.parseContent(parser);
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Description Description::fromFile(const boost::filesystem::path &path)
|
||||
{
|
||||
if (!boost::filesystem::is_regular_file(path))
|
||||
throw std::runtime_error("File does not exist: \"" + path.string() + "\"");
|
||||
|
||||
std::ifstream fileStream(path.string(), std::ios::in);
|
||||
|
||||
return Description::fromStream(fileStream);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Description::parseContent(utils::Parser &parser)
|
||||
{
|
||||
std::cout << "Parsing file content" << std::endl;
|
||||
|
||||
parser.expect<std::string>("(define");
|
||||
parseSection(parser);
|
||||
parser.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Description::parseSection(utils::Parser &parser)
|
||||
{
|
||||
// Parse domain/problem identifier
|
||||
parser.expect<std::string>("(");
|
||||
|
||||
const auto sectionIdentifier = parser.parse<std::string>();
|
||||
|
||||
std::cout << "Parsing section " << sectionIdentifier << std::endl;
|
||||
|
||||
if (sectionIdentifier == "domain")
|
||||
m_domain = std::make_unique<Domain>(Domain::fromPDDL(parser));
|
||||
//else if (sectionIdentifier == "problem")
|
||||
// m_problem = std::make_unique<Problem>(Problem::fromPDDL(parser));
|
||||
else
|
||||
throw utils::ParserException(parser.row(), parser.column(), "Unknown PDDL section \"" + sectionIdentifier + "\"");
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
92
src/plasp/pddl/Domain.cpp
Normal file
92
src/plasp/pddl/Domain.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include <plasp/pddl/Domain.h>
|
||||
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Domain
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Domain Domain::fromPDDL(utils::Parser &parser)
|
||||
{
|
||||
Domain domain;
|
||||
|
||||
domain.m_name = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
std::cout << "Parsing domain " << domain.m_name << std::endl;
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
|
||||
while (true)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
std::cout << parser.currentCharacter() << std::endl;
|
||||
|
||||
if (parser.currentCharacter() == ')')
|
||||
break;
|
||||
|
||||
domain.parseSection(parser);
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parseSection(utils::Parser &parser)
|
||||
{
|
||||
parser.expect<std::string>("(:");
|
||||
|
||||
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
const auto skipSection =
|
||||
[&]()
|
||||
{
|
||||
std::cout << "Skipping section " << sectionIdentifier << std::endl;
|
||||
|
||||
size_t openParentheses = 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
const auto character = parser.currentCharacter();
|
||||
parser.advance();
|
||||
|
||||
if (character == '(')
|
||||
openParentheses++;
|
||||
else if (character == ')')
|
||||
{
|
||||
openParentheses--;
|
||||
|
||||
if (openParentheses == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (sectionIdentifier == "requirements")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "types")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "constants")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "predicates")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "functions")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "constraints")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "action")
|
||||
skipSection();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -63,6 +63,13 @@ Parser::CharacterType Parser::currentCharacter() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Parser::atEndOfFile() const
|
||||
{
|
||||
return m_position == EndOfFile;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Parser::checkStream() const
|
||||
{
|
||||
if (m_position == EndOfFile)
|
||||
|
Reference in New Issue
Block a user