This repository has been archived on 2024-03-07. You can view files and clone it, but cannot push or open issues/pull-requests.
wongola/lib/Parser.cpp

110 lines
2.1 KiB
C++

#include "Parser.hpp"
namespace wg
{
/*explicit*/ Parser::Parser()
{
}
/*virtual*/ Parser::~Parser()
{
}
std::shared_ptr<Node> Parser::parse(std::vector<std::shared_ptr<Node>>
const& tokens)
{
m_cursor = 0;
m_tokens = tokens;
return parse_prog();
}
Loc Parser::loc() const
{
return m_tokens[m_cursor]->loc();
}
std::shared_ptr<Node> 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<syntax_error>(ss);
}
else
{
return consume();
}
return nullptr;
}
std::shared_ptr<Node> 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<Node> Parser::make_node(NodeType type) const
{
return std::make_shared<Node>(type, "", loc());
}
std::shared_ptr<Node> Parser::parse_prog()
{
auto node = std::make_shared<Node>(NODE_PROG, "", Loc {});
while (m_cursor < m_tokens.size())
{
node->add_child(parse_instr());
}
return node;
}
std::shared_ptr<Node> Parser::parse_instr()
{
return parse_dir();
}
std::shared_ptr<Node> 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<Node> Parser::parse_expr()
{
return consume(NODE_IDENT);
}
}