diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h b/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h index eb227a3..172590d 100644 --- a/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h @@ -16,6 +16,7 @@ namespace detail // //////////////////////////////////////////////////////////////////////////////////////////////////// +std::experimental::optional testParsingConstant(Context &context, ASTContext &astContext); ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h b/lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h index 760b7f6..d7fa173 100644 --- a/lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h @@ -17,6 +17,7 @@ namespace detail // //////////////////////////////////////////////////////////////////////////////////////////////////// +// TODO: rename consistently std::experimental::optional parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h b/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h index b007d9e..bb8dc20 100644 --- a/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h @@ -16,6 +16,8 @@ namespace detail // //////////////////////////////////////////////////////////////////////////////////////////////////// +// TODO: find consistent naming scheme +std::experimental::optional testParsingVariable(Context &context, VariableStack &variableStack); ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp index 3cd8774..5fa3230 100644 --- a/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp @@ -30,48 +30,8 @@ std::experimental::optional findConstant(const std::string //////////////////////////////////////////////////////////////////////////////////////////////////// -// TODO: remove if unneeded -ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain) +std::experimental::optional findConstant(const std::string &constantName, ASTContext &astContext) { - auto &tokenizer = context.tokenizer; - const auto constantName = tokenizer.getIdentifier(); - - auto constant = findConstant(constantName, domain.constants); - - if (constant) - return std::move(constant.value()); - - throw ParserException(tokenizer.location(), "constant “" + constantName + "” used but never declared"); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// TODO: remove if unneeded -ast::ConstantPointer parseConstant(Context &context, ast::Problem &problem) -{ - auto &tokenizer = context.tokenizer; - const auto constantName = tokenizer.getIdentifier(); - - auto constant = findConstant(constantName, problem.domain->constants); - - if (constant) - return std::move(constant.value()); - - auto object = findConstant(constantName, problem.objects); - - if (object) - return std::move(object.value()); - - throw ParserException(tokenizer.location(), "constant “" + constantName + "” used but never declared"); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext) -{ - auto &tokenizer = context.tokenizer; - const auto constantName = tokenizer.getIdentifier(); - auto constant = findConstant(constantName, astContext.domain->constants); if (constant) @@ -85,7 +45,37 @@ ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext) return std::move(constant.value()); } - throw ParserException(tokenizer.location(), "constant “" + constantName + "” used but never declared"); + return std::experimental::nullopt; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional testParsingConstant(Context &context, ASTContext &astContext) +{ + auto &tokenizer = context.tokenizer; + + const auto constantName = tokenizer.getIdentifier(); + auto constant = findConstant(constantName, astContext); + + if (!constant) + return std::experimental::nullopt; + + return std::move(constant.value()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext) +{ + auto &tokenizer = context.tokenizer; + + const auto constantName = tokenizer.getIdentifier(); + auto constant = findConstant(constantName, astContext); + + if (!constant) + throw ParserException(tokenizer.location(), "undeclared constant “" + constantName + "”"); + + return std::move(constant.value()); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp index b8a2fcb..b3aecbc 100644 --- a/lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp @@ -20,11 +20,11 @@ std::experimental::optional parsePredicate(Context &conte { auto &tokenizer = context.tokenizer; - const auto position = tokenizer.position(); + const auto previousPosition = tokenizer.position(); if (!tokenizer.testAndSkip("(")) { - tokenizer.seek(position); + tokenizer.seek(previousPosition); return std::experimental::nullopt; } @@ -53,14 +53,31 @@ std::experimental::optional parsePredicate(Context &conte // Parse arguments while (tokenizer.currentCharacter() != ')') { - // Parse variables - if (tokenizer.currentCharacter() == '?') - arguments.emplace_back(parseVariable(context, variableStack)); - // Parse constants - else - arguments.emplace_back(parseConstant(context, astContext)); + // Parse argument if it is a variable + auto variable = testParsingVariable(context, variableStack); - tokenizer.skipWhiteSpace(); + if (variable) + { + arguments.emplace_back(std::move(variable.value())); + + tokenizer.skipWhiteSpace(); + continue; + } + + // Parse argument if it is a constant + auto constant = testParsingConstant(context, astContext); + + if (constant) + { + arguments.emplace_back(std::move(constant.value())); + + tokenizer.skipWhiteSpace(); + continue; + } + + // If argument is neither variable nor constant, this is not a valid predicate + tokenizer.seek(previousPosition); + return std::experimental::nullopt; } //const auto &predicates = astContext.domain->predicates; diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp index 31249a3..1da68be 100644 --- a/lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp @@ -14,14 +14,53 @@ namespace detail // //////////////////////////////////////////////////////////////////////////////////////////////////// -ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack) +std::experimental::optional testParsingVariableName(Context &context) +{ + auto &tokenizer = context.tokenizer; + + if (!tokenizer.testAndReturn("?")) + return std::experimental::nullopt; + + tokenizer.expect("?"); + + return tokenizer.getIdentifier(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::string parseVariableName(Context &context) { auto &tokenizer = context.tokenizer; tokenizer.expect("?"); - const auto variableName = tokenizer.getIdentifier(); + return tokenizer.getIdentifier(); +} +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional testParsingVariable(Context &context, VariableStack &variableStack) +{ + auto variableName = testParsingVariableName(context); + + if (!variableName) + return std::experimental::nullopt; + + auto variableDeclaration = variableStack.findVariableDeclaration(variableName.value()); + + if (!variableDeclaration) + return std::experimental::nullopt; + + return std::make_unique(variableDeclaration.value()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack) +{ + auto &tokenizer = context.tokenizer; + + auto variableName = parseVariableName(context); auto variableDeclaration = variableStack.findVariableDeclaration(variableName); if (!variableDeclaration)