Started implementing colored output.
This commit is contained in:
		@@ -66,14 +66,6 @@ int main(int argc, char **argv)
 | 
			
		||||
		return EXIT_SUCCESS;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto handleException =
 | 
			
		||||
		[&](const auto &messagePrefix, const auto &exception)
 | 
			
		||||
		{
 | 
			
		||||
			std::cerr << messagePrefix << ": " << exception.what() << std::endl << std::endl;
 | 
			
		||||
			printHelp();
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		plasp::utils::Parser parser;
 | 
			
		||||
@@ -108,7 +100,9 @@ int main(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
		if (language == plasp::Language::Type::Unknown)
 | 
			
		||||
		{
 | 
			
		||||
			std::cerr << "Error: Unknown input language" << std::endl << std::endl;
 | 
			
		||||
			plasp::utils::Logger logger;
 | 
			
		||||
			logger.exception("error", "unknown input language");
 | 
			
		||||
			std::cout << std::endl;
 | 
			
		||||
			printHelp();
 | 
			
		||||
			return EXIT_FAILURE;
 | 
			
		||||
		}
 | 
			
		||||
@@ -137,19 +131,27 @@ int main(int argc, char **argv)
 | 
			
		||||
	}
 | 
			
		||||
	catch (const plasp::utils::ParserException &e)
 | 
			
		||||
	{
 | 
			
		||||
		handleException("Parser error", e);
 | 
			
		||||
		plasp::utils::Logger logger;
 | 
			
		||||
		logger.parserException(e.coordinate(), e.message());
 | 
			
		||||
		return EXIT_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
	catch (const plasp::utils::ParserWarning &e)
 | 
			
		||||
	{
 | 
			
		||||
		handleException("Parser warning", e);
 | 
			
		||||
		plasp::utils::Logger logger;
 | 
			
		||||
		logger.parserException(e.coordinate(), e.message());
 | 
			
		||||
		return EXIT_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
	catch (const plasp::utils::TranslatorException &e)
 | 
			
		||||
	{
 | 
			
		||||
		handleException("Translation error", e);
 | 
			
		||||
		plasp::utils::Logger logger;
 | 
			
		||||
		logger.exception("translation error", e.what());
 | 
			
		||||
		return EXIT_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
	catch (const std::exception &e)
 | 
			
		||||
	{
 | 
			
		||||
		handleException("Error", e);
 | 
			
		||||
		plasp::utils::Logger logger;
 | 
			
		||||
		logger.exception("unexpected error", e.what());
 | 
			
		||||
		return EXIT_FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return EXIT_SUCCESS;
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ std::unique_ptr<Derived> NAry<Derived>::parse(Context &context,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (expression->m_arguments.empty())
 | 
			
		||||
		context.logger.parserWarning(context.parser, "\"" + Derived::Identifier + "\" expressions should not be empty");
 | 
			
		||||
		context.logger.parserWarning(context.parser, "“" + Derived::Identifier + "” expressions should not be empty");
 | 
			
		||||
 | 
			
		||||
	parser.expect<std::string>(")");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										81
									
								
								include/plasp/utils/Formatting.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								include/plasp/utils/Formatting.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#ifndef __PLASP__UTILS__FORMATTING_H
 | 
			
		||||
#define __PLASP__UTILS__FORMATTING_H
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
namespace utils
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Formatting
 | 
			
		||||
//
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
enum class Color
 | 
			
		||||
{
 | 
			
		||||
	Black = 0,
 | 
			
		||||
	Red = 1,
 | 
			
		||||
	Green = 2,
 | 
			
		||||
	Yellow = 3,
 | 
			
		||||
	Blue = 4,
 | 
			
		||||
	Magenta = 5,
 | 
			
		||||
	Cyan = 6,
 | 
			
		||||
	White = 7
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
enum class FontWeight
 | 
			
		||||
{
 | 
			
		||||
	Normal = 0,
 | 
			
		||||
	Bold = 1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
struct Format
 | 
			
		||||
{
 | 
			
		||||
	Format(Color color, FontWeight fontWeight = FontWeight::Normal)
 | 
			
		||||
	:	color{color},
 | 
			
		||||
		fontWeight{fontWeight}
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Color color;
 | 
			
		||||
	FontWeight fontWeight;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
std::ostream &operator<<(std::ostream &ostream, const Format &format)
 | 
			
		||||
{
 | 
			
		||||
	const auto fontWeightCode = static_cast<size_t>(format.fontWeight);
 | 
			
		||||
	const auto colorCode = 30 + static_cast<size_t>(format.color);
 | 
			
		||||
 | 
			
		||||
	return (ostream << "\033[" << fontWeightCode << ";" << colorCode << "m");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
class ResetFormat
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
std::ostream &operator<<(std::ostream &ostream, const ResetFormat &)
 | 
			
		||||
{
 | 
			
		||||
	return (ostream << "\033[0m");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Parser.h>
 | 
			
		||||
#include <plasp/utils/ParserException.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
{
 | 
			
		||||
@@ -37,6 +38,8 @@ class Logger
 | 
			
		||||
 | 
			
		||||
		void setWarningLevel(WarningLevel warningLevel);
 | 
			
		||||
 | 
			
		||||
		void exception(const std::string &errorType, const std::string &message);
 | 
			
		||||
		void parserException(const Parser::Coordinate &coordinate, const std::string &message);
 | 
			
		||||
		void parserWarning(const Parser &parser, const std::string &message);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,11 @@ class ParserException: public std::exception
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		explicit ParserException(const utils::Parser &parser, const std::string &message)
 | 
			
		||||
		:	m_coordinate{parser.coordinate()},
 | 
			
		||||
			m_message{message},
 | 
			
		||||
			m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row)
 | 
			
		||||
				+ ":" + std::to_string(m_coordinate.column) + " " + m_message}
 | 
			
		||||
		{
 | 
			
		||||
			const auto coordinate = parser.coordinate();
 | 
			
		||||
 | 
			
		||||
			m_message = coordinate.sectionName + ":" + std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) + " " + message;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		~ParserException() throw()
 | 
			
		||||
@@ -43,14 +44,23 @@ class ParserException: public std::exception
 | 
			
		||||
 | 
			
		||||
		const char *what() const throw()
 | 
			
		||||
		{
 | 
			
		||||
			if (m_message.empty())
 | 
			
		||||
				return "Unspecified parser error";
 | 
			
		||||
			return m_plainMessage.c_str();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			return m_message.c_str();
 | 
			
		||||
		const Parser::Coordinate &coordinate() const
 | 
			
		||||
		{
 | 
			
		||||
			return m_coordinate;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const std::string &message() const
 | 
			
		||||
		{
 | 
			
		||||
			return m_message;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Parser::Coordinate m_coordinate;
 | 
			
		||||
		std::string m_message;
 | 
			
		||||
		std::string m_plainMessage;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,11 @@ class ParserWarning: public std::exception
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		explicit ParserWarning(const utils::Parser &parser, const std::string &message)
 | 
			
		||||
		:	m_coordinate{parser.coordinate()},
 | 
			
		||||
			m_message{message},
 | 
			
		||||
			m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row)
 | 
			
		||||
				+ ":" + std::to_string(m_coordinate.column) + " " + m_message}
 | 
			
		||||
		{
 | 
			
		||||
			const auto coordinate = parser.coordinate();
 | 
			
		||||
 | 
			
		||||
			m_message = coordinate.sectionName + ":" + std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) + " " + message;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		~ParserWarning() throw()
 | 
			
		||||
@@ -43,14 +44,23 @@ class ParserWarning: public std::exception
 | 
			
		||||
 | 
			
		||||
		const char *what() const throw()
 | 
			
		||||
		{
 | 
			
		||||
			if (m_message.empty())
 | 
			
		||||
				return "Unspecified parser warning";
 | 
			
		||||
			return m_plainMessage.c_str();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			return m_message.c_str();
 | 
			
		||||
		const Parser::Coordinate &coordinate() const
 | 
			
		||||
		{
 | 
			
		||||
			return m_coordinate;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const std::string &message() const
 | 
			
		||||
		{
 | 
			
		||||
			return m_message;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Parser::Coordinate m_coordinate;
 | 
			
		||||
		std::string m_message;
 | 
			
		||||
		std::string m_plainMessage;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -188,7 +188,7 @@ void Description::findSections()
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			const auto sectionIdentifier = parser.parse<std::string>();
 | 
			
		||||
			throw utils::ParserException(parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
 | 
			
		||||
			throw utils::ParserException(parser, "Unknown PDDL section “" + sectionIdentifier + "”");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m_context.parser.skipWhiteSpace();
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ void Domain::findSections()
 | 
			
		||||
			if (unique && sectionPosition != -1)
 | 
			
		||||
			{
 | 
			
		||||
				parser.seek(value);
 | 
			
		||||
				throw utils::ParserException(parser, "Only one \":" + sectionName + "\" section allowed");
 | 
			
		||||
				throw utils::ParserException(parser, "Only one “:" + sectionName + "” section allowed");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			sectionPosition = value;
 | 
			
		||||
@@ -95,7 +95,7 @@ void Domain::findSections()
 | 
			
		||||
 | 
			
		||||
			const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
			m_context.logger.parserWarning(parser, "Section type \"" + sectionIdentifier + "\" currently unsupported");
 | 
			
		||||
			m_context.logger.parserWarning(parser, "Section type “" + sectionIdentifier + "” currently unsupported");
 | 
			
		||||
 | 
			
		||||
			parser.seek(sectionIdentifierPosition);
 | 
			
		||||
		}
 | 
			
		||||
@@ -104,7 +104,7 @@ void Domain::findSections()
 | 
			
		||||
			const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
			parser.seek(position);
 | 
			
		||||
			throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\"");
 | 
			
		||||
			throw utils::ParserException(m_context.parser, "Unknown domain section “" + sectionIdentifier + "”");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Skip section for now and parse it later
 | 
			
		||||
@@ -280,7 +280,7 @@ void Domain::checkRequirement(Requirement::Type requirementType) const
 | 
			
		||||
	if (hasRequirement(requirementType))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	throw ConsistencyException("Requirement \"" + Requirement(requirementType).toPDDL() + "\" used but never declared");
 | 
			
		||||
	throw ConsistencyException("Requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ ExpressionPointer parseExpression(Context &context, ExpressionContext &expressio
 | 
			
		||||
	const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	parser.seek(position);
 | 
			
		||||
	throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
 | 
			
		||||
	throw utils::ParserException(context.parser, "Expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -186,7 +186,7 @@ ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext
 | 
			
		||||
	const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	parser.seek(position);
 | 
			
		||||
	throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
 | 
			
		||||
	throw utils::ParserException(context.parser, "Expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context,
 | 
			
		||||
			const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
			parser.seek(position);
 | 
			
		||||
			throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
 | 
			
		||||
			throw utils::ParserException(parser, "Expression type “" + expressionIdentifier + "” unknown or not allowed in this context");
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
	parser.skipWhiteSpace();
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ void Problem::findSections()
 | 
			
		||||
		if (unique && sectionPosition != -1)
 | 
			
		||||
		{
 | 
			
		||||
			parser.seek(value);
 | 
			
		||||
			throw utils::ParserException(parser, "Only one \":" + sectionName + "\" section allowed");
 | 
			
		||||
			throw utils::ParserException(parser, "Only one “:" + sectionName + "” section allowed");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sectionPosition = value;
 | 
			
		||||
@@ -89,7 +89,7 @@ void Problem::findSections()
 | 
			
		||||
 | 
			
		||||
			const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
			m_context.logger.parserWarning(parser, "Section type \"" + sectionIdentifier + "\" currently unsupported");
 | 
			
		||||
			m_context.logger.parserWarning(parser, "Section type “" + sectionIdentifier + "” currently unsupported");
 | 
			
		||||
 | 
			
		||||
			parser.seek(sectionIdentifierPosition);
 | 
			
		||||
		}
 | 
			
		||||
@@ -98,7 +98,7 @@ void Problem::findSections()
 | 
			
		||||
			const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
			parser.seek(position);
 | 
			
		||||
			throw utils::ParserException(m_context.parser, "Unknown problem section \"" + sectionIdentifier + "\"");
 | 
			
		||||
			throw utils::ParserException(m_context.parser, "Unknown problem section “" + sectionIdentifier + "”");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Skip section for now and parse it later
 | 
			
		||||
@@ -204,7 +204,7 @@ void Problem::parseDomainSection()
 | 
			
		||||
	const auto domainName = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	if (m_domain.name() != domainName)
 | 
			
		||||
		throw utils::ParserException(parser, "Domains do not match (\"" + m_domain.name() + "\" and \"" + domainName + "\")");
 | 
			
		||||
		throw utils::ParserException(parser, "Domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)");
 | 
			
		||||
 | 
			
		||||
	parser.expect<std::string>(")");
 | 
			
		||||
}
 | 
			
		||||
@@ -261,7 +261,7 @@ void Problem::checkRequirement(Requirement::Type requirementType) const
 | 
			
		||||
	if (hasRequirement(requirementType))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	throw ConsistencyException("Requirement \"" + Requirement(requirementType).toPDDL() + "\" used but never declared");
 | 
			
		||||
	throw ConsistencyException("Requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -89,12 +89,12 @@ Requirement Requirement::parse(Context &context)
 | 
			
		||||
	const auto match = requirementTypesToPDDL.right.find(requirementName);
 | 
			
		||||
 | 
			
		||||
	if (match == requirementTypesToPDDL.right.end())
 | 
			
		||||
		throw utils::ParserException(context.parser, "Unknown PDDL requirement \"" + requirementName + "\"");
 | 
			
		||||
		throw utils::ParserException(context.parser, "Unknown PDDL requirement “" + requirementName + "”");
 | 
			
		||||
 | 
			
		||||
	const auto requirementType = match->second;
 | 
			
		||||
 | 
			
		||||
	if (requirementType == Requirement::Type::GoalUtilities)
 | 
			
		||||
		context.logger.parserWarning(context.parser, "Requirement \"goal-utilities\" is not part of the PDDL 3.1 specification");
 | 
			
		||||
		context.logger.parserWarning(context.parser, "Requirement “goal-utilities” is not part of the PDDL 3.1 specification");
 | 
			
		||||
 | 
			
		||||
	return Requirement(match->second);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -225,7 +225,7 @@ void TranslatorASP::translateActions() const
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					if (precondition.expressionType() != Expression::Type::And)
 | 
			
		||||
						throw utils::TranslatorException("Only \"and\" expressions and (negated) predicates supported as action preconditions currently");
 | 
			
		||||
						throw utils::TranslatorException("Only “and” expressions and (negated) predicates supported as action preconditions currently");
 | 
			
		||||
 | 
			
		||||
					const auto &andExpression = dynamic_cast<const expressions::And &>(precondition);
 | 
			
		||||
 | 
			
		||||
@@ -251,7 +251,7 @@ void TranslatorASP::translateActions() const
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					if (effect.expressionType() != Expression::Type::And)
 | 
			
		||||
						throw utils::TranslatorException("Only \"and\" expressions and (negated) predicates supported as action effects currently");
 | 
			
		||||
						throw utils::TranslatorException("Only “and” expressions and (negated) predicates supported as action effects currently");
 | 
			
		||||
 | 
			
		||||
					const auto &andExpression = dynamic_cast<const expressions::And &>(effect);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -156,7 +156,7 @@ Constant *Constant::parseAndFind(Context &context, const Domain &domain)
 | 
			
		||||
	if (constant != nullptr)
 | 
			
		||||
		return constant;
 | 
			
		||||
 | 
			
		||||
	throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
 | 
			
		||||
	throw utils::ParserException(context.parser, "Constant “" + constantName + "” used but never declared");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -177,7 +177,7 @@ Constant *Constant::parseAndFind(Context &context, const Problem &problem)
 | 
			
		||||
	if (constant)
 | 
			
		||||
		return constant;
 | 
			
		||||
 | 
			
		||||
	throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
 | 
			
		||||
	throw utils::ParserException(context.parser, "Constant “" + constantName + "” used but never declared");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -122,11 +122,11 @@ PrimitiveType *PrimitiveType::parseAndFind(Context &context, Domain &domain)
 | 
			
		||||
		// Only "object" is allowed as an implicit type
 | 
			
		||||
		if (typeName == "object" || typeName == "objects")
 | 
			
		||||
		{
 | 
			
		||||
			context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" should be declared");
 | 
			
		||||
			context.logger.parserWarning(context.parser, "Primitive type “" + typeName + "” should be declared");
 | 
			
		||||
			types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			throw utils::ParserException(context.parser, "Type \"" + typeName + "\" used but never declared");
 | 
			
		||||
			throw utils::ParserException(context.parser, "Type “" + typeName + "” used but never declared");
 | 
			
		||||
 | 
			
		||||
		return types.back().get();
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ UnsupportedPointer Unsupported::parse(Context &context)
 | 
			
		||||
 | 
			
		||||
	expression->m_type = parser.parseIdentifier(isIdentifier);
 | 
			
		||||
 | 
			
		||||
	context.logger.parserWarning(context.parser, "Expression type \"" + expression->m_type + "\" currently unsupported in this context");
 | 
			
		||||
	context.logger.parserWarning(context.parser, "Expression type “" + expression->m_type + "” currently unsupported in this context");
 | 
			
		||||
 | 
			
		||||
	skipSection(parser);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ void Variable::parseDeclaration(Context &context, Variables ¶meters)
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	if (match != parameters.cend())
 | 
			
		||||
		throw utils::ParserException(context.parser, "Variable \"" + variable->m_name + "\" already declared in this scope");
 | 
			
		||||
		throw utils::ParserException(context.parser, "Variable “" + variable->m_name + "” already declared in this scope");
 | 
			
		||||
 | 
			
		||||
	// Flag variable for potentially upcoming type declaration
 | 
			
		||||
	variable->setDirty();
 | 
			
		||||
@@ -154,7 +154,7 @@ const Variable *Variable::parseAndFind(Context &context, const ExpressionContext
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
	if (match == variables.cend())
 | 
			
		||||
		throw utils::ParserException(context.parser, "Parameter \"" + variableName + "\" used but never declared");
 | 
			
		||||
		throw utils::ParserException(context.parser, "Parameter “" + variableName + "” used but never declared");
 | 
			
		||||
 | 
			
		||||
	return match->get();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ Description Description::fromStream(std::istream &istream)
 | 
			
		||||
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() + "\"");
 | 
			
		||||
		throw std::runtime_error("File does not exist: “" + path.string() + "”");
 | 
			
		||||
 | 
			
		||||
	utils::Parser parser;
 | 
			
		||||
	parser.readFile(path);
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ Value Value::fromSAS(utils::Parser &parser)
 | 
			
		||||
	else if (sasSign == "NegatedAtom")
 | 
			
		||||
		value.m_sign = Value::Sign::Negative;
 | 
			
		||||
	else
 | 
			
		||||
		throw utils::ParserException(parser, "Invalid value sign \"" + sasSign + "\"");
 | 
			
		||||
		throw utils::ParserException(parser, "Invalid value sign “" + sasSign + "”");
 | 
			
		||||
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#include <plasp/utils/Logger.h>
 | 
			
		||||
 | 
			
		||||
#include <plasp/utils/Formatting.h>
 | 
			
		||||
#include <plasp/utils/ParserWarning.h>
 | 
			
		||||
 | 
			
		||||
namespace plasp
 | 
			
		||||
@@ -61,6 +62,56 @@ void Logger::setWarningLevel(WarningLevel warningLevel)
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Logger::exception(const std::string &errorType, const std::string &message)
 | 
			
		||||
{
 | 
			
		||||
	if (isatty(STDERR_FILENO))
 | 
			
		||||
	{
 | 
			
		||||
		std::cerr
 | 
			
		||||
			<< Format(Color::Red, FontWeight::Bold) << "error:"
 | 
			
		||||
			<< ResetFormat() << " "
 | 
			
		||||
			<< Format(Color::White, FontWeight::Bold) << message
 | 
			
		||||
			<< ResetFormat() << std::endl;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		std::cerr
 | 
			
		||||
			<< "error:"
 | 
			
		||||
			<< " "
 | 
			
		||||
			<< message
 | 
			
		||||
			<< std::endl;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Logger::parserException(const Parser::Coordinate &coordinate, const std::string &message)
 | 
			
		||||
{
 | 
			
		||||
	if (isatty(STDERR_FILENO))
 | 
			
		||||
	{
 | 
			
		||||
		std::cerr
 | 
			
		||||
			<< Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":"
 | 
			
		||||
			<< std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":"
 | 
			
		||||
			<< ResetFormat() << " "
 | 
			
		||||
			<< Format(Color::Red, FontWeight::Bold) << "error:"
 | 
			
		||||
			<< ResetFormat() << " "
 | 
			
		||||
			<< Format(Color::White, FontWeight::Bold) << message
 | 
			
		||||
			<< ResetFormat() << std::endl;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		std::cerr
 | 
			
		||||
			<< coordinate.sectionName << ":"
 | 
			
		||||
			<< std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":"
 | 
			
		||||
			<< " "
 | 
			
		||||
			<< "error:"
 | 
			
		||||
			<< " "
 | 
			
		||||
			<< message
 | 
			
		||||
			<< std::endl;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
void Logger::parserWarning(const Parser &parser, const std::string &message)
 | 
			
		||||
{
 | 
			
		||||
	if (m_warningLevel == WarningLevel::Ignore)
 | 
			
		||||
@@ -71,9 +122,28 @@ void Logger::parserWarning(const Parser &parser, const std::string &message)
 | 
			
		||||
 | 
			
		||||
	const auto coordinate = parser.coordinate();
 | 
			
		||||
 | 
			
		||||
	std::cerr << "Warning: " << coordinate.sectionName << ":"
 | 
			
		||||
		<< std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column)
 | 
			
		||||
		<< " " << message << std::endl;
 | 
			
		||||
	if (isatty(STDERR_FILENO))
 | 
			
		||||
	{
 | 
			
		||||
		std::cerr
 | 
			
		||||
			<< Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":"
 | 
			
		||||
			<< std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":"
 | 
			
		||||
			<< ResetFormat() << " "
 | 
			
		||||
			<< Format(Color::Magenta, FontWeight::Bold) << "warning:"
 | 
			
		||||
			<< ResetFormat() << " "
 | 
			
		||||
			<< Format(Color::White, FontWeight::Bold) << message
 | 
			
		||||
			<< ResetFormat() << std::endl;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		std::cerr
 | 
			
		||||
			<< coordinate.sectionName << ":"
 | 
			
		||||
			<< std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":"
 | 
			
		||||
			<< " "
 | 
			
		||||
			<< "warning:"
 | 
			
		||||
			<< " "
 | 
			
		||||
			<< message
 | 
			
		||||
			<< std::endl;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,7 @@ void Parser::readStream(std::string streamName, std::istream &istream)
 | 
			
		||||
void Parser::readFile(const boost::filesystem::path &path)
 | 
			
		||||
{
 | 
			
		||||
	if (!boost::filesystem::is_regular_file(path))
 | 
			
		||||
		throw std::runtime_error("File does not exist: \"" + path.string() + "\"");
 | 
			
		||||
		throw std::runtime_error("File does not exist: “" + path.string() + "”");
 | 
			
		||||
 | 
			
		||||
	std::ifstream fileStream(path.string(), std::ios::in);
 | 
			
		||||
 | 
			
		||||
@@ -310,7 +310,7 @@ template<>
 | 
			
		||||
void Parser::expect<std::string>(const std::string &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	if (!probe<std::string>(expectedValue))
 | 
			
		||||
		throw ParserException(*this, "Expected \"" + expectedValue + "\"");
 | 
			
		||||
		throw ParserException(*this, "Expected “" + expectedValue + "”");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -344,7 +344,7 @@ template<>
 | 
			
		||||
void Parser::expect<char>(const char &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	if (!probe<char>(expectedValue))
 | 
			
		||||
		throw ParserException(*this, std::string("Expected \"") + expectedValue + "\"");
 | 
			
		||||
		throw ParserException(*this, std::string("Expected “") + expectedValue + "”");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -439,7 +439,7 @@ template<>
 | 
			
		||||
void Parser::expect<int64_t>(const int64_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	if (!probe<int64_t>(expectedValue))
 | 
			
		||||
		throw ParserException(*this, "Expected \"" + std::to_string(expectedValue) + "\"");
 | 
			
		||||
		throw ParserException(*this, "Expected “" + std::to_string(expectedValue) + "”");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -448,7 +448,7 @@ template<>
 | 
			
		||||
void Parser::expect<uint64_t>(const uint64_t &expectedValue)
 | 
			
		||||
{
 | 
			
		||||
	if (!probe<uint64_t>(expectedValue))
 | 
			
		||||
		throw ParserException(*this, "Expected \"" + std::to_string(expectedValue) + "\"");
 | 
			
		||||
		throw ParserException(*this, "Expected “" + std::to_string(expectedValue) + "”");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -523,7 +523,7 @@ void Parser::expect<bool>(const bool &expectedValue)
 | 
			
		||||
	const auto value = parse<bool>();
 | 
			
		||||
 | 
			
		||||
	if (value != expectedValue)
 | 
			
		||||
		throw ParserException(*this, "Expected \"" + std::to_string(expectedValue) + "\"");
 | 
			
		||||
		throw ParserException(*this, "Expected “" + std::to_string(expectedValue) + "”");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ class SASParserTests : public ::testing::Test
 | 
			
		||||
			std::stringstream outputStream;
 | 
			
		||||
 | 
			
		||||
			if (!fileStream.is_open())
 | 
			
		||||
				throw std::runtime_error("Could not open file \"" + path + "\"");
 | 
			
		||||
				throw std::runtime_error("Could not open file “" + path + "”");
 | 
			
		||||
 | 
			
		||||
			outputStream << fileStream.rdbuf();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user