#pragma once #include "AST/NumberNode.h" #include "Error.h" #include "Lexer.h" #include "sapphirepch.h" /* Parser class for the Sapphire compiler. */ class Parser { /* Struct to store a parsing result which can be either a parsing error or a success, in which case it contains a * pointer to the result. */ template struct ErrorOr { /* Return the stored pointer. */ std::shared_ptr get() { assert(!m_is_error); return m_ptr; } /* Call Error::throw_error() with the stored error's location, line text, and the error string provided to this * struct instance. */ void ethrow() { assert(m_is_error); Error::throw_error(error_tok->loc, error_tok->line(), m_error); } /* Construct a new successful ErrorOr with a heap-allocated pointer to the result class. */ ErrorOr(T* ptr) : m_ptr(ptr), m_is_error(false) { } /* Construct a new failed ErrorOr with the error details and the token where parsing failed. */ ErrorOr(const std::string& error, const Token& error_tok) : m_error(error), m_is_error(true), error_tok(error_tok) { } /* Is this ErrorOr instance successful or failed? */ bool is_error() { return m_is_error; } private: bool m_is_error; std::string m_error; std::unique_ptr error_tok; std::shared_ptr m_ptr; }; private: Parser(const TokenStream& tokens); TokenStream tokens; ErrorOr walk_expr(); ErrorOr walk_number(); int m_index; int saved_m_index; void save_current_position(); void restore_current_position(); public: ~Parser(); /* Construct a new Parser with the given TokenStream. */ static std::shared_ptr new_parser(const TokenStream& tokens); /* Parse the stored TokenStream and return the top-level node of the result Abstract Syntax Tree. */ std::shared_ptr parse(); };