#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 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 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 Returns the AST * expression that caused the error. */ std::unique_ptr logError(const char* str); /** * @brief Log errors from the LLVM parsing involving the prototypes. * * @param[in] str The error message. * @return std::unique_ptr Returns the AST * for the prototype. */ std::unique_ptr logErrorPrototype( const char* str); /** * @brief The AST expression parser. * * @return std::unique_ptr Returns the * parsed AST expression. */ std::unique_ptr parseExpression(); /** * @brief The AST number expression parser. * * @return std::unique_ptr Returns the * parsed AST expression. */ std::unique_ptr parseNumberExpression(); /** * @brief The AST parenthesis expression parser. * * @return std::unique_ptr Returns the * parsed AST expression. */ std::unique_ptr parseParenthesisExpression(); /** * @brief The AST identifier expression parser. * * @return std::unique_ptr Returns the * parsed AST expression. */ std::unique_ptr parseIdentifierExpression(); /** * @brief The AST primary expression parser. * * @return std::unique_ptr Returns the * parsed AST expression. */ std::unique_ptr parsePrimary(); /** * @brief The AST prototype parser. * * @return std::unique_ptr Returns the parsed * AST prototype expression. */ std::unique_ptr parsePrototype(); /** * @brief The AST definition parser. * * @return std::unique_ptr Returns the parsed * AST definition expression. */ std::unique_ptr parseDefinition(); /** * @brief The AST top level expression parser. * * @return std::unique_ptr Returns the parsed * AST top level expression. */ std::unique_ptr parseTopLevelExpression(); /** * @brief The AST external definition parser. * * @return std::unique_ptr Returns the parsed * AST external definition. */ std::unique_ptr 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& 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 lexer) : lexer_(lexer) { } /** * @brief Get the Lexer. * * @return std::shared_ptr Returns the current Lexer * in use by the Parser. */ std::shared_ptr getLexer(); /** * @brief Set the Lexer to use during the parsing phase. * * @param[in] lexer The Lexer. */ void setLexer(std::shared_ptr 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& 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& 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& 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& 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& 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& 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& 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& 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& 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