bl-compiler

compiler for the bl programming language.
Log | Files | Refs | README

parser.cpp (3943B)


      1 #include <iostream>
      2 
      3 #include "parser.hpp"
      4 
      5 Parser::Parser(const std::vector<Token>& tokens) : tokens_(tokens), position_(0) {}
      6 
      7 std::unique_ptr<Program> Parser::parse() {
      8     auto program = std::make_unique<Program>();
      9 
     10     while (peek().type != TokenType::END_OF_FILE) {
     11         try {
     12             auto statement = parseStatement();
     13             program->declarations.push_back(std::move(statement));
     14             
     15             if (peek().type == TokenType::SEMICOLON) {
     16                 advance();
     17             }
     18         }
     19 
     20         catch (const std::exception& e) {
     21             std::cerr << " Parser error: " << e.what() << std::endl;
     22             break;
     23         }
     24     } 
     25     
     26     return program;
     27 }
     28 
     29 std::unique_ptr<ASTNode> Parser::parseStatement() {
     30     switch(peek().type) {
     31         case TokenType::INT:
     32         case TokenType::STRING:
     33         {
     34             return parseDeclaration();
     35             break;
     36         }
     37 
     38         default:
     39         {
     40             error("Unexpected statement");
     41             return nullptr;
     42         }
     43     }
     44 }
     45 
     46 std::unique_ptr<ASTNode> Parser::parseExpression() {
     47     return parseAddSub(); 
     48 }
     49 
     50 std::unique_ptr<ASTNode> Parser::parseDeclaration() {
     51     std::string type;
     52 
     53     switch(peek().type) {
     54         case TokenType::INT:
     55         {
     56             type = "int";
     57             break;
     58         }
     59 
     60         case TokenType::STRING:
     61         {
     62             type = "string";
     63             break;
     64         }
     65 
     66         default:
     67         {
     68             error("Unexpected declaration: Invalid type");
     69             return nullptr;
     70         }
     71     }
     72     
     73     advance();
     74     std::string name = peek().value;
     75     advance();
     76     if (peek().type == TokenType::ASSIGN) {
     77         advance();
     78         auto value = parseExpression();
     79         return std::make_unique<Declaration>(type, name, std::move(value));
     80     } 
     81 
     82     else if (peek().type == TokenType::SEMICOLON) {
     83         return std::make_unique<Declaration>(type, name); 
     84     }
     85 
     86     else {
     87         error("Invalid declaration");
     88         return nullptr;
     89     }
     90 }
     91 
     92 std::unique_ptr<ASTNode> Parser::parseAssignment() {
     93     std::string name = peek().value;
     94     advance();
     95     advance(); // consume "="
     96     auto value = parseExpression();
     97     return std::make_unique<Assignment>(name, std::move(value));
     98 }
     99 
    100 std::unique_ptr<ASTNode> Parser::parseAddSub() {
    101     auto left = parseMulDiv();
    102 
    103     while (peek().type == TokenType::PLUS || peek().type == TokenType::MINUS) {
    104         std::string op = peek().value;
    105         advance();
    106         auto right = parseMulDiv();
    107         left = std::make_unique<BinaryOp>(std::move(left), op, std::move(right));
    108     }
    109 
    110     return left;
    111 }
    112 
    113 std::unique_ptr<ASTNode> Parser::parseMulDiv() {
    114     auto left = parsePrimary();
    115     
    116     while (peek().type == TokenType::MULTIPLY || peek().type == TokenType::DIVIDE) {
    117         std::string op = peek().value;
    118         advance();
    119         auto right = parsePrimary();
    120         left = std::make_unique<BinaryOp>(std::move(left), op, std::move(right));
    121     } 
    122 
    123     return left;
    124 }
    125 
    126 std::unique_ptr<ASTNode> Parser::parsePrimary() {
    127     switch(peek().type) {
    128         case TokenType::NUMBER:
    129         {
    130             double value = std::stod(peek().value);
    131             advance();
    132             return std::make_unique<NumberLiteral>(value);
    133         }
    134 
    135         case TokenType::IDENTIFIER:
    136         {
    137             std::string name = peek().value;
    138             advance();
    139             return std::make_unique<Identifier>(name);
    140         }
    141 
    142         case TokenType::STRING:
    143         {
    144             std::string value = peek().value;
    145             advance();
    146             return std::make_unique<StringLiteral>(value);
    147         }
    148 
    149         default:
    150         {
    151             error("Unknown keyword");
    152             return nullptr;
    153         }
    154     }
    155 }
    156 
    157 Token Parser::advance() {
    158     return tokens_[position_++];
    159 }
    160 
    161 Token Parser::peek() {
    162     return tokens_[position_];
    163 }
    164 
    165 bool Parser::isAtEnd() {
    166     return position_ >= tokens_.size();
    167 }
    168 
    169 void Parser::error(std::string s) {
    170 
    171 }