Refactored parsing variables, constants, and predicates.
This commit is contained in:
parent
0de5b9eb56
commit
51249fd678
|
@ -16,6 +16,7 @@ namespace detail
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::experimental::optional<ast::ConstantPointer> testParsingConstant(Context &context, ASTContext &astContext);
|
||||||
ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext);
|
ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace detail
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// TODO: rename consistently
|
||||||
std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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);
|
ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -30,48 +30,8 @@ std::experimental::optional<ast::ConstantPointer> findConstant(const std::string
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// TODO: remove if unneeded
|
std::experimental::optional<ast::ConstantPointer> findConstant(const std::string &constantName, ASTContext &astContext)
|
||||||
ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain)
|
|
||||||
{
|
{
|
||||||
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);
|
auto constant = findConstant(constantName, astContext.domain->constants);
|
||||||
|
|
||||||
if (constant)
|
if (constant)
|
||||||
|
@ -85,7 +45,37 @@ ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext)
|
||||||
return std::move(constant.value());
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -20,11 +20,11 @@ std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &conte
|
||||||
{
|
{
|
||||||
auto &tokenizer = context.tokenizer;
|
auto &tokenizer = context.tokenizer;
|
||||||
|
|
||||||
const auto position = tokenizer.position();
|
const auto previousPosition = tokenizer.position();
|
||||||
|
|
||||||
if (!tokenizer.testAndSkip<std::string>("("))
|
if (!tokenizer.testAndSkip<std::string>("("))
|
||||||
{
|
{
|
||||||
tokenizer.seek(position);
|
tokenizer.seek(previousPosition);
|
||||||
return std::experimental::nullopt;
|
return std::experimental::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,14 +53,31 @@ std::experimental::optional<ast::PredicatePointer> parsePredicate(Context &conte
|
||||||
// Parse arguments
|
// Parse arguments
|
||||||
while (tokenizer.currentCharacter() != ')')
|
while (tokenizer.currentCharacter() != ')')
|
||||||
{
|
{
|
||||||
// Parse variables
|
// Parse argument if it is a variable
|
||||||
if (tokenizer.currentCharacter() == '?')
|
auto variable = testParsingVariable(context, variableStack);
|
||||||
arguments.emplace_back(parseVariable(context, variableStack));
|
|
||||||
// Parse constants
|
|
||||||
else
|
|
||||||
arguments.emplace_back(parseConstant(context, astContext));
|
|
||||||
|
|
||||||
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;
|
//const auto &predicates = astContext.domain->predicates;
|
||||||
|
|
|
@ -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;
|
auto &tokenizer = context.tokenizer;
|
||||||
|
|
||||||
tokenizer.expect<std::string>("?");
|
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);
|
auto variableDeclaration = variableStack.findVariableDeclaration(variableName);
|
||||||
|
|
||||||
if (!variableDeclaration)
|
if (!variableDeclaration)
|
||||||
|
|
Reference in New Issue