DeveloperBreeze

C++17 Development Tutorials, Guides & Insights

Unlock 1+ expert-curated c++17 tutorials, real-world code snippets, and modern dev strategies. From fundamentals to advanced topics, boost your c++17 skills on DeveloperBreeze.

Implementing a Domain-Specific Language (DSL) with LLVM and C++

Tutorial February 12, 2025

Implementation: Parser.cpp

#include "DSL/Parser.h"
#include <stdexcept>

Parser::Parser(Lexer& lexer) : lexer(lexer) {
    currentToken = lexer.getNextToken();
}

void Parser::eat(TokenType type) {
    if (currentToken.type == type) {
        currentToken = lexer.getNextToken();
    } else {
        throw std::runtime_error("Unexpected token: " + currentToken.text);
    }
}

std::unique_ptr<ASTNode> Parser::factor() {
    if (currentToken.type == TokenType::Number) {
        auto node = std::make_unique<NumberExprAST>(currentToken.value);
        eat(TokenType::Number);
        return node;
    } else if (currentToken.type == TokenType::LParen) {
        eat(TokenType::LParen);
        auto node = parseExpression();
        eat(TokenType::RParen);
        return node;
    }
    throw std::runtime_error("Invalid syntax in factor.");
}

std::unique_ptr<ASTNode> Parser::term() {
    auto node = factor();
    while (currentToken.type == TokenType::Asterisk || currentToken.type == TokenType::Slash) {
        TokenType op = currentToken.type;
        eat(op);
        auto right = factor();
        node = std::make_unique<BinaryExprAST>(op, std::move(node), std::move(right));
    }
    return node;
}

std::unique_ptr<ASTNode> Parser::parseExpression() {
    auto node = term();
    while (currentToken.type == TokenType::Plus || currentToken.type == TokenType::Minus) {
        TokenType op = currentToken.type;
        eat(op);
        auto right = term();
        node = std::make_unique<BinaryExprAST>(op, std::move(node), std::move(right));
    }
    return node;
}