2022-10-17 22:26:36 -03:00
|
|
|
#include "ast/call_expression_ast.h"
|
|
|
|
#include "ast/number_expression_ast.h"
|
|
|
|
#include "ast/variable_expression_ast.h"
|
|
|
|
#include "parser.h"
|
|
|
|
|
2022-11-04 11:19:53 -03:00
|
|
|
#include <memory>
|
2022-11-08 22:27:26 -03:00
|
|
|
#include <stack>
|
2022-11-22 11:34:07 -03:00
|
|
|
#include <string>
|
2022-11-08 22:27:26 -03:00
|
|
|
#include <vector>
|
|
|
|
|
2023-02-13 23:03:31 -03:00
|
|
|
std::shared_ptr<obelisk::Lexer> obelisk::Parser::getLexer()
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
2023-02-13 23:03:31 -03:00
|
|
|
return lexer_;
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
|
2023-02-13 23:03:31 -03:00
|
|
|
void obelisk::Parser::setLexer(std::shared_ptr<obelisk::Lexer> lexer)
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
2023-02-13 23:03:31 -03:00
|
|
|
lexer_ = lexer;
|
|
|
|
currentToken_ = 0;
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
int obelisk::Parser::getNextToken()
|
|
|
|
{
|
2022-11-30 22:44:35 -03:00
|
|
|
try
|
|
|
|
{
|
|
|
|
setCurrentToken(getLexer()->getToken());
|
|
|
|
}
|
|
|
|
catch (obelisk::LexerException& exception)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
2022-10-17 22:26:36 -03:00
|
|
|
return getCurrentToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
int obelisk::Parser::getCurrentToken()
|
|
|
|
{
|
|
|
|
return currentToken_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void obelisk::Parser::setCurrentToken(int currentToken)
|
|
|
|
{
|
|
|
|
currentToken_ = currentToken;
|
|
|
|
}
|
|
|
|
|
2022-12-13 17:35:14 -03:00
|
|
|
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::logError(const char* str)
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
|
|
|
fprintf(stderr, "Error: %s\n", str);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-12-13 17:35:14 -03:00
|
|
|
std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::logErrorPrototype(const char* str)
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
|
|
|
logError(str);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseExpression()
|
|
|
|
{
|
|
|
|
auto LHS = parsePrimary();
|
|
|
|
if (!LHS)
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LHS;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parsePrimary()
|
|
|
|
{
|
|
|
|
switch (getCurrentToken())
|
|
|
|
{
|
|
|
|
case obelisk::Lexer::kTokenIdentifier :
|
|
|
|
return parseIdentifierExpression();
|
|
|
|
case obelisk::Lexer::kTokenNumber :
|
|
|
|
return parseNumberExpression();
|
|
|
|
case '(' :
|
|
|
|
return parseParenthesisExpression();
|
|
|
|
default :
|
|
|
|
return logError("unknown token when expecting and expression");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseNumberExpression()
|
|
|
|
{
|
2022-12-13 17:35:14 -03:00
|
|
|
auto result = std::make_unique<obelisk::NumberExpressionAST>(getLexer()->getNumberValue());
|
2022-10-17 22:26:36 -03:00
|
|
|
getNextToken();
|
2022-11-04 11:19:53 -03:00
|
|
|
return result;
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
|
2022-12-13 17:35:14 -03:00
|
|
|
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseParenthesisExpression()
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
|
|
|
getNextToken();
|
|
|
|
auto v = parseExpression();
|
|
|
|
if (!v)
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getCurrentToken() != ')')
|
|
|
|
{
|
|
|
|
return logError("expected ')'");
|
|
|
|
}
|
|
|
|
getNextToken();
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2022-12-13 17:35:14 -03:00
|
|
|
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseIdentifierExpression()
|
2022-10-17 22:26:36 -03:00
|
|
|
{
|
|
|
|
std::string idName = getLexer()->getIdentifier();
|
|
|
|
getNextToken();
|
|
|
|
if (getCurrentToken() != '(')
|
|
|
|
{
|
|
|
|
return std::make_unique<obelisk::VariableExpressionAST>(idName);
|
|
|
|
}
|
|
|
|
|
|
|
|
getNextToken();
|
|
|
|
std::vector<std::unique_ptr<obelisk::ExpressionAST>> args;
|
|
|
|
if (getCurrentToken() != ')')
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (auto arg = parseExpression())
|
|
|
|
{
|
|
|
|
args.push_back(std::move(arg));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getCurrentToken() == ')')
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getCurrentToken() != ',')
|
|
|
|
{
|
|
|
|
return logError("Expected ')' or ',' in argument list");
|
|
|
|
}
|
|
|
|
|
|
|
|
getNextToken();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getNextToken();
|
|
|
|
return std::make_unique<CallExpressionAST>(idName, std::move(args));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::parsePrototype()
|
|
|
|
{
|
|
|
|
if (getCurrentToken() != obelisk::Lexer::kTokenIdentifier)
|
|
|
|
{
|
|
|
|
return logErrorPrototype("Expected function name in prototype");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string functionName = getLexer()->getIdentifier();
|
|
|
|
getNextToken();
|
|
|
|
|
|
|
|
if (getCurrentToken() != '(')
|
|
|
|
{
|
|
|
|
return logErrorPrototype("Expected '(' in prototype");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> argNames;
|
|
|
|
while (getNextToken() == obelisk::Lexer::kTokenIdentifier)
|
|
|
|
{
|
|
|
|
argNames.push_back(getLexer()->getIdentifier());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getCurrentToken() != ')')
|
|
|
|
{
|
|
|
|
return logErrorPrototype("Expected ')' in prototype");
|
|
|
|
}
|
|
|
|
|
|
|
|
getNextToken();
|
|
|
|
|
2022-12-13 17:35:14 -03:00
|
|
|
return std::make_unique<obelisk::PrototypeAST>(functionName, std::move(argNames));
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseDefinition()
|
|
|
|
{
|
|
|
|
getNextToken();
|
|
|
|
auto prototype = parsePrototype();
|
|
|
|
if (!prototype)
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (auto expression = parseExpression())
|
|
|
|
{
|
2022-12-13 17:35:14 -03:00
|
|
|
return std::make_unique<FunctionAST>(std::move(prototype), std::move(expression));
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseTopLevelExpression()
|
|
|
|
{
|
|
|
|
if (auto expression = parseExpression())
|
|
|
|
{
|
|
|
|
// Make an anonymous prototype
|
2022-12-13 17:35:14 -03:00
|
|
|
auto prototype = std::make_unique<obelisk::PrototypeAST>("__anon_expr", std::vector<std::string>());
|
|
|
|
return std::make_unique<obelisk::FunctionAST>(std::move(prototype), std::move(expression));
|
2022-10-17 22:26:36 -03:00
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::parseExtern()
|
|
|
|
{
|
|
|
|
getNextToken();
|
|
|
|
return parsePrototype();
|
|
|
|
}
|
2022-11-08 22:27:26 -03:00
|
|
|
|
2023-02-16 00:35:29 -03:00
|
|
|
void obelisk::Parser::parseAction(obelisk::SuggestAction& suggestAction)
|
2022-11-08 22:27:26 -03:00
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
std::stack<char> syntax;
|
|
|
|
|
|
|
|
getNextToken();
|
|
|
|
if (getCurrentToken() != '(')
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("expected '(' but got '" + std::to_string(getCurrentToken()) + "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
syntax.push('(');
|
|
|
|
|
|
|
|
getNextToken();
|
|
|
|
if (getLexer()->getIdentifier() != "if")
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("expected 'if' but got '" + getLexer()->getIdentifier() + "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool getEntity {true};
|
|
|
|
std::string leftEntity {""};
|
|
|
|
std::string rightEntity {""};
|
|
|
|
std::string trueAction {""};
|
|
|
|
std::string falseAction {""};
|
|
|
|
std::string entityName {""};
|
|
|
|
std::string verb {""};
|
|
|
|
getNextToken();
|
|
|
|
|
|
|
|
// get the entity side of statement
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (getEntity)
|
|
|
|
{
|
|
|
|
if (getCurrentToken() == '"')
|
|
|
|
{
|
|
|
|
if (syntax.top() != '"')
|
|
|
|
{
|
|
|
|
// open a double quote
|
|
|
|
syntax.push('"');
|
|
|
|
getNextToken();
|
|
|
|
}
|
|
|
|
else if (syntax.top() == '"')
|
|
|
|
{
|
|
|
|
// close a double quote
|
|
|
|
syntax.pop();
|
|
|
|
if (verb == "")
|
|
|
|
{
|
|
|
|
leftEntity = entityName;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rightEntity = entityName;
|
|
|
|
}
|
|
|
|
entityName = "";
|
|
|
|
getEntity = false;
|
|
|
|
getNextToken();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (syntax.top() == '"')
|
|
|
|
{
|
|
|
|
if (entityName != "")
|
|
|
|
{
|
|
|
|
entityName += " ";
|
|
|
|
}
|
|
|
|
entityName += getLexer()->getIdentifier();
|
|
|
|
}
|
|
|
|
getNextToken();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (getCurrentToken() == ')')
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("unexpected ')'");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getCurrentToken() == '"')
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("unexpected '\"'");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getLexer()->getIdentifier() == "and")
|
|
|
|
{
|
|
|
|
getNextToken();
|
|
|
|
getEntity = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (getLexer()->getIdentifier() == "then")
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
verb = getLexer()->getIdentifier();
|
|
|
|
// TODO: make sure verb is alphabetic
|
|
|
|
getEntity = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the action side of statement
|
|
|
|
bool getAction {true};
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
if (getAction)
|
|
|
|
{
|
|
|
|
if (getCurrentToken() == '"')
|
|
|
|
{
|
|
|
|
if (syntax.top() != '"')
|
|
|
|
{
|
|
|
|
// open a double quote
|
|
|
|
syntax.push('"');
|
|
|
|
getNextToken();
|
|
|
|
}
|
|
|
|
else if (syntax.top() == '"')
|
|
|
|
{
|
|
|
|
// close a double quote
|
|
|
|
syntax.pop();
|
|
|
|
if (trueAction == "")
|
|
|
|
{
|
|
|
|
trueAction = entityName;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
falseAction = entityName;
|
|
|
|
}
|
|
|
|
entityName = "";
|
|
|
|
getAction = false;
|
|
|
|
getNextToken();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (syntax.top() == '"')
|
|
|
|
{
|
|
|
|
if (entityName != "")
|
|
|
|
{
|
|
|
|
entityName += " ";
|
|
|
|
}
|
|
|
|
entityName += getLexer()->getIdentifier();
|
|
|
|
}
|
|
|
|
getNextToken();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (getCurrentToken() == ')')
|
|
|
|
{
|
|
|
|
// closing parenthesis found, make sure we have everything needed
|
|
|
|
if (syntax.top() != '(')
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("unexpected ')'");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
syntax.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trueAction == "")
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("missing true action");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (falseAction == "")
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("missing false action");
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getCurrentToken() == '"')
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("unexpected '\"'");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-02-18 21:06:42 -03:00
|
|
|
if (getLexer()->getIdentifier() == "else")
|
2023-02-16 00:35:29 -03:00
|
|
|
{
|
|
|
|
getNextToken();
|
|
|
|
getAction = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
getAction = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
suggestAction.setFact(
|
|
|
|
obelisk::Fact(obelisk::Entity(leftEntity), obelisk::Entity(rightEntity), obelisk::Verb(verb)));
|
|
|
|
suggestAction.setTrueAction(obelisk::Action(trueAction));
|
2023-02-18 21:06:42 -03:00
|
|
|
suggestAction.setFalseAction(obelisk::Action(falseAction));
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|
|
|
|
|
2023-02-16 00:35:29 -03:00
|
|
|
void obelisk::Parser::parseRule(std::vector<obelisk::Rule>& rules)
|
2022-11-08 22:27:26 -03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-11-26 00:32:06 -03:00
|
|
|
void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
|
2022-11-08 22:27:26 -03:00
|
|
|
{
|
|
|
|
std::stack<char> syntax;
|
|
|
|
|
|
|
|
getNextToken();
|
|
|
|
if (getCurrentToken() != '(')
|
|
|
|
{
|
2022-12-13 17:35:14 -03:00
|
|
|
throw obelisk::ParserException("expected '(' but got '" + std::to_string(getCurrentToken()) + "'");
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
syntax.push('(');
|
|
|
|
|
|
|
|
bool getEntity {true};
|
|
|
|
std::vector<std::string> leftEntities;
|
2022-11-09 16:49:58 -03:00
|
|
|
std::vector<std::string> rightEntities;
|
2022-11-08 22:27:26 -03:00
|
|
|
std::string entityName {""};
|
2022-11-09 16:49:58 -03:00
|
|
|
std::string verb {""};
|
2022-11-08 22:27:26 -03:00
|
|
|
getNextToken();
|
2023-02-16 00:35:29 -03:00
|
|
|
while (true)
|
2022-11-08 22:27:26 -03:00
|
|
|
{
|
|
|
|
if (getEntity)
|
|
|
|
{
|
|
|
|
if (getCurrentToken() == '"')
|
|
|
|
{
|
|
|
|
if (syntax.top() != '"')
|
|
|
|
{
|
|
|
|
// open a double quote
|
|
|
|
syntax.push('"');
|
2022-11-09 16:49:58 -03:00
|
|
|
getNextToken();
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|
|
|
|
else if (syntax.top() == '"')
|
|
|
|
{
|
|
|
|
// close a double quote
|
|
|
|
syntax.pop();
|
2022-11-09 16:49:58 -03:00
|
|
|
if (verb == "")
|
|
|
|
{
|
|
|
|
leftEntities.push_back(entityName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rightEntities.push_back(entityName);
|
|
|
|
}
|
2022-11-08 22:27:26 -03:00
|
|
|
entityName = "";
|
2022-11-09 16:49:58 -03:00
|
|
|
getEntity = false;
|
|
|
|
getNextToken();
|
|
|
|
continue;
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (syntax.top() == '"')
|
|
|
|
{
|
|
|
|
if (entityName != "")
|
|
|
|
{
|
|
|
|
entityName += " ";
|
|
|
|
}
|
|
|
|
entityName += getLexer()->getIdentifier();
|
|
|
|
}
|
|
|
|
getNextToken();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-11-09 16:49:58 -03:00
|
|
|
if (getCurrentToken() == ')')
|
|
|
|
{
|
2022-11-22 11:34:07 -03:00
|
|
|
// closing parenthesis found, make sure we have everything needed
|
2023-02-16 00:35:29 -03:00
|
|
|
if (syntax.top() != '(')
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("unexpected ')'");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
syntax.pop();
|
|
|
|
}
|
|
|
|
|
2022-11-22 11:34:07 -03:00
|
|
|
if (verb == "")
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("verb is empty");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (leftEntities.size() == 0)
|
|
|
|
{
|
2022-12-13 17:35:14 -03:00
|
|
|
throw obelisk::ParserException("missing left side entities");
|
2022-11-22 11:34:07 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (rightEntities.size() == 0)
|
|
|
|
{
|
2022-12-13 17:35:14 -03:00
|
|
|
throw obelisk::ParserException("missing right side entities");
|
2022-11-22 11:34:07 -03:00
|
|
|
}
|
2023-02-16 00:35:29 -03:00
|
|
|
|
2022-11-09 16:49:58 -03:00
|
|
|
break;
|
|
|
|
}
|
2022-11-08 22:27:26 -03:00
|
|
|
|
2022-11-09 16:49:58 -03:00
|
|
|
if (getCurrentToken() == '"')
|
|
|
|
{
|
2022-11-22 11:34:07 -03:00
|
|
|
throw obelisk::ParserException("unexpected '\"'");
|
2022-11-09 16:49:58 -03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getLexer()->getIdentifier() == "and")
|
|
|
|
{
|
|
|
|
getNextToken();
|
|
|
|
getEntity = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
verb = getLexer()->getIdentifier();
|
2022-11-30 22:44:35 -03:00
|
|
|
// TODO: make sure verb is alphabetic
|
2022-11-09 16:49:58 -03:00
|
|
|
getEntity = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|
2022-11-09 16:49:58 -03:00
|
|
|
|
2022-11-26 00:32:06 -03:00
|
|
|
for (auto& leftEntity : leftEntities)
|
|
|
|
{
|
|
|
|
for (auto& rightEntity : rightEntities)
|
|
|
|
{
|
2022-12-13 17:35:14 -03:00
|
|
|
facts.push_back(
|
2023-02-15 21:49:53 -03:00
|
|
|
obelisk::Fact(obelisk::Entity(leftEntity), obelisk::Entity(rightEntity), obelisk::Verb(verb), true));
|
2022-11-26 00:32:06 -03:00
|
|
|
}
|
|
|
|
}
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|
|
|
|
|
2022-11-26 00:32:06 -03:00
|
|
|
void obelisk::Parser::handleAction(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
2022-11-08 22:27:26 -03:00
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
obelisk::SuggestAction suggestAction;
|
|
|
|
parseAction(suggestAction);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
insertEntity(kb, suggestAction.getFact().getLeftEntity());
|
|
|
|
insertEntity(kb, suggestAction.getFact().getRightEntity());
|
|
|
|
insertVerb(kb, suggestAction.getFact().getVerb());
|
|
|
|
insertFact(kb, suggestAction.getFact());
|
2023-02-18 21:06:42 -03:00
|
|
|
insertAction(kb, suggestAction.getTrueAction());
|
|
|
|
insertAction(kb, suggestAction.getFalseAction());
|
2023-02-16 00:35:29 -03:00
|
|
|
|
|
|
|
// TODO: insert the actions, then insert the suggested action
|
|
|
|
}
|
|
|
|
catch (obelisk::ParserException& exception)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|
|
|
|
|
2022-11-26 00:32:06 -03:00
|
|
|
void obelisk::Parser::handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
2022-11-08 22:27:26 -03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-11-26 00:32:06 -03:00
|
|
|
void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
2022-11-08 22:27:26 -03:00
|
|
|
{
|
2022-11-26 00:32:06 -03:00
|
|
|
std::vector<obelisk::Fact> facts;
|
2023-02-16 00:35:29 -03:00
|
|
|
try
|
|
|
|
{
|
|
|
|
parseFact(facts);
|
|
|
|
}
|
|
|
|
catch (obelisk::ParserException& exception)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
2022-11-26 00:32:06 -03:00
|
|
|
|
|
|
|
int verbId = 0;
|
|
|
|
for (auto& fact : facts)
|
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
try
|
2022-11-27 23:58:40 -03:00
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
insertEntity(kb, fact.getLeftEntity());
|
|
|
|
insertEntity(kb, fact.getRightEntity());
|
2022-11-27 23:58:40 -03:00
|
|
|
}
|
2023-02-16 00:35:29 -03:00
|
|
|
catch (obelisk::ParserException& exception)
|
2022-11-27 23:58:40 -03:00
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
throw;
|
2022-11-27 23:58:40 -03:00
|
|
|
}
|
|
|
|
|
2022-11-26 00:32:06 -03:00
|
|
|
if (verbId == 0)
|
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
try
|
2022-11-26 00:32:06 -03:00
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
insertVerb(kb, fact.getVerb());
|
2022-11-26 00:32:06 -03:00
|
|
|
}
|
2023-02-16 00:35:29 -03:00
|
|
|
catch (obelisk::ParserException& exception)
|
2022-11-26 00:32:06 -03:00
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
throw;
|
2022-11-26 00:32:06 -03:00
|
|
|
}
|
2023-02-16 00:35:29 -03:00
|
|
|
verbId = fact.getVerb().getId();
|
2022-11-26 00:32:06 -03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fact.getVerb().setId(verbId);
|
|
|
|
}
|
|
|
|
|
2023-02-16 00:35:29 -03:00
|
|
|
try
|
|
|
|
{
|
|
|
|
insertFact(kb, fact);
|
|
|
|
}
|
|
|
|
catch (obelisk::ParserException& exception)
|
|
|
|
{
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void obelisk::Parser::insertEntity(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Entity& entity)
|
|
|
|
{
|
|
|
|
std::vector<obelisk::Entity> entities {entity};
|
|
|
|
kb->addEntities(entities);
|
|
|
|
entity = std::move(entities.front());
|
|
|
|
|
|
|
|
// the id was not inserted, so check if it exists in the database
|
|
|
|
if (entity.getId() == 0)
|
|
|
|
{
|
|
|
|
kb->getEntity(entity);
|
|
|
|
if (entity.getId() == 0)
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("entity could not be inserted into the database");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void obelisk::Parser::insertVerb(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Verb& verb)
|
|
|
|
{
|
|
|
|
std::vector<obelisk::Verb> verbs {verb};
|
|
|
|
kb->addVerbs(verbs);
|
|
|
|
verb = std::move(verbs.front());
|
|
|
|
|
|
|
|
// the id was not inserted, so check if it exists in the database
|
|
|
|
if (verb.getId() == 0)
|
|
|
|
{
|
|
|
|
kb->getVerb(verb);
|
|
|
|
if (verb.getId() == 0)
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("verb could not be inserted into the database");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-18 21:06:42 -03:00
|
|
|
void obelisk::Parser::insertAction(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Action& action)
|
|
|
|
{
|
|
|
|
std::vector<obelisk::Action> actions {action};
|
|
|
|
kb->addActions(actions);
|
|
|
|
action = std::move(actions.front());
|
|
|
|
|
|
|
|
// the id was not inserted, so check if it exists in the database
|
|
|
|
if (action.getId() == 0)
|
|
|
|
{
|
|
|
|
kb->getAction(action);
|
|
|
|
if (action.getId() == 0)
|
|
|
|
{
|
|
|
|
throw obelisk::ParserException("action could not be inserted into the database");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-16 00:35:29 -03:00
|
|
|
void obelisk::Parser::insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Fact& fact)
|
|
|
|
{
|
|
|
|
std::vector<obelisk::Fact> facts {fact};
|
|
|
|
kb->addFacts(facts);
|
|
|
|
fact = std::move(facts.front());
|
2022-11-30 22:44:35 -03:00
|
|
|
|
2023-02-16 00:35:29 -03:00
|
|
|
// the id was not inserted, so check if it exists in the database
|
|
|
|
if (fact.getId() == 0)
|
|
|
|
{
|
|
|
|
kb->getFact(fact);
|
2022-11-30 22:44:35 -03:00
|
|
|
if (fact.getId() == 0)
|
|
|
|
{
|
2023-02-16 00:35:29 -03:00
|
|
|
throw obelisk::ParserException("fact could not be inserted into the database");
|
2022-11-30 22:44:35 -03:00
|
|
|
}
|
2022-11-26 00:32:06 -03:00
|
|
|
}
|
2022-11-08 22:27:26 -03:00
|
|
|
}
|