patrick
/
plasp
Archived
1
0
Fork 0

Put Parser into Context.

This commit is contained in:
Patrick Lühne 2016-06-04 16:10:11 +02:00
parent 08eb14e400
commit a776fc9e06
18 changed files with 145 additions and 131 deletions

View File

@ -25,6 +25,13 @@ namespace pddl
class Context
{
public:
Context(utils::Parser &parser)
: parser(parser)
{
}
utils::Parser &parser;
expressions::PrimitiveTypes primitiveTypes;
//std::unordered_map<std::string, expressions::PrimitiveType *> primitiveTypesHashMap;

View File

@ -27,12 +27,14 @@ class Description
const Domain &domain() const;
private:
Description() = default;
Description(std::istream &istream);
void parseContent(utils::Parser &parser);
void parseSection(utils::Parser &parser);
void parseContent();
void parseSection();
utils::Parser m_parser;
Context m_context;
std::unique_ptr<Domain> m_domain;
//std::unique_ptr<Problem> m_problem;
};

View File

@ -6,7 +6,6 @@
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Requirement.h>
#include <plasp/utils/Parser.h>
namespace plasp
{
@ -22,7 +21,7 @@ namespace pddl
class Domain
{
public:
static Domain fromPDDL(utils::Parser &parser, Context &context);
static Domain fromPDDL(Context &context);
public:
const std::string &name() const;
@ -35,19 +34,19 @@ class Domain
private:
Domain(Context &context);
void parseSection(utils::Parser &parser);
void parseSection();
void parseRequirementSection(utils::Parser &parser);
void parseRequirementSection();
bool hasRequirement(Requirement::Type requirementType) const;
void computeDerivedRequirements();
void parseTypeSection(utils::Parser &parser);
void parseTypeSection();
void parseConstantSection(utils::Parser &parser);
void parseConstantSection();
void parsePredicateSection(utils::Parser &parser);
void parsePredicateSection();
void parseActionSection(utils::Parser &parser);
void parseActionSection();
void checkConsistency();

View File

@ -25,8 +25,7 @@ class Constant: public Expression
static ConstantPointer parseDeclaration(utils::Parser &parser, Context &context);
static void parseTypedDeclaration(utils::Parser &parser, Context &context);
template<class Container>
static Constant *parseExisting(utils::Parser &parser, const Container &constants);
static Constant *parseExisting(utils::Parser &parser, Context &context);
// TODO: method for lazy creation if not existing
@ -58,28 +57,6 @@ class Constant: public Expression
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class Container>
Constant *Constant::parseExisting(utils::Parser &parser, const Container &constants)
{
parser.skipWhiteSpace();
const auto constantName = parser.parseIdentifier(isIdentifier);
// TODO: use hash map
const auto match = std::find_if(constants.cbegin(), constants.cend(),
[&](const auto &constant)
{
return constant->name() == constantName;
});
const auto constantExists = (match != constants.cend());
if (!constantExists)
throw utils::ParserException(parser.row(), parser.column(), "Constant \"" + constantName + "\" used but never declared");
return match->get();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}

View File

@ -4,6 +4,8 @@
#include <exception>
#include <string>
#include <plasp/utils/Parser.h>
namespace plasp
{
namespace utils
@ -18,18 +20,18 @@ namespace utils
class ParserException: public std::exception
{
public:
explicit ParserException(size_t row, size_t column)
: ParserException(row, column, "Unspecified parser error")
explicit ParserException(const utils::Parser &parser)
: ParserException(parser, "Unspecified parser error")
{
}
explicit ParserException(size_t row, size_t column, const char *message)
: ParserException(row, column, static_cast<std::string>(message))
explicit ParserException(const utils::Parser &parser, const char *message)
: ParserException(parser, static_cast<std::string>(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}
explicit ParserException(const utils::Parser &parser, const std::string &message)
: m_message{std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + "\t" + message}
{
}

View File

@ -18,20 +18,26 @@ namespace pddl
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Description::Description(std::istream &istream)
: m_parser(istream),
m_context(m_parser)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Description Description::fromStream(std::istream &istream)
{
Description description;
utils::Parser parser(istream);
Description description(istream);
while (true)
{
parser.skipWhiteSpace();
description.m_context.parser.skipWhiteSpace();
if (parser.atEndOfFile())
if (description.m_context.parser.atEndOfFile())
break;
description.parseContent(parser);
description.parseContent();
}
return description;
@ -60,33 +66,33 @@ const Domain &Description::domain() const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Description::parseContent(utils::Parser &parser)
void Description::parseContent()
{
std::cout << "Parsing file content" << std::endl;
parser.expect<std::string>("(");
parser.expect<std::string>("define");
parseSection(parser);
parser.expect<std::string>(")");
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define");
parseSection();
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Description::parseSection(utils::Parser &parser)
void Description::parseSection()
{
// Parse domain/problem identifier
parser.expect<std::string>("(");
m_context.parser.expect<std::string>("(");
const auto sectionIdentifier = parser.parse<std::string>();
const auto sectionIdentifier = m_context.parser.parse<std::string>();
std::cout << "Parsing section " << sectionIdentifier << std::endl;
if (sectionIdentifier == "domain")
m_domain = std::make_unique<Domain>(Domain::fromPDDL(parser, m_context));
m_domain = std::make_unique<Domain>(Domain::fromPDDL(m_context));
//else if (sectionIdentifier == "problem")
// m_problem = std::make_unique<Problem>(Problem::fromPDDL(parser));
else
throw utils::ParserException(parser.row(), parser.column(), "Unknown PDDL section \"" + sectionIdentifier + "\"");
throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -28,24 +28,24 @@ Domain::Domain(Context &context)
////////////////////////////////////////////////////////////////////////////////////////////////////
Domain Domain::fromPDDL(utils::Parser &parser, Context &context)
Domain Domain::fromPDDL(Context &context)
{
Domain domain(context);
domain.m_name = parser.parseIdentifier(isIdentifier);
domain.m_name = context.parser.parseIdentifier(isIdentifier);
std::cout << "Parsing domain " << domain.m_name << std::endl;
parser.expect<std::string>(")");
context.parser.expect<std::string>(")");
while (true)
{
parser.skipWhiteSpace();
context.parser.skipWhiteSpace();
if (parser.currentCharacter() == ')')
if (context.parser.currentCharacter() == ')')
break;
domain.parseSection(parser);
domain.parseSection();
}
domain.computeDerivedRequirements();
@ -99,12 +99,12 @@ const std::vector<std::unique_ptr<Action>> &Domain::actions() const
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseSection(utils::Parser &parser)
void Domain::parseSection()
{
parser.expect<std::string>("(");
parser.expect<std::string>(":");
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>(":");
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
const auto sectionIdentifier = m_context.parser.parseIdentifier(isIdentifier);
const auto skipSection =
[&]()
@ -115,8 +115,8 @@ void Domain::parseSection(utils::Parser &parser)
while (true)
{
const auto character = parser.currentCharacter();
parser.advance();
const auto character = m_context.parser.currentCharacter();
m_context.parser.advance();
if (character == '(')
openParentheses++;
@ -132,19 +132,19 @@ void Domain::parseSection(utils::Parser &parser)
// TODO: check order of the sections
if (sectionIdentifier == "requirements")
parseRequirementSection(parser);
parseRequirementSection();
else if (sectionIdentifier == "types")
parseTypeSection(parser);
parseTypeSection();
else if (sectionIdentifier == "constants")
parseConstantSection(parser);
parseConstantSection();
else if (sectionIdentifier == "predicates")
parsePredicateSection(parser);
parsePredicateSection();
else if (sectionIdentifier == "functions")
skipSection();
else if (sectionIdentifier == "constraints")
skipSection();
else if (sectionIdentifier == "action")
parseActionSection(parser);
parseActionSection();
else if (sectionIdentifier == "durative-action")
skipSection();
else if (sectionIdentifier == "derived")
@ -153,24 +153,24 @@ void Domain::parseSection(utils::Parser &parser)
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseRequirementSection(utils::Parser &parser)
void Domain::parseRequirementSection()
{
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
while (parser.currentCharacter() != ')')
while (m_context.parser.currentCharacter() != ')')
{
if (parser.currentCharacter() == ':')
parser.advance();
if (m_context.parser.currentCharacter() == ':')
m_context.parser.advance();
m_requirements.emplace_back(Requirement::parse(parser));
m_requirements.emplace_back(Requirement::parse(m_context.parser));
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
}
if (m_requirements.empty())
throw utils::ParserException(parser.row(), parser.column(), "Requirements section does not contain any requirements");
throw utils::ParserException(m_context.parser, "Requirements section does not contain any requirements");
parser.expect<std::string>(")");
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -232,67 +232,67 @@ void Domain::computeDerivedRequirements()
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseTypeSection(utils::Parser &parser)
void Domain::parseTypeSection()
{
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
// Store types and their parent types
while (parser.currentCharacter() != ')')
while (m_context.parser.currentCharacter() != ')')
{
if (parser.currentCharacter() == '(')
throw utils::ParserException(parser.row(), parser.column(), "Only primitive types are allowed in type section");
if (m_context.parser.currentCharacter() == '(')
throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section");
expressions::PrimitiveType::parseTypedDeclaration(parser, m_context);
expressions::PrimitiveType::parseTypedDeclaration(m_context.parser, m_context);
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseConstantSection(utils::Parser &parser)
void Domain::parseConstantSection()
{
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
// Store constants
while (parser.currentCharacter() != ')')
while (m_context.parser.currentCharacter() != ')')
{
expressions::Constant::parseTypedDeclaration(parser, m_context);
expressions::Constant::parseTypedDeclaration(m_context.parser, m_context);
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parsePredicateSection(utils::Parser &parser)
void Domain::parsePredicateSection()
{
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
// Store predicates and their arguments
while (parser.currentCharacter() != ')')
while (m_context.parser.currentCharacter() != ')')
{
expressions::PredicateDeclaration::parse(parser, m_context);
expressions::PredicateDeclaration::parse(m_context.parser, m_context);
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseActionSection(utils::Parser &parser)
void Domain::parseActionSection()
{
parser.skipWhiteSpace();
m_context.parser.skipWhiteSpace();
Action::parseDeclaration(parser, m_context);
Action::parseDeclaration(m_context.parser, m_context);
parser.expect<std::string>(")");
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -32,7 +32,7 @@ ExpressionPointer parsePredicate(utils::Parser &parser, Context &context,
void throwUnsupported(const utils::Parser &parser, const std::string &expressionIdentifier)
{
throw utils::ParserException(parser.row(), parser.column(), "Expression type \"" + expressionIdentifier + "\" currently unsupported");
throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -125,7 +125,7 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
if (match != context.predicateDeclarations.cend())
expression = expressions::Predicate::parse(expressionIdentifier, parser, context, parameters);
else
throw utils::ParserException(parser.row(), parser.column(), "Expression \"" + expressionIdentifier + "\" not allowed in this context");
throw utils::ParserException(parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
}
return expression;
@ -188,7 +188,7 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression
if (match != context.predicateDeclarations.cend())
expression = expressions::Predicate::parse(expressionIdentifier, parser, context, parameters);
else
throw utils::ParserException(parser.row(), parser.column(), "Expression \"" + expressionIdentifier + "\" not allowed in this context");
throw utils::ParserException(parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
}
return expression;
@ -214,7 +214,7 @@ ExpressionPointer parsePredicate(utils::Parser &parser, Context &context,
// If predicate exists, parse it
if (match == context.predicateDeclarations.cend())
throw utils::ParserException(parser.row(), parser.column(), "Unknown predicate \"" + predicateName + "\"");
throw utils::ParserException(parser, "Unknown predicate \"" + predicateName + "\"");
expression = expressions::Predicate::parse(predicateName, parser, context, parameters);

View File

@ -86,7 +86,7 @@ Requirement Requirement::parse(utils::Parser &parser)
const auto match = requirementTypesToPDDL.right.find(requirementName);
if (match == requirementTypesToPDDL.right.end())
throw utils::ParserException(parser.row(), parser.column(), "Unknown PDDL requirement \"" + requirementName + "\"");
throw utils::ParserException(parser, "Unknown PDDL requirement \"" + requirementName + "\"");
return Requirement(match->second);
}

View File

@ -81,6 +81,27 @@ void Constant::parseTypedDeclaration(utils::Parser &parser, Context &context)
////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseExisting(utils::Parser &parser, Context &context)
{
parser.skipWhiteSpace();
const auto constantName = parser.parseIdentifier(isIdentifier);
// TODO: use hash map
const auto match = std::find_if(context.constants.cbegin(), context.constants.cend(),
[&](const auto &constant)
{
return constant->name() == constantName;
});
const auto constantExists = (match != context.constants.cend());
if (!constantExists)
throw utils::ParserException(parser, "Constant \"" + constantName + "\" used but never declared");
return match->get();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Constant::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
{
expressionVisitor.visit(*this);

View File

@ -49,7 +49,7 @@ PredicatePointer Predicate::parse(std::string name, utils::Parser &parser,
// Parse constants
else
{
const auto *constant = Constant::parseExisting(parser, context.constants);
const auto *constant = Constant::parseExisting(parser, context);
auto constantReference = std::make_unique<Reference<Constant>>(constant);
predicate->m_arguments.emplace_back(std::move(constantReference));
}

View File

@ -116,7 +116,7 @@ const Variable *Variable::parseExisting(utils::Parser &parser, const Variables &
});
if (match == variables.cend())
throw utils::ParserException(parser.row(), parser.column(), "Variable \"" + variableName + "\" used but never declared");
throw utils::ParserException(parser, "Variable \"" + variableName + "\" used but never declared");
return match->get();
}

View File

@ -153,7 +153,7 @@ void Description::parseVersionSection(utils::Parser &parser) const
const auto formatVersion = parser.parse<size_t>();
if (formatVersion != 3)
throw utils::ParserException(parser.row(), parser.column(), "Unsupported SAS format version (" + std::to_string(formatVersion) + ")");
throw utils::ParserException(parser, "Unsupported SAS format version (" + std::to_string(formatVersion) + ")");
parser.expect<std::string>("end_version");
}

View File

@ -29,7 +29,7 @@ MutexGroup MutexGroup::fromSAS(utils::Parser &parser, const Variables &variables
mutexGroup.m_facts.emplace_back(Fact::fromSAS(parser, variables));
if (mutexGroup.m_facts[j].value() == Value::None)
throw utils::ParserException(parser.row(), parser.column(), "Mutex groups must not contain <none of those> values");
throw utils::ParserException(parser, "Mutex groups must not contain <none of those> values");
}
parser.expect<std::string>("end_mutex_group");

View File

@ -46,7 +46,7 @@ Predicate Predicate::fromSAS(utils::Parser &parser)
}
catch (const std::exception &e)
{
throw utils::ParserException(parser.row(), parser.column(), "Could not parse operator predicate");
throw utils::ParserException(parser, "Could not parse operator predicate");
}
return predicate;

View File

@ -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.row(), parser.column(), "Invalid value sign \"" + sasSign + "\"");
throw utils::ParserException(parser, "Invalid value sign \"" + sasSign + "\"");
try
{
@ -90,7 +90,7 @@ Value Value::fromSAS(utils::Parser &parser)
}
catch (const std::exception &e)
{
throw utils::ParserException(parser.row(), parser.column(), std::string("Could not parse variable value (") + e.what() + ")");
throw utils::ParserException(parser, std::string("Could not parse variable value (") + e.what() + ")");
}
return value;
@ -106,7 +106,7 @@ const Value &Value::referenceFromSAS(utils::Parser &parser, const Variable &vari
return Value::Any;
if (valueID < 0 || static_cast<size_t>(valueID) >= variable.values().size())
throw utils::ParserException(parser.row(), parser.column(), "Value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")");
throw utils::ParserException(parser, "Value index out of range (variable " + variable.name() + ", index " + std::to_string(valueID) + ")");
return variable.values()[valueID];
}

View File

@ -41,7 +41,7 @@ Variable Variable::fromSAS(utils::Parser &parser)
// <none of those> values are only allowed at the end
if (j < numberOfValues - 1 && variable.m_values[j] == Value::None)
throw utils::ParserException(parser.row(), parser.column(), "<none of those> value must be the last value of a variable");
throw utils::ParserException(parser, "<none of those> value must be the last value of a variable");
}
parser.expect<std::string>("end_variable");
@ -63,7 +63,7 @@ const Variable &Variable::referenceFromSAS(utils::Parser &parser, const Variable
const auto variableID = parser.parse<size_t>();
if (variableID >= variables.size())
throw utils::ParserException(parser.row(), parser.column(), "Variable index out of range (index " + std::to_string(variableID) + ")");
throw utils::ParserException(parser, "Variable index out of range (index " + std::to_string(variableID) + ")");
return variables[variableID];
}

View File

@ -71,10 +71,10 @@ bool Parser::atEndOfFile() const
void Parser::checkStream() const
{
if (atEndOfFile())
throw ParserException(m_row, m_column, "Reading past end of file");
throw ParserException(*this, "Reading past end of file");
if (m_istream.fail())
throw ParserException(m_row, m_column);
throw ParserException(*this);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -196,7 +196,7 @@ void Parser::expect<std::string>(const std::string &expectedValue)
const auto character = static_cast<char>(this->currentCharacter());
if (character != expectedCharacter)
throw ParserException(m_row, m_column, "Unexpected string, expected \"" + expectedValue + "\" (expected character '" + expectedCharacter + "', got '" + character + "')");
throw ParserException(*this, "Unexpected string, expected \"" + expectedValue + "\" (expected character '" + expectedCharacter + "', got '" + character + "')");
this->advance();
});
@ -209,7 +209,7 @@ uint64_t Parser::parseIntegerBody()
checkStream();
if (!std::isdigit(currentCharacter()))
throw ParserException(m_row, m_column, "Could not parse integer value");
throw ParserException(*this, "Could not parse integer value");
uint64_t value = 0;
@ -251,7 +251,7 @@ uint64_t Parser::parse<uint64_t>()
skipWhiteSpace();
if (currentCharacter() == '-')
throw ParserException(m_row, m_column, "Expected unsigned integer, got signed one");
throw ParserException(*this, "Expected unsigned integer, got signed one");
return parseIntegerBody();
}
@ -264,7 +264,7 @@ 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));
throw ParserException(*this, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -275,7 +275,7 @@ 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));
throw ParserException(*this, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -387,7 +387,7 @@ bool Parser::parse<bool>()
if (advanceIf('1'))
return true;
throw ParserException(m_row, m_column, "Could not parse Boolean value");
throw ParserException(*this, "Could not parse Boolean value");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -398,7 +398,7 @@ 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));
throw ParserException(*this, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue));
}
////////////////////////////////////////////////////////////////////////////////////////////////////