Refactored basic parsing.
This commit is contained in:
		@@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/Value.h>
 | 
			
		||||
#include <plasp/sas/Variable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -26,8 +27,8 @@ using AssignedVariables = std::vector<AssignedVariable>;
 | 
			
		||||
class AssignedVariable
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static AssignedVariable fromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static AssignedVariable fromSAS(std::istream &istream, const Variable &variable);
 | 
			
		||||
		static AssignedVariable fromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
		static AssignedVariable fromSAS(utils::Parser &parser, const Variable &variable);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		explicit AssignedVariable(const Variable &variable, const Value &value);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/AssignedVariable.h>
 | 
			
		||||
#include <plasp/sas/Variable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -28,7 +29,7 @@ class AxiomRule
 | 
			
		||||
		using Condition = AssignedVariable;
 | 
			
		||||
		using Conditions = AssignedVariables;
 | 
			
		||||
 | 
			
		||||
		static AxiomRule fromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static AxiomRule fromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const Conditions &conditions() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
#include <plasp/sas/MutexGroup.h>
 | 
			
		||||
#include <plasp/sas/Operator.h>
 | 
			
		||||
#include <plasp/sas/Variable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -46,14 +47,14 @@ class Description
 | 
			
		||||
	private:
 | 
			
		||||
		Description();
 | 
			
		||||
 | 
			
		||||
		void parseVersionSection(std::istream &istream) const;
 | 
			
		||||
		void parseMetricSection(std::istream &istream);
 | 
			
		||||
		void parseVariablesSection(std::istream &istream);
 | 
			
		||||
		void parseMutexSection(std::istream &istream);
 | 
			
		||||
		void parseInitialStateSection(std::istream &istream);
 | 
			
		||||
		void parseGoalSection(std::istream &istream);
 | 
			
		||||
		void parseOperatorSection(std::istream &istream);
 | 
			
		||||
		void parseAxiomSection(std::istream &istream);
 | 
			
		||||
		void parseVersionSection(utils::Parser &parser) const;
 | 
			
		||||
		void parseMetricSection(utils::Parser &parser);
 | 
			
		||||
		void parseVariablesSection(utils::Parser &parser);
 | 
			
		||||
		void parseMutexSection(utils::Parser &parser);
 | 
			
		||||
		void parseInitialStateSection(utils::Parser &parser);
 | 
			
		||||
		void parseGoalSection(utils::Parser &parser);
 | 
			
		||||
		void parseOperatorSection(utils::Parser &parser);
 | 
			
		||||
		void parseAxiomSection(utils::Parser &parser);
 | 
			
		||||
 | 
			
		||||
		bool m_usesActionCosts;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/AssignedVariable.h>
 | 
			
		||||
#include <plasp/sas/Variable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -28,7 +29,7 @@ class Effect
 | 
			
		||||
		using Condition = AssignedVariable;
 | 
			
		||||
		using Conditions = AssignedVariables;
 | 
			
		||||
 | 
			
		||||
		static Effect fromSAS(std::istream &istream, const Variables &variables, Conditions &preconditions);
 | 
			
		||||
		static Effect fromSAS(utils::Parser &parser, const Variables &variables, Conditions &preconditions);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const Conditions &conditions() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
#define __PLASP__SAS__GOAL_H
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/AssignedVariable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -20,7 +21,7 @@ class Goal
 | 
			
		||||
		using Fact = AssignedVariable;
 | 
			
		||||
		using Facts = AssignedVariables;
 | 
			
		||||
 | 
			
		||||
		static Goal fromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static Goal fromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const Facts &facts() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
#define __PLASP__SAS__INITIAL_STATE_H
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/AssignedVariable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -20,7 +21,7 @@ class InitialState
 | 
			
		||||
		using Fact = AssignedVariable;
 | 
			
		||||
		using Facts = AssignedVariables;
 | 
			
		||||
 | 
			
		||||
		static InitialState fromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static InitialState fromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const Facts &facts() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/AssignedVariable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -27,7 +28,7 @@ class MutexGroup
 | 
			
		||||
		using Fact = AssignedVariable;
 | 
			
		||||
		using Facts = AssignedVariables;
 | 
			
		||||
 | 
			
		||||
		static MutexGroup fromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static MutexGroup fromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const Facts &facts() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@
 | 
			
		||||
#include <plasp/sas/Effect.h>
 | 
			
		||||
#include <plasp/sas/Predicate.h>
 | 
			
		||||
#include <plasp/sas/Variable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -31,7 +32,7 @@ class Operator
 | 
			
		||||
		using Condition = AssignedVariable;
 | 
			
		||||
		using Conditions = AssignedVariables;
 | 
			
		||||
 | 
			
		||||
		static Operator fromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static Operator fromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		void printPredicateAsASP(std::ostream &ostream) const;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace sas
 | 
			
		||||
@@ -19,7 +21,7 @@ namespace sas
 | 
			
		||||
class Predicate
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static Predicate fromSAS(std::istream &istream);
 | 
			
		||||
		static Predicate fromSAS(utils::Parser &parser);
 | 
			
		||||
 | 
			
		||||
		using Arguments = std::vector<std::string>;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace sas
 | 
			
		||||
@@ -36,8 +38,8 @@ struct Value
 | 
			
		||||
		static const Value Any;
 | 
			
		||||
		static const Value None;
 | 
			
		||||
 | 
			
		||||
		static Value fromSAS(std::istream &istream);
 | 
			
		||||
		static const Value &referenceFromSAS(std::istream &istream, const Variable &variable);
 | 
			
		||||
		static Value fromSAS(utils::Parser &parser);
 | 
			
		||||
		static const Value &referenceFromSAS(utils::Parser &parser, const Variable &variable);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		Value negated() const;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/Value.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -26,8 +27,8 @@ using Variables = std::vector<Variable>;
 | 
			
		||||
class Variable
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static Variable fromSAS(std::istream &istream);
 | 
			
		||||
		static const Variable &referenceFromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static Variable fromSAS(utils::Parser &parser);
 | 
			
		||||
		static const Variable &referenceFromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		void printNameAsASPPredicate(std::ostream &ostream) const;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/Value.h>
 | 
			
		||||
#include <plasp/sas/Variable.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -25,7 +26,7 @@ using VariableTransitions = std::vector<VariableTransition>;
 | 
			
		||||
