Started implementing PDDL domain parser.
This commit is contained in:
		@@ -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}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										100
									
								
								src/plasp/pddl/Description.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/plasp/pddl/Description.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
#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);
 | 
			
		||||
 | 
			
		||||
	std::cout << "CHAR1: " << istream.peek() << std::endl;
 | 
			
		||||
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
	std::cout << "char1: " << parser.currentCharacter() << std::endl;
 | 
			
		||||
 | 
			
		||||
	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