elna/include/elna/source/parser.hpp
2024-12-20 15:49:33 +01:00

151 lines
3.7 KiB
C++

#pragma once
#include <cstdint>
#include <memory>
#include <elna/source/lexer.hpp>
namespace elna::source
{
enum class binary_operator
{
sum,
subtraction,
multiplication,
division
};
class definition;
class bang_statement;
class block;
class binary_expression;
class variable_expression;
class integer_literal;
struct parser_visitor
{
virtual void visit(definition *) = 0;
virtual void visit(bang_statement *) = 0;
virtual void visit(block *) = 0;
virtual void visit(binary_expression *) = 0;
virtual void visit(variable_expression *) = 0;
virtual void visit(integer_literal *) = 0;
};
/**
* AST node.
*/
class node
{
public:
virtual void accept(parser_visitor *) = 0;
};
class statement : public node
{
};
class expression : public node
{
};
/**
* Constant definition.
*/
class definition : public node
{
std::string m_identifier;
std::unique_ptr<integer_literal> m_body;
public:
definition(std::string&& identifier, std::unique_ptr<integer_literal>&& body);
virtual void accept(parser_visitor *visitor) override;
std::string& identifier() noexcept;
integer_literal& body();
};
class bang_statement : public statement
{
std::unique_ptr<expression> m_body;
public:
bang_statement(std::unique_ptr<expression>&& body);
virtual void accept(parser_visitor *visitor) override;
expression& body();
};
/**
* Block.
*/
class block : public node
{
std::unique_ptr<statement> m_body;
std::vector<std::unique_ptr<definition>> m_definitions;
public:
block(std::vector<std::unique_ptr<definition>>&& definitions, std::unique_ptr<statement>&& body);
virtual void accept(parser_visitor *visitor) override;
statement& body();
std::vector<std::unique_ptr<definition>>& definitions() noexcept;
};
class integer_literal : public expression
{
std::int32_t m_number;
public:
integer_literal(const std::int32_t value);
virtual void accept(parser_visitor *visitor) override;
std::int32_t number() const noexcept;
};
class variable_expression : public expression
{
std::string m_name;
public:
variable_expression(const std::string& name);
virtual void accept(parser_visitor *visitor) override;
const std::string& name() const noexcept;
};
class binary_expression : public expression
{
std::unique_ptr<expression> m_lhs;
std::unique_ptr<expression> m_rhs;
binary_operator m_operator;
public:
binary_expression(std::unique_ptr<expression>&& lhs,
std::unique_ptr<expression>&& rhs, const unsigned char operation);
virtual void accept(parser_visitor *visitor) override;
expression& lhs();
expression& rhs();
binary_operator operation() const noexcept;
};
struct parser
{
parser(const std::vector<token>& tokens);
std::unique_ptr<block> parse();
private:
std::unique_ptr<expression> parse_factor();
std::unique_ptr<expression> parse_term();
std::unique_ptr<expression> parse_expression();
std::unique_ptr<definition> parse_definition();
std::unique_ptr<statement> parse_bang_statement();
std::vector<std::unique_ptr<definition>> parse_definitions();
std::unique_ptr<block> parse_block();
std::vector<token>::const_iterator tokens;
std::vector<token>::const_iterator end;
};
}