#include "Parser.hpp" #include "lib/Node.hpp" namespace sk { /*explicit*/ Parser::Parser(std::shared_ptr lexer, Logger& logger) : m_lexer { lexer } , m_logger { logger } { } /*virtual*/ Parser::~Parser() { } std::shared_ptr Parser::parse(std::string const& source) { m_lexer->scan(source); std::shared_ptr node; while ( (node = m_lexer->next()) ) { m_tokens.push_back(node); } return parse_prog(); } std::shared_ptr Parser::consume() { assert(m_cursor < m_tokens.size()); auto root = m_tokens[m_cursor]; m_cursor++; return root; } std::shared_ptr Parser::consume(NodeType type) { if (type != m_tokens[m_cursor]->type()) { std::stringstream ss; ss << "expected '" << NodeTypeStr[type] << "' node, got '" << NodeTypeStr[m_tokens[m_cursor]->type()] << "'"; m_logger.log(m_tokens[m_cursor]->loc(), LOGGER_ERROR, ss); } return consume(); } bool Parser::type_is(NodeType type) { return m_cursor < m_tokens.size() && m_tokens[m_cursor]->type() == type; } Loc Parser::loc() const { assert(m_cursor < m_tokens.size()); return m_tokens[m_cursor]->loc(); } std::shared_ptr Parser::parse_prog() { auto root = std::make_shared(NODE_PROG, "", m_lexer->loc()); while (m_cursor < m_tokens.size()) { root->add_child(parse_builtins()); } return root; } std::shared_ptr Parser::parse_builtins() { if (type_is(NODE_INT) || type_is(NODE_FLOAT) || type_is(NODE_BOOL) || type_is(NODE_STRING)) { return consume(); } std::stringstream ss; ss << "unknown node of type '" << NodeTypeStr[m_tokens[m_cursor]->type()] << "'"; m_logger.log(loc(), LOGGER_ERROR, ss); return nullptr; } }