class VariableTransition
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		static VariableTransition fromSAS(std::istream &istream, const Variables &variables);
 | 
			
		||||
		static VariableTransition fromSAS(utils::Parser &parser, const Variables &variables);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		const Variable &variable() const;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								include/plasp/utils/IO.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								include/plasp/utils/IO.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#ifndef __PLASP__UTILS__IO_H
 | 
			
		||||
#define __PLASP__UTILS__IO_H
 | 
			
		||||
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace utils
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// IO
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
inline std::string escapeASP(const std::string &string)
 | 
			
		||||
{
 | 
			
		||||
	auto escaped = string;
 | 
			
		||||
 | 
			
		||||
	boost::replace_all(escaped, "_", "__");
 | 
			
		||||
	boost::replace_all(escaped, "-", "_h");
 | 
			
		||||
	boost::replace_all(escaped, "@", "_a");
 | 
			
		||||
 | 
			
		||||
	return escaped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
inline std::string unescapeASP(const std::string &string)
 | 
			
		||||
{
 | 
			
		||||
	auto unescaped = string;
 | 
			
		||||
 | 
			
		||||
	boost::replace_all(unescaped, "_a", "@");
 | 
			
		||||
	boost::replace_all(unescaped, "_h", "-");
 | 
			
		||||
	boost::replace_all(unescaped, "__", "_");
 | 
			
		||||
 | 
			
		||||
	return unescaped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										62
									
								
								include/plasp/utils/Parser.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								include/plasp/utils/Parser.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#ifndef __PLASP__UTILS__PARSER_H
 | 
			
		||||
#define __PLASP__UTILS__PARSER_H
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iterator>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace utils
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Parser
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
class Parser
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		Parser(std::istream &istream);
 | 
			
		||||
 | 
			
		||||
		size_t row() const;
 | 
			
		||||
		size_t column() const;
 | 
			
		||||
 | 
			
		||||
		template<typename T>
 | 
			
		||||
		T parse();
 | 
			
		||||
 | 
			
		||||
		template<typename T>
 | 
			
		||||
		void expect(const T &expectedValue);
 | 
			
		||||
 | 
			
		||||
		void skipWhiteSpace();
 | 
			
		||||
		void skipLine();
 | 
			
		||||
 | 
			
		||||
		std::string getLine();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		static const std::istream_iterator<unsigned char> EndOfFile;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void checkStream() const;
 | 
			
		||||
		void advance();
 | 
			
		||||
 | 
			
		||||
		bool advanceIf(unsigned char expectedCharacter);
 | 
			
		||||
 | 
			
		||||
		uint64_t parseIntegerBody();
 | 
			
		||||
 | 
			
		||||
		std::istream &m_istream;
 | 
			
		||||
		std::istream_iterator<unsigned char> m_position;
 | 
			
		||||
 | 
			
		||||
		size_t m_row;
 | 
			
		||||
		size_t m_column;
 | 
			
		||||
 | 
			
		||||
		bool m_endOfFile;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -18,17 +18,18 @@ namespace utils
 | 
			
		||||
class ParserException: public std::exception
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		explicit ParserException()
 | 
			
		||||
		explicit ParserException(size_t row, size_t column)
 | 
			
		||||
		:	ParserException(row, column, "Unspecified parser error")
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		explicit ParserException(const char *message)
 | 
			
		||||
		:	m_message(message)
 | 
			
		||||
		explicit ParserException(size_t row, size_t column, const char *message)
 | 
			
		||||
		:	ParserException(row, column, static_cast<std::string>(message))
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		explicit ParserException(const std::string &message)
 | 
			
		||||
		:	m_message(message)
 | 
			
		||||
		explicit ParserException(size_t row, size_t column, const std::string &message)
 | 
			
		||||
		:	m_message{std::to_string(row) + ":" + std::to_string(column) + "\t" + message}
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -39,7 +40,7 @@ class ParserException: public std::exception
 | 
			
		||||
		const char *what() const throw()
 | 
			
		||||
		{
 | 
			
		||||
			if (m_message.empty())
 | 
			
		||||
				return "Unspecified error while parsing SAS description file";
 | 
			
		||||
				return "Unspecified parser error";
 | 
			
		||||
 | 
			
		||||
			return m_message.c_str();
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,91 +0,0 @@
 | 
			
		||||
#ifndef __PLASP__UTILS__PARSING_H
 | 
			
		||||
#define __PLASP__UTILS__PARSING_H
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <exception>
 | 
			
		||||
#include <iosfwd>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace utils
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Parsing
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
T parse(std::istream &istream)
 | 
			
		||||
{
 | 
			
		||||
	T value;
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		istream >> value;
 | 
			
		||||
	}
 | 
			
		||||
	catch (const std::exception &e)
 | 
			
		||||
	{
 | 
			
		||||
		throw ParserException(std::string("Could not parse value of type ") + typeid(T).name() + " (" + e.what() + ")");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
void parseExpected(std::istream &istream, const T &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	const auto value = parse<T>(istream);
 | 
			
		||||
 | 
			
		||||
	if (value == expectedValue)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	std::stringstream errorStream;
 | 
			
		||||
 | 
			
		||||
	errorStream << "Invalid format, expected " << expectedValue << ", got " + value;
 | 
			
		||||
 | 
			
		||||
	throw utils::ParserException(errorStream.str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
inline std::string escapeASP(const std::string &string)
 | 
			
		||||
{
 | 
			
		||||
	auto escaped = string;
 | 
			
		||||
 | 
			
		||||
	boost::replace_all(escaped, "_", "__");
 | 
			
		||||
	boost::replace_all(escaped, "-", "_h");
 | 
			
		||||
	boost::replace_all(escaped, "@", "_a");
 | 
			
		||||
 | 
			
		||||
	return escaped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
inline std::string unescapeASP(const std::string &string)
 | 
			
		||||
{
 | 
			
		||||
	auto unescaped = string;
 | 
			
		||||
 | 
			
		||||
	boost::replace_all(unescaped, "_a", "@");
 | 
			
		||||
	boost::replace_all(unescaped, "_h", "-");
 | 
			
		||||
	boost::replace_all(unescaped, "__", "_");
 | 
			
		||||
 | 
			
		||||
	return unescaped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -4,8 +4,6 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace sas
 | 
			
		||||
@@ -33,24 +31,24 @@ AssignedVariable::AssignedVariable(const Variable &variable, const Value &value)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
AssignedVariable AssignedVariable::fromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
AssignedVariable AssignedVariable::fromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	AssignedVariable assignedVariable;
 | 
			
		||||
 | 
			
		||||
	assignedVariable.m_variable = &Variable::referenceFromSAS(istream, variables);
 | 
			
		||||
	assignedVariable.m_value = &Value::referenceFromSAS(istream, *assignedVariable.m_variable);
 | 
			
		||||
	assignedVariable.m_variable = &Variable::referenceFromSAS(parser, variables);
 | 
			
		||||
	assignedVariable.m_value = &Value::referenceFromSAS(parser, *assignedVariable.m_variable);
 | 
			
		||||
 | 
			
		||||
	return assignedVariable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
AssignedVariable AssignedVariable::fromSAS(std::istream &istream, const Variable &variable)
 | 
			
		||||
AssignedVariable AssignedVariable::fromSAS(utils::Parser &parser, const Variable &variable)
 | 
			
		||||
{
 | 
			
		||||
	AssignedVariable assignedVariable;
 | 
			
		||||
 | 
			
		||||
	assignedVariable.m_variable = &variable;
 | 
			
		||||
	assignedVariable.m_value = &Value::referenceFromSAS(istream, *assignedVariable.m_variable);
 | 
			
		||||
	assignedVariable.m_value = &Value::referenceFromSAS(parser, *assignedVariable.m_variable);
 | 
			
		||||
 | 
			
		||||
	return assignedVariable;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/VariableTransition.h>
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -24,24 +23,24 @@ AxiomRule::AxiomRule(AxiomRule::Conditions conditions, AxiomRule::Condition post
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
AxiomRule AxiomRule::fromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
AxiomRule AxiomRule::fromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_rule");
 | 
			
		||||
	parser.expect<std::string>("begin_rule");
 | 
			
		||||
 | 
			
		||||
	const auto numberOfConditions = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfConditions = parser.parse<size_t>();
 | 
			
		||||
 | 
			
		||||
	Conditions conditions;
 | 
			
		||||
	conditions.reserve(numberOfConditions);
 | 
			
		||||
 | 
			
		||||
	for (size_t j = 0; j < numberOfConditions; j++)
 | 
			
		||||
		conditions.emplace_back(Condition::fromSAS(istream, variables));
 | 
			
		||||
		conditions.emplace_back(Condition::fromSAS(parser, variables));
 | 
			
		||||
 | 
			
		||||
	const auto variableTransition = VariableTransition::fromSAS(istream, variables);
 | 
			
		||||
	const auto variableTransition = VariableTransition::fromSAS(parser, variables);
 | 
			
		||||
 | 
			
		||||
	if (&variableTransition.valueBefore() != &Value::Any)
 | 
			
		||||
		conditions.emplace_back(Condition(variableTransition.variable(), variableTransition.valueBefore()));
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_rule");
 | 
			
		||||
	parser.expect<std::string>("end_rule");
 | 
			
		||||
 | 
			
		||||
	const Condition postcondition(variableTransition.variable(), variableTransition.valueAfter());
 | 
			
		||||
	const AxiomRule axiomRule(std::move(conditions), std::move(postcondition));
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,6 @@
 | 
			
		||||
#include <boost/filesystem.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
#include <plasp/sas/VariableTransition.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
@@ -33,18 +32,16 @@ Description Description::fromStream(std::istream &istream)
 | 
			
		||||
{
 | 
			
		||||
	Description description;
 | 
			
		||||
 | 
			
		||||
	std::setlocale(LC_NUMERIC, "C");
 | 
			
		||||
	utils::Parser parser(istream);
 | 
			
		||||
 | 
			
		||||
	istream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
 | 
			
		||||
 | 
			
		||||
	description.parseVersionSection(istream);
 | 
			
		||||
	description.parseMetricSection(istream);
 | 
			
		||||
	description.parseVariablesSection(istream);
 | 
			
		||||
	description.parseMutexSection(istream);
 | 
			
		||||
	description.parseInitialStateSection(istream);
 | 
			
		||||
	description.parseGoalSection(istream);
 | 
			
		||||
	description.parseOperatorSection(istream);
 | 
			
		||||
	description.parseAxiomSection(istream);
 | 
			
		||||
	description.parseVersionSection(parser);
 | 
			
		||||
	description.parseMetricSection(parser);
 | 
			
		||||
	description.parseVariablesSection(parser);
 | 
			
		||||
	description.parseMutexSection(parser);
 | 
			
		||||
	description.parseInitialStateSection(parser);
 | 
			
		||||
	description.parseGoalSection(parser);
 | 
			
		||||
	description.parseOperatorSection(parser);
 | 
			
		||||
	description.parseAxiomSection(parser);
 | 
			
		||||
 | 
			
		||||
	return description;
 | 
			
		||||
}
 | 
			
		||||
@@ -149,85 +146,85 @@ bool Description::usesConditionalEffects() const
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseVersionSection(std::istream &istream) const
 | 
			
		||||
void Description::parseVersionSection(utils::Parser &parser) const
 | 
			
		||||
{
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_version");
 | 
			
		||||
	parser.expect<std::string>("begin_version");
 | 
			
		||||
 | 
			
		||||
	const auto formatVersion = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto formatVersion = parser.parse<size_t>();
 | 
			
		||||
 | 
			
		||||
	if (formatVersion != 3)
 | 
			
		||||
		throw utils::ParserException("Unsupported SAS format version (" + std::to_string(formatVersion) + ")");
 | 
			
		||||
		throw utils::ParserException(parser.row(), parser.column(), "Unsupported SAS format version (" + std::to_string(formatVersion) + ")");
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_version");
 | 
			
		||||
	parser.expect<std::string>("end_version");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseMetricSection(std::istream &istream)
 | 
			
		||||
void Description::parseMetricSection(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_metric");
 | 
			
		||||
	parser.expect<std::string>("begin_metric");
 | 
			
		||||
 | 
			
		||||
	m_usesActionCosts = utils::parse<bool>(istream);
 | 
			
		||||
	m_usesActionCosts = parser.parse<bool>();
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_metric");
 | 
			
		||||
	parser.expect<std::string>("end_metric");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseVariablesSection(std::istream &istream)
 | 
			
		||||
void Description::parseVariablesSection(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	const auto numberOfVariables = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfVariables = parser.parse<size_t>();
 | 
			
		||||
	m_variables.reserve(numberOfVariables);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < numberOfVariables; i++)
 | 
			
		||||
		m_variables.emplace_back(Variable::fromSAS(istream));
 | 
			
		||||
		m_variables.emplace_back(Variable::fromSAS(parser));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseMutexSection(std::istream &istream)
 | 
			
		||||
void Description::parseMutexSection(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	const auto numberOfMutexGroups = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfMutexGroups = parser.parse<size_t>();
 | 
			
		||||
	m_mutexGroups.reserve(numberOfMutexGroups);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < numberOfMutexGroups; i++)
 | 
			
		||||
		m_mutexGroups.emplace_back(MutexGroup::fromSAS(istream, m_variables));
 | 
			
		||||
		m_mutexGroups.emplace_back(MutexGroup::fromSAS(parser, m_variables));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseInitialStateSection(std::istream &istream)
 | 
			
		||||
void Description::parseInitialStateSection(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	m_initialState = std::make_unique<InitialState>(InitialState::fromSAS(istream, m_variables));
 | 
			
		||||
	m_initialState = std::make_unique<InitialState>(InitialState::fromSAS(parser, m_variables));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseGoalSection(std::istream &istream)
 | 
			
		||||
void Description::parseGoalSection(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	m_goal = std::make_unique<Goal>(Goal::fromSAS(istream, m_variables));
 | 
			
		||||
	m_goal = std::make_unique<Goal>(Goal::fromSAS(parser, m_variables));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseOperatorSection(std::istream &istream)
 | 
			
		||||
void Description::parseOperatorSection(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	const auto numberOfOperators = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfOperators = parser.parse<size_t>();
 | 
			
		||||
	m_operators.reserve(numberOfOperators);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < numberOfOperators; i++)
 | 
			
		||||
		m_operators.emplace_back(Operator::fromSAS(istream, m_variables));
 | 
			
		||||
		m_operators.emplace_back(Operator::fromSAS(parser, m_variables));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Description::parseAxiomSection(std::istream &istream)
 | 
			
		||||
void Description::parseAxiomSection(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	const auto numberOfAxiomRules = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfAxiomRules = parser.parse<size_t>();
 | 
			
		||||
	m_axiomRules.reserve(numberOfAxiomRules);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < numberOfAxiomRules; i++)
 | 
			
		||||
		m_axiomRules.emplace_back(AxiomRule::fromSAS(istream, m_variables));
 | 
			
		||||
		m_axiomRules.emplace_back(AxiomRule::fromSAS(parser, m_variables));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/VariableTransition.h>
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -24,17 +23,17 @@ Effect::Effect(Conditions conditions, Condition postcondition)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Effect Effect::fromSAS(std::istream &istream, const Variables &variables, Conditions &preconditions)
 | 
			
		||||
Effect Effect::fromSAS(utils::Parser &parser, const Variables &variables, Conditions &preconditions)
 | 
			
		||||
{
 | 
			
		||||
	Effect::Conditions conditions;
 | 
			
		||||
 | 
			
		||||
	const auto numberOfEffectConditions = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfEffectConditions = parser.parse<size_t>();
 | 
			
		||||
	conditions.reserve(numberOfEffectConditions);
 | 
			
		||||
 | 
			
		||||
	for (size_t k = 0; k < numberOfEffectConditions; k++)
 | 
			
		||||
		conditions.emplace_back(Condition::fromSAS(istream, variables));
 | 
			
		||||
		conditions.emplace_back(Condition::fromSAS(parser, variables));
 | 
			
		||||
 | 
			
		||||
	const auto variableTransition = VariableTransition::fromSAS(istream, variables);
 | 
			
		||||
	const auto variableTransition = VariableTransition::fromSAS(parser, variables);
 | 
			
		||||
 | 
			
		||||
	if (&variableTransition.valueBefore() != &Value::Any)
 | 
			
		||||
		preconditions.emplace_back(Condition(variableTransition.variable(), variableTransition.valueBefore()));
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,6 @@
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace sas
 | 
			
		||||
@@ -15,19 +13,19 @@ namespace sas
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Goal Goal::fromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
Goal Goal::fromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	Goal goal;
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_goal");
 | 
			
		||||
	parser.expect<std::string>("begin_goal");
 | 
			
		||||
 | 
			
		||||
	const auto numberOfGoalFacts = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfGoalFacts = parser.parse<size_t>();
 | 
			
		||||
	goal.m_facts.reserve(numberOfGoalFacts);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < numberOfGoalFacts; i++)
 | 
			
		||||
		goal.m_facts.emplace_back(Fact::fromSAS(istream, variables));
 | 
			
		||||
		goal.m_facts.emplace_back(Fact::fromSAS(parser, variables));
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_goal");
 | 
			
		||||
	parser.expect<std::string>("end_goal");
 | 
			
		||||
 | 
			
		||||
	return goal;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,6 @@
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace sas
 | 
			
		||||
@@ -15,18 +13,18 @@ namespace sas
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
InitialState InitialState::fromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
InitialState InitialState::fromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	InitialState initialState;
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_state");
 | 
			
		||||
	parser.expect<std::string>("begin_state");
 | 
			
		||||
 | 
			
		||||
	initialState.m_facts.reserve(variables.size());
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < variables.size(); i++)
 | 
			
		||||
		initialState.m_facts.emplace_back(Fact::fromSAS(istream, variables[i]));
 | 
			
		||||
		initialState.m_facts.emplace_back(Fact::fromSAS(parser, variables[i]));
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_state");
 | 
			
		||||
	parser.expect<std::string>("end_state");
 | 
			
		||||
 | 
			
		||||
	return initialState;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -15,24 +15,24 @@ namespace sas
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
MutexGroup MutexGroup::fromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
MutexGroup MutexGroup::fromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	MutexGroup mutexGroup;
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_mutex_group");
 | 
			
		||||
	parser.expect<std::string>("begin_mutex_group");
 | 
			
		||||
 | 
			
		||||
	const auto numberOfFacts = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfFacts = parser.parse<size_t>();
 | 
			
		||||
	mutexGroup.m_facts.reserve(numberOfFacts);
 | 
			
		||||
 | 
			
		||||
	for (size_t j = 0; j < numberOfFacts; j++)
 | 
			
		||||
	{
 | 
			
		||||
		mutexGroup.m_facts.emplace_back(Fact::fromSAS(istream, variables));
 | 
			
		||||
		mutexGroup.m_facts.emplace_back(Fact::fromSAS(parser, variables));
 | 
			
		||||
 | 
			
		||||
		if (mutexGroup.m_facts[j].value() == Value::None)
 | 
			
		||||
			throw utils::ParserException("Mutex groups must not contain <none of those> values");
 | 
			
		||||
			throw utils::ParserException(parser.row(), parser.column(), "Mutex groups must not contain <none of those> values");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_mutex_group");
 | 
			
		||||
	parser.expect<std::string>("end_mutex_group");
 | 
			
		||||
 | 
			
		||||
	return mutexGroup;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@
 | 
			
		||||
#include <limits>
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/VariableTransition.h>
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -17,29 +16,29 @@ namespace sas
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Operator Operator::fromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
Operator Operator::fromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	Operator operator_;
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_operator");
 | 
			
		||||
	parser.expect<std::string>("begin_operator");
 | 
			
		||||
 | 
			
		||||
	operator_.m_predicate = Predicate::fromSAS(istream);
 | 
			
		||||
	operator_.m_predicate = Predicate::fromSAS(parser);
 | 
			
		||||
 | 
			
		||||
	const auto numberOfPrevailConditions = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfPrevailConditions = parser.parse<size_t>();
 | 
			
		||||
	operator_.m_preconditions.reserve(numberOfPrevailConditions);
 | 
			
		||||
 | 
			
		||||
	for (size_t j = 0; j < numberOfPrevailConditions; j++)
 | 
			
		||||
		operator_.m_preconditions.emplace_back(Condition::fromSAS(istream, variables));
 | 
			
		||||
		operator_.m_preconditions.emplace_back(Condition::fromSAS(parser, variables));
 | 
			
		||||
 | 
			
		||||
	const auto numberOfEffects = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfEffects = parser.parse<size_t>();
 | 
			
		||||
	operator_.m_effects.reserve(numberOfEffects);
 | 
			
		||||
 | 
			
		||||
	for (size_t j = 0; j < numberOfEffects; j++)
 | 
			
		||||
		operator_.m_effects.emplace_back(Effect::fromSAS(istream, variables, operator_.m_preconditions));
 | 
			
		||||
		operator_.m_effects.emplace_back(Effect::fromSAS(parser, variables, operator_.m_preconditions));
 | 
			
		||||
 | 
			
		||||
	operator_.m_costs = utils::parse<size_t>(istream);
 | 
			
		||||
	operator_.m_costs = parser.parse<size_t>();
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_operator");
 | 
			
		||||
	parser.expect<std::string>("end_operator");
 | 
			
		||||
 | 
			
		||||
	return operator_;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,8 @@
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
#include <plasp/utils/IO.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -17,21 +18,19 @@ namespace sas
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Predicate Predicate::fromSAS(std::istream &istream)
 | 
			
		||||
Predicate Predicate::fromSAS(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	Predicate predicate;
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		istream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
 | 
			
		||||
		parser.skipLine();
 | 
			
		||||
 | 
			
		||||
		// TODO: Inefficient, reimplement in one pass
 | 
			
		||||
		std::string line;
 | 
			
		||||
		std::getline(istream, line);
 | 
			
		||||
		const std::string line = parser.getLine();
 | 
			
		||||
 | 
			
		||||
		std::stringstream lineStream(line);
 | 
			
		||||
 | 
			
		||||
		predicate.m_name = utils::parse<std::string>(lineStream);
 | 
			
		||||
		lineStream >> predicate.m_name;
 | 
			
		||||
 | 
			
		||||
		while (lineStream.peek() == ' ')
 | 
			
		||||
			lineStream.ignore(1);
 | 
			
		||||
@@ -41,7 +40,7 @@ Predicate Predicate::fromSAS(std::istream &istream)
 | 
			
		||||
	}
 | 
			
		||||
	catch (const std::exception &e)
 | 
			
		||||
	{
 | 
			
		||||
		throw utils::ParserException("Could not parse operator predicate");
 | 
			
		||||
		throw utils::ParserException(parser.row(), parser.column(), "Could not parse operator predicate");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return predicate;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
#include <plasp/sas/TranslatorASP.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/TranslatorException.h>
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,8 @@
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/sas/Variable.h>
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
#include <plasp/utils/IO.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -53,14 +54,14 @@ Value Value::negated() const
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Value Value::fromSAS(std::istream &istream)
 | 
			
		||||
Value Value::fromSAS(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	const auto sasSign = utils::parse<std::string>(istream);
 | 
			
		||||
	const auto sasSign = parser.parse<std::string>();
 | 
			
		||||
 | 
			
		||||
	if (sasSign == "<none")
 | 
			
		||||
	{
 | 
			
		||||
		utils::parseExpected<std::string>(istream, "of");
 | 
			
		||||
		utils::parseExpected<std::string>(istream, "those>");
 | 
			
		||||
		parser.expect<std::string>("of");
 | 
			
		||||
		parser.expect<std::string>("those>");
 | 
			
		||||
 | 
			
		||||
		// TODO: do not return a copy of Value::None
 | 
			
		||||
		return Value::None;
 | 
			
		||||
@@ -73,12 +74,12 @@ Value Value::fromSAS(std::istream &istream)
 | 
			
		||||
	else if (sasSign == "NegatedAtom")
 | 
			
		||||
		value.m_sign = Value::Sign::Negative;
 | 
			
		||||
	else
 | 
			
		||||
		throw utils::ParserException("Invalid value sign \"" + sasSign + "\"");
 | 
			
		||||
		throw utils::ParserException(parser.row(), parser.column(), "Invalid value sign \"" + sasSign + "\"");
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		istream.ignore(1);
 | 
			
		||||
		std::getline(istream, value.m_name);
 | 
			
		||||
		parser.skipWhiteSpace();
 | 
			
		||||
		value.m_name = parser.getLine();
 | 
			
		||||
 | 
			
		||||
		// Remove trailing ()
 | 
			
		||||
		if (value.m_name.find("()") != std::string::npos)
 | 
			
		||||
@@ -89,7 +90,7 @@ Value Value::fromSAS(std::istream &istream)
 | 
			
		||||
	}
 | 
			
		||||
	catch (const std::exception &e)
 | 
			
		||||
	{
 | 
			
		||||
		throw utils::ParserException(std::string("Could not parse variable value (") + e.what() + ")");
 | 
			
		||||
		throw utils::ParserException(parser.row(), parser.column(), std::string("Could not parse variable value (") + e.what() + ")");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return value;
 | 
			
		||||
@@ -97,15 +98,15 @@ Value Value::fromSAS(std::istream &istream)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const Value &Value::referenceFromSAS(std::istream &istream, const Variable &variable)
 | 
			
		||||
const Value &Value::referenceFromSAS(utils::Parser &parser, const Variable &variable)
 | 
			
		||||
{
 | 
			
		||||
	const auto valueID = utils::parse<int>(istream);
 | 
			
		||||
	const auto valueID = parser.parse<int>();
 | 
			
		||||
 | 
			
		||||
	if (valueID == -1)
 | 
			
		||||
		return Value::Any;
 | 
			
		||||
 | 
			
		||||
	if (valueID < 0 || static_cast<size_t>(valueID) >= variable.values().size())
 | 
			
		||||
		throw utils::ParserException("Value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")");
 | 
			
		||||
		throw utils::ParserException(parser.row(), parser.column(), "Value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")");
 | 
			
		||||
 | 
			
		||||
	return variable.values()[valueID];
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,8 @@
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
#include <plasp/utils/IO.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -22,28 +23,28 @@ Variable::Variable()
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Variable Variable::fromSAS(std::istream &istream)
 | 
			
		||||
Variable Variable::fromSAS(utils::Parser &parser)
 | 
			
		||||
{
 | 
			
		||||
	Variable variable;
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "begin_variable");
 | 
			
		||||
	parser.expect<std::string>("begin_variable");
 | 
			
		||||
 | 
			
		||||
	variable.m_name = utils::parse<std::string>(istream);
 | 
			
		||||
	variable.m_axiomLayer = utils::parse<int>(istream);
 | 
			
		||||
	variable.m_name = parser.parse<std::string>();
 | 
			
		||||
	variable.m_axiomLayer = parser.parse<int>();
 | 
			
		||||
 | 
			
		||||
	const auto numberOfValues = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto numberOfValues = parser.parse<size_t>();
 | 
			
		||||
	variable.m_values.reserve(numberOfValues);
 | 
			
		||||
 | 
			
		||||
	for (size_t j = 0; j < numberOfValues; j++)
 | 
			
		||||
	{
 | 
			
		||||
		variable.m_values.emplace_back(Value::fromSAS(istream));
 | 
			
		||||
		variable.m_values.emplace_back(Value::fromSAS(parser));
 | 
			
		||||
 | 
			
		||||
		// <none of those> values are only allowed at the end
 | 
			
		||||
		if (j < numberOfValues - 1 && variable.m_values[j] == Value::None)
 | 
			
		||||
			throw utils::ParserException("<none of those> value must be the last value of a variable");
 | 
			
		||||
			throw utils::ParserException(parser.row(), parser.column(), "<none of those> value must be the last value of a variable");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	utils::parseExpected<std::string>(istream, "end_variable");
 | 
			
		||||
	parser.expect<std::string>("end_variable");
 | 
			
		||||
 | 
			
		||||
	return variable;
 | 
			
		||||
}
 | 
			
		||||
@@ -57,12 +58,12 @@ void Variable::printNameAsASPPredicate(std::ostream &ostream) const
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const Variable &Variable::referenceFromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
const Variable &Variable::referenceFromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	const auto variableID = utils::parse<size_t>(istream);
 | 
			
		||||
	const auto variableID = parser.parse<size_t>();
 | 
			
		||||
 | 
			
		||||
	if (variableID >= variables.size())
 | 
			
		||||
		throw utils::ParserException("Variable index out of range (index " + std::to_string(variableID) + ")");
 | 
			
		||||
		throw utils::ParserException(parser.row(), parser.column(), "Variable index out of range (index " + std::to_string(variableID) + ")");
 | 
			
		||||
 | 
			
		||||
	return variables[variableID];
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,6 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace sas
 | 
			
		||||
@@ -26,13 +24,13 @@ VariableTransition::VariableTransition()
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
VariableTransition VariableTransition::fromSAS(std::istream &istream, const Variables &variables)
 | 
			
		||||
VariableTransition VariableTransition::fromSAS(utils::Parser &parser, const Variables &variables)
 | 
			
		||||
{
 | 
			
		||||
	VariableTransition variableTransition;
 | 
			
		||||
 | 
			
		||||
	variableTransition.m_variable = &Variable::referenceFromSAS(istream, variables);
 | 
			
		||||
	variableTransition.m_valueBefore = &Value::referenceFromSAS(istream, *variableTransition.m_variable);
 | 
			
		||||
	variableTransition.m_valueAfter = &Value::referenceFromSAS(istream, *variableTransition.m_variable);
 | 
			
		||||
	variableTransition.m_variable = &Variable::referenceFromSAS(parser, variables);
 | 
			
		||||
	variableTransition.m_valueBefore = &Value::referenceFromSAS(parser, *variableTransition.m_variable);
 | 
			
		||||
	variableTransition.m_valueAfter = &Value::referenceFromSAS(parser, *variableTransition.m_variable);
 | 
			
		||||
 | 
			
		||||
	return variableTransition;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										392
									
								
								src/plasp/utils/Parser.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										392
									
								
								src/plasp/utils/Parser.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,392 @@
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include <boost/assert.hpp>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace utils
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Parser
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
const std::istream_iterator<unsigned char> Parser::EndOfFile = std::istream_iterator<unsigned char>();
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
Parser::Parser(std::istream &istream)
 | 
			
		||||
:	m_istream(istream),
 | 
			
		||||
	m_position(m_istream),
 | 
			
		||||
	m_row{1},
 | 
			
		||||
	m_column{1},
 | 
			
		||||
	m_endOfFile{false}
 | 
			
		||||
{
 | 
			
		||||
	std::setlocale(LC_NUMERIC, "C");
 | 
			
		||||
 | 
			
		||||
	istream.exceptions(std::istream::badbit);
 | 
			
		||||
 | 
			
		||||
	// Don’t skip whitespace
 | 
			
		||||
	istream >> std::noskipws;
 | 
			
		||||
 | 
			
		||||
	checkStream();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
size_t Parser::row() const
 | 
			
		||||
{
 | 
			
		||||
	return m_row;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
size_t Parser::column() const
 | 
			
		||||
{
 | 
			
		||||
	return m_column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Parser::checkStream() const
 | 
			
		||||
{
 | 
			
		||||
	if (m_position == EndOfFile)
 | 
			
		||||
		throw ParserException(m_row, m_column, "Reading past end of file");
 | 
			
		||||
 | 
			
		||||
	if (m_istream.fail())
 | 
			
		||||
		throw ParserException(m_row, m_column);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Parser::advance()
 | 
			
		||||
{
 | 
			
		||||
	checkStream();
 | 
			
		||||
 | 
			
		||||
	const auto character = *m_position;
 | 
			
		||||
 | 
			
		||||
	if (character == '\n')
 | 
			
		||||
	{
 | 
			
		||||
		m_row++;
 | 
			
		||||
		m_column = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (std::isblank(character) || std::isprint(character))
 | 
			
		||||
		m_column++;
 | 
			
		||||
 | 
			
		||||
	m_position++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
bool Parser::advanceIf(unsigned char expectedCharacter)
 | 
			
		||||
{
 | 
			
		||||
	checkStream();
 | 
			
		||||
 | 
			
		||||
	if (*m_position != expectedCharacter)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	advance();
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Parser::skipWhiteSpace()
 | 
			
		||||
{
 | 
			
		||||
	checkStream();
 | 
			
		||||
 | 
			
		||||
	while (std::isspace(*m_position))
 | 
			
		||||
		advance();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Parser::skipLine()
 | 
			
		||||
{
 | 
			
		||||
	checkStream();
 | 
			
		||||
 | 
			
		||||
	while (*m_position != '\n')
 | 
			
		||||
		advance();
 | 
			
		||||
 | 
			
		||||
	advance();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
std::string Parser::getLine()
 | 
			
		||||
{
 | 
			
		||||
	checkStream();
 | 
			
		||||
 | 
			
		||||
	std::string value;
 | 
			
		||||
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
		const auto character = *m_position;
 | 
			
		||||
 | 
			
		||||
		advance();
 | 
			
		||||
 | 
			
		||||
		if (character == '\n')
 | 
			
		||||
			break;
 | 
			
		||||
		else if (character == '\r')
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		value.push_back(character);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
std::string Parser::parse<std::string>()
 | 
			
		||||
{
 | 
			
		||||
	skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	std::string value;
 | 
			
		||||
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
		const auto character = *m_position;
 | 
			
		||||
 | 
			
		||||
		if (std::isspace(character))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		value.push_back(character);
 | 
			
		||||
		advance();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<std::string>(const std::string &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	BOOST_ASSERT(!std::isspace(expectedValue[0]));
 | 
			
		||||
 | 
			
		||||
	skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	std::for_each(expectedValue.cbegin(), expectedValue.cend(),
 | 
			
		||||
		[&](const auto &expectedCharacter)
 | 
			
		||||
		{
 | 
			
		||||
			const auto character = *m_position;
 | 
			
		||||
 | 
			
		||||
			if (character != expectedCharacter)
 | 
			
		||||
				throw ParserException(m_row, m_column, "Unexpected string, expected " + expectedValue);
 | 
			
		||||
 | 
			
		||||
			this->advance();
 | 
			
		||||
		});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
uint64_t Parser::parseIntegerBody()
 | 
			
		||||
{
 | 
			
		||||
	checkStream();
 | 
			
		||||
 | 
			
		||||
	if (!std::isdigit(*m_position))
 | 
			
		||||
		throw ParserException(m_row, m_column, "Could not parse integer value");
 | 
			
		||||
 | 
			
		||||
	uint64_t value = 0;
 | 
			
		||||
 | 
			
		||||
	while (m_position != std::istream_iterator<unsigned char>())
 | 
			
		||||
	{
 | 
			
		||||
		const auto character = *m_position;
 | 
			
		||||
 | 
			
		||||
		if (!std::isdigit(character))
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		value *= 10;
 | 
			
		||||
		value += character - '0';
 | 
			
		||||
 | 
			
		||||
		advance();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int64_t Parser::parse<int64_t>()
 | 
			
		||||
{
 | 
			
		||||
	skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	bool positive = advanceIf('+') || !advanceIf('-');
 | 
			
		||||
 | 
			
		||||
	const auto value = parseIntegerBody();
 | 
			
		||||
 | 
			
		||||
	return (positive ? value : -value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
uint64_t Parser::parse<uint64_t>()
 | 
			
		||||
{
 | 
			
		||||
	skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	if (*m_position == '-')
 | 
			
		||||
		throw ParserException(m_row, m_column, "Expected unsigned integer, got signed one");
 | 
			
		||||
 | 
			
		||||
	return parseIntegerBody();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<int64_t>(const int64_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	const auto value = parse<int64_t>();
 | 
			
		||||
 | 
			
		||||
	if (value != expectedValue)
 | 
			
		||||
		throw ParserException(m_row, m_column, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<uint64_t>(const uint64_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	const auto value = parse<uint64_t>();
 | 
			
		||||
 | 
			
		||||
	if (value != expectedValue)
 | 
			
		||||
		throw ParserException(m_row, m_column, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int32_t Parser::parse<int32_t>()
 | 
			
		||||
{
 | 
			
		||||
	return static_cast<int32_t>(parse<int64_t>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
uint32_t Parser::parse<uint32_t>()
 | 
			
		||||
{
 | 
			
		||||
	return static_cast<uint32_t>(parse<uint64_t>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<int32_t>(const int32_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	expect<int64_t>(static_cast<int64_t>(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<uint32_t>(const uint32_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	expect<uint64_t>(static_cast<uint64_t>(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int16_t Parser::parse<int16_t>()
 | 
			
		||||
{
 | 
			
		||||
	return static_cast<int16_t>(parse<int64_t>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
uint16_t Parser::parse<uint16_t>()
 | 
			
		||||
{
 | 
			
		||||
	return static_cast<uint16_t>(parse<uint64_t>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<int16_t>(const int16_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	expect<int64_t>(static_cast<int64_t>(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<uint16_t>(const uint16_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	expect<uint64_t>(static_cast<uint64_t>(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int8_t Parser::parse<int8_t>()
 | 
			
		||||
{
 | 
			
		||||
	return static_cast<int8_t>(parse<int64_t>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
uint8_t Parser::parse<uint8_t>()
 | 
			
		||||
{
 | 
			
		||||
	return static_cast<uint8_t>(parse<uint64_t>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<int8_t>(const int8_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	expect<int64_t>(static_cast<int64_t>(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<uint8_t>(const uint8_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	expect<uint64_t>(static_cast<uint64_t>(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
bool Parser::parse<bool>()
 | 
			
		||||
{
 | 
			
		||||
	skipWhiteSpace();
 | 
			
		||||
 | 
			
		||||
	if (advanceIf('0'))
 | 
			
		||||
	    return false;
 | 
			
		||||
 | 
			
		||||
	if (advanceIf('1'))
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	throw ParserException(m_row, m_column, "Could not parse Boolean value");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
void Parser::expect<bool>(const bool &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	const auto value = parse<bool>();
 | 
			
		||||
 | 
			
		||||
	if (value != expectedValue)
 | 
			
		||||
		throw ParserException(m_row, m_column, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,84 @@
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parsing.h>
 | 
			
		||||
#include <plasp/utils/IO.h>
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
TEST(UtilsTests, ParseSimple)
 | 
			
		||||
{
 | 
			
		||||
	std::stringstream stream("identifier  5   \n-51\t expected unexpected 100 -100");
 | 
			
		||||
	std::stringstream s("identifier  5   \n-51\t 0 1 expected unexpected");
 | 
			
		||||
	plasp::utils::Parser p(s);
 | 
			
		||||
 | 
			
		||||
	ASSERT_EQ(plasp::utils::parse<std::string>(stream), "identifier");
 | 
			
		||||
	ASSERT_EQ(plasp::utils::parse<size_t>(stream), 5u);
 | 
			
		||||
	ASSERT_EQ(plasp::utils::parse<int>(stream), -51);
 | 
			
		||||
	ASSERT_NO_THROW(plasp::utils::parseExpected<std::string>(stream, "expected"));
 | 
			
		||||
	ASSERT_THROW(plasp::utils::parseExpected<std::string>(stream, "expected"), plasp::utils::ParserException);
 | 
			
		||||
	ASSERT_NO_THROW(plasp::utils::parseExpected<size_t>(stream, 100));
 | 
			
		||||
	ASSERT_THROW(plasp::utils::parseExpected<size_t>(stream, 100), plasp::utils::ParserException);
 | 
			
		||||
	ASSERT_EQ(p.parse<std::string>(), "identifier");
 | 
			
		||||
	ASSERT_EQ(p.parse<size_t>(), 5u);
 | 
			
		||||
	ASSERT_EQ(p.parse<int>(), -51);
 | 
			
		||||
	ASSERT_EQ(p.parse<bool>(), false);
 | 
			
		||||
	ASSERT_EQ(p.parse<bool>(), true);
 | 
			
		||||
 | 
			
		||||
	ASSERT_NO_THROW(p.expect<std::string>("expected"));
 | 
			
		||||
	ASSERT_THROW(p.expect<std::string>("expected"), plasp::utils::ParserException);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
TEST(UtilsTests, ParseUnsignedNumbers)
 | 
			
		||||
{
 | 
			
		||||
	std::stringstream s("100 200 -300 -400");
 | 
			
		||||
	plasp::utils::Parser p(s);
 | 
			
		||||
 | 
			
		||||
	ASSERT_EQ(p.parse<int>(), 100);
 | 
			
		||||
	ASSERT_EQ(p.parse<size_t>(), 200u);
 | 
			
		||||
	ASSERT_EQ(p.parse<int>(), -300);
 | 
			
		||||
	ASSERT_THROW(p.parse<size_t>(), plasp::utils::ParserException);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
TEST(UtilsTests, ParseEndOfFile)
 | 
			
		||||
{
 | 
			
		||||
	std::stringstream s1("test");
 | 
			
		||||
	plasp::utils::Parser p1(s1);
 | 
			
		||||
 | 
			
		||||
	ASSERT_NO_THROW(p1.expect<std::string>("test"));
 | 
			
		||||
	ASSERT_THROW(p1.parse<std::string>(), plasp::utils::ParserException);
 | 
			
		||||
 | 
			
		||||
	std::stringstream s2("test1 test2 test3");
 | 
			
		||||
	plasp::utils::Parser p2(s2);
 | 
			
		||||
 | 
			
		||||
	ASSERT_NO_THROW(p2.expect<std::string>("test1"));
 | 
			
		||||
	ASSERT_NO_THROW(p2.expect<std::string>("test2"));
 | 
			
		||||
	ASSERT_NO_THROW(p2.expect<std::string>("test3"));
 | 
			
		||||
	ASSERT_THROW(p2.parse<std::string>(), plasp::utils::ParserException);
 | 
			
		||||
 | 
			
		||||
	std::stringstream s3("-127");
 | 
			
		||||
	plasp::utils::Parser p3(s3);
 | 
			
		||||
 | 
			
		||||
	p3.expect<int>(-127);
 | 
			
		||||
	ASSERT_THROW(p3.parse<int>(), plasp::utils::ParserException);
 | 
			
		||||
 | 
			
		||||
	std::stringstream s4("128 -1023 -4095");
 | 
			
		||||
	plasp::utils::Parser p4(s4);
 | 
			
		||||
 | 
			
		||||
	ASSERT_NO_THROW(p4.expect<size_t>(128));
 | 
			
		||||
	ASSERT_NO_THROW(p4.expect<int>(-1023));
 | 
			
		||||
	ASSERT_NO_THROW(p4.expect<int>(-4095));
 | 
			
		||||
	ASSERT_THROW(p4.parse<int>(), plasp::utils::ParserException);
 | 
			
		||||
 | 
			
		||||
	std::stringstream s5("0");
 | 
			
		||||
	plasp::utils::Parser p5(s5);
 | 
			
		||||
 | 
			
		||||
	p5.expect<bool>(false);
 | 
			
		||||
	ASSERT_THROW(p5.parse<bool>(), plasp::utils::ParserException);
 | 
			
		||||
 | 
			
		||||
	std::stringstream s6("0 1 0");
 | 
			
		||||
	plasp::utils::Parser p6(s6);
 | 
			
		||||
 | 
			
		||||
	ASSERT_NO_THROW(p6.expect<bool>(false));
 | 
			
		||||
	ASSERT_NO_THROW(p6.expect<bool>(true));
 | 
			
		||||
	ASSERT_NO_THROW(p6.expect<bool>(false));
 | 
			
		||||
	ASSERT_THROW(p6.parse<bool>(), plasp::utils::ParserException);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user