#include "Parser.hpp" namespace wg { /*explicit*/ Parser::Parser() { } /*virtual*/ Parser::~Parser() { } std::shared_ptr Parser::parse(std::vector> const& tokens) { m_cursor = 0; m_tokens = tokens; return parse_prog(); } Loc Parser::loc() const { return m_tokens[m_cursor]->loc(); } std::shared_ptr Parser::consume(NodeType type) { auto current = m_tokens[m_cursor]; if (current->type() != type) { std::stringstream ss; ss << "type mismatch, expected '" << (NodeTypeStr[type] + strlen("NODE_")) << "', got '" << (NodeTypeStr[current->type()] + strlen("NODE_")) << "'"; loc().error(ss); } else { return consume(); } return nullptr; } std::shared_ptr Parser::consume() { WG_ASSERT(m_cursor < m_tokens.size(), "cannot consume"); auto node = m_tokens[m_cursor]; m_cursor++; return node; } bool Parser::type_is(NodeType type, int lookahead) { if (m_cursor + lookahead >= m_tokens.size()) { return false; } return m_tokens[m_cursor + lookahead]->type() == type; } bool Parser::type_isnt(NodeType type, int lookahead) { return !type_is(type, lookahead); } std::shared_ptr Parser::make_node(NodeType type) const { return std::make_shared(type, "", loc()); } std::shared_ptr Parser::parse_prog() { auto node = std::make_shared(NODE_PROG, "", Loc {}); while (m_cursor < m_tokens.size()) { node->add_child(parse_instr()); } return node; } std::shared_ptr Parser::parse_instr() { return parse_dir(); } std::shared_ptr Parser::parse_dir() { auto node = make_node(NODE_DIR); consume(NODE_HASH); node->add_child(consume(NODE_IDENT)); node->add_child(parse_expr()); return node; } std::shared_ptr Parser::parse_expr() { return consume(NODE_IDENT); } }