Refactored parsing variables, constants, and predicates.

This commit is contained in:
Patrick Lühne 2017-06-17 18:00:26 +02:00
parent 0de5b9eb56
commit 51249fd678
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
6 changed files with 103 additions and 53 deletions

View File

@ -16,6 +16,7 @@ namespace detail
//
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::ConstantPointer> testParsingConstant(Context &context, ASTContext &astContext);
ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext);
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -17,6 +17,7 @@ namespace detail
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: rename consistently
std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack);
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -16,6 +16,8 @@ namespace detail
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: find consistent naming scheme
std::experimental::optional<ast::VariablePointer> testParsingVariable(Context &context, VariableStack &variableStack);
ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack);
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -30,48 +30,8 @@ std::experimental::optional<ast::ConstantPointer> findConstant(const std::string
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: remove if unneeded
ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain)
std::experimental::optional<ast::ConstantPointer> 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<ast::ConstantPointer> 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());
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -20,11 +20,11 @@ std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &conte
{
auto &tokenizer = context.tokenizer;
const auto position = tokenizer.position();
const auto previousPosition = tokenizer.position();
if (!tokenizer.testAndSkip<std::string>("("))
{
tokenizer.seek(position);
tokenizer.seek(previousPosition);
return std::experimental::nullopt;
}
@ -53,14 +53,31 @@ std::experimental::optional<ast::PredicatePointer> 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;

View File

@ -14,14 +14,53 @@ namespace detail
//
////////////////////////////////////////////////////////////////////////////////////////////////////
ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack)
std::experimental::optional<std::string> testParsingVariableName(Context &context)
{
auto &tokenizer = context.tokenizer;
if (!tokenizer.testAndReturn<std::string>("?"))
return std::experimental::nullopt;
tokenizer.expect<std::string>("?");
return tokenizer.getIdentifier();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::string parseVariableName(Context &context)
{
auto &tokenizer = context.tokenizer;
tokenizer.expect<std::string>("?");
const auto variableName = tokenizer.getIdentifier();
return tokenizer.getIdentifier();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::experimental::optional<ast::VariablePointer> 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<ast::Variable>(variableDeclaration.value());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack)
{
auto &tokenizer = context.tokenizer;
auto variableName = parseVariableName(context);
auto variableDeclaration = variableStack.findVariableDeclaration(variableName);
if (!variableDeclaration)