obelisk/src/parser.h

336 lines
11 KiB
C++

#ifndef OBELISK_PARSER_H
#define OBELISK_PARSER_H
#include "ast/expression_ast.h"
#include "ast/function_ast.h"
#include "ast/prototype_ast.h"
#include "knowledge_base.h"
#include "lexer.h"
#include "models/action.h"
#include "models/entity.h"
#include "models/fact.h"
#include "models/rule.h"
#include "models/suggest_action.h"
#include "models/verb.h"
#include <memory>
namespace obelisk
{
/**
* @brief The Parser is responsible for analyzing the language's key words
* and taking action based on its analysis.
*
*/
class Parser
{
private:
/**
* @brief The Lexer object that the Parser is using to Parse a
* specific source file.
*
*/
std::shared_ptr<obelisk::Lexer> lexer_;
/**
* @brief The current token that the lexer has retrieved.
*
*/
int currentToken_ = 0;
/**
* @brief Set the current token.
*
* @param[in] currentToken The token should be ASCII character.
*/
void setCurrentToken(int currentToken);
/**
* @brief Log errors from the LLVM parsing.
*
* @param[in] str The error message.
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the AST
* expression that caused the error.
*/
std::unique_ptr<obelisk::ExpressionAST> logError(const char* str);
/**
* @brief Log errors from the LLVM parsing involving the prototypes.
*
* @param[in] str The error message.
* @return std::unique_ptr<obelisk::PrototypeAST> Returns the AST
* for the prototype.
*/
std::unique_ptr<obelisk::PrototypeAST> logErrorPrototype(
const char* str);
/**
* @brief The AST expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the
* parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parseExpression();
/**
* @brief The AST number expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the
* parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parseNumberExpression();
/**
* @brief The AST parenthesis expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the
* parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST>
parseParenthesisExpression();
/**
* @brief The AST identifier expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the
* parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parseIdentifierExpression();
/**
* @brief The AST primary expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the
* parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parsePrimary();
/**
* @brief The AST prototype parser.
*
* @return std::unique_ptr<obelisk::PrototypeAST> Returns the parsed
* AST prototype expression.
*/
std::unique_ptr<obelisk::PrototypeAST> parsePrototype();
/**
* @brief The AST definition parser.
*
* @return std::unique_ptr<obelisk::FunctionAST> Returns the parsed
* AST definition expression.
*/
std::unique_ptr<obelisk::FunctionAST> parseDefinition();
/**
* @brief The AST top level expression parser.
*
* @return std::unique_ptr<obelisk::FunctionAST> Returns the parsed
* AST top level expression.
*/
std::unique_ptr<obelisk::FunctionAST> parseTopLevelExpression();
/**
* @brief The AST external definition parser.
*
* @return std::unique_ptr<obelisk::PrototypeAST> Returns the parsed
* AST external definition.
*/
std::unique_ptr<obelisk::PrototypeAST> parseExtern();
/**
* @brief Parse a SuggestAction.
*
* @param[out] suggestAction The parsed SuggestAction.
*/
void parseAction(obelisk::SuggestAction& suggestAction);
/**
* @brief Parse a Rule.
*
* @param[out] rule The parsed Rule.
*/
void parseRule(obelisk::Rule& rule);
/**
* @brief Parse Facts.
*
* @param[out] facts The parsed Facts.
*/
void parseFact(std::vector<obelisk::Fact>& facts);
public:
/**
* @brief Construct a new Parser object.
*
* @param[in] lexer The lexer the parser uses to retrieve parts of
* the language.
*/
Parser(std::shared_ptr<obelisk::Lexer> lexer) :
lexer_(lexer)
{
}
/**
* @brief Get the Lexer.
*
* @return std::shared_ptr<obelisk::Lexer> Returns the current Lexer
* in use by the Parser.
*/
std::shared_ptr<obelisk::Lexer> getLexer();
/**
* @brief Set the Lexer to use during the parsing phase.
*
* @param[in] lexer The Lexer.
*/
void setLexer(std::shared_ptr<obelisk::Lexer> lexer);
/**
* @brief Gets the current token held inside the Lexer.
*
* @return int Returns the current token.
*/
int getCurrentToken();
/**
* @brief Instructs the Lexer to retrieve a new token.
*
* @return int Returns the next token.
*/
int getNextToken();
/**
* @brief Parse the SuggestAction and then insert it into the
* KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to insert the SuggestAction into.
*/
void handleAction(std::unique_ptr<obelisk::KnowledgeBase>& kb);
/**
* @brief Parse the Rule and then insert it into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to insert the Rule into.
*/
void handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb);
/**
* @brief Parse the Fact and then insert it into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to insert the Fact into.
*/
void handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb);
/**
* @brief Helper used to insert an Entity into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] entity The Entity to insert. It will contain the
* ID of the Entity after inserting it.
*/
void insertEntity(std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::Entity& entity);
/**
* @brief Helper used to insert a Verb into the KnowledgeBase.
*
* @param[in] kb The KnowledegeBase to use.
* @param[in,out] verb The Verb to insert. It will contain the ID of
* the Verb after inserting it.
*/
void insertVerb(std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::Verb& verb);
/**
* @brief Helper used to insert an Action into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] action The Action to insert. It will contain the
* ID of the Action after inserting it.
*/
void insertAction(std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::Action& action);
/**
* @brief Helper used to insert a Fact into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] fact The Fact to insert. It will contain the ID of
* the Fact after inserting it.
* @param[in] updateIsTrue If true, it will update the value of
* is_true in the KnowledgeBase if the Fact already exists.
*/
void insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::Fact& fact,
bool updateIsTrue = false);
/**
* @brief Helper used to insert a SuggestAction into the
* KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] suggestAction The SuggestAction to insert. It will
* contain the ID of the SuggestAction after inserting it.
*/
void insertSuggestAction(
std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::SuggestAction& suggestAction);
/**
* @brief Helper usedto insert a Rule into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] rule The Rule to insert. It will contain the ID of
* the Rule after inserting it.
*/
void insertRule(std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::Rule& rule);
};
/**
* @brief The exceptions thrown by the Parser.
*
*/
class ParserException : public std::exception
{
private:
/**
* @brief The error message.
*
*/
const std::string errorMessage_;
public:
/**
* @brief Construct a new ParserException object.
*
*/
ParserException() :
errorMessage_("an unknown error ocurred")
{
}
/**
* @brief Construct a new ParserException object.
*
* @param[in] errorMessage The error message.
*/
ParserException(const std::string& errorMessage) :
errorMessage_(errorMessage)
{
}
/**
* @brief Return the error message as a C style string.
*
* @return const char* Returns the error message.
*/
const char* what() const noexcept
{
return errorMessage_.c_str();
}
};
} // namespace obelisk
#endif