From 74eafbd39c4c622ce2ebdf699102ec7541dfe807 Mon Sep 17 00:00:00 2001 From: Cori Barker Date: Mon, 19 Jan 2026 09:36:05 +0000 Subject: parser --- src/parser/parser.cpp | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/parser/parser.cpp (limited to 'src/parser/parser.cpp') diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp new file mode 100644 index 0000000..9eb94a3 --- /dev/null +++ b/src/parser/parser.cpp @@ -0,0 +1,171 @@ +#include + +#include "parser/parser.h" + +Parser::Parser(const std::vector& tokens) : tokens_(tokens), position_(0) {} + +std::unique_ptr Parser::parse() { + auto program = std::make_unique(); + + while (peek().type != TokenType::END_OF_FILE) { + try { + auto statement = parseStatement(); + program->declarations.push_back(std::move(statement)); + + if (peek().type == TokenType::SEMICOLON) { + advance(); + } + } + + catch (const std::exception& e) { + std::cerr << " Parser error: " << e.what() << std::endl; + break; + } + } + + return program; +} + +std::unique_ptr Parser::parseStatement() { + switch(peek().type) { + case TokenType::INT: + case TokenType::STRING: + { + return parseDeclaration(); + break; + } + + default: + { + error("Unexpected statement"); + return nullptr; + } + } +} + +std::unique_ptr Parser::parseExpression() { + return parseAddSub(); +} + +std::unique_ptr Parser::parseDeclaration() { + std::string type; + + switch(peek().type) { + case TokenType::INT: + { + type = "int"; + break; + } + + case TokenType::STRING: + { + type = "string"; + break; + } + + default: + { + error("Unexpected declaration: Invalid type"); + return nullptr; + } + } + + advance(); + std::string name = peek().value; + advance(); + if (peek().type == TokenType::ASSIGN) { + advance(); + auto value = parseExpression(); + return std::make_unique(type, name, std::move(value)); + } + + else if (peek().type == TokenType::SEMICOLON) { + return std::make_unique(type, name); + } + + else { + error("Invalid declaration"); + return nullptr; + } +} + +std::unique_ptr Parser::parseAssignment() { + std::string name = peek().value; + advance(); + advance(); // consume = + auto value = parseExpression(); + return std::make_unique(name, std::move(value)); +} + +std::unique_ptr Parser::parseAddSub() { + auto left = parseMulDiv(); + + while (peek().type == TokenType::PLUS || peek().type == TokenType::MINUS) { + std::string op = peek().value; + advance(); + auto right = parseMulDiv(); + left = std::make_unique(std::move(left), op, std::move(right)); + } + + return left; +} + +std::unique_ptr Parser::parseMulDiv() { + auto left = parsePrimary(); + + while (peek().type == TokenType::MULTIPLY || peek().type == TokenType::DIVIDE) { + std::string op = peek().value; + advance(); + auto right = parsePrimary(); + left = std::make_unique(std::move(left), op, std::move(right)); + } + + return left; +} + +std::unique_ptr Parser::parsePrimary() { + switch(peek().type) { + case TokenType::NUMBER: + { + double value = std::stod(peek().value); + advance(); + return std::make_unique(value); + } + + case TokenType::IDENTIFIER: + { + std::string name = peek().value; + advance(); + return std::make_unique(name); + } + + case TokenType::STRING: + { + std::string value = peek().value; + advance(); + return std::make_unique(value); + } + + default: + { + error("Unknown keyword"); + return nullptr; + } + } +} + +Token Parser::advance() { + return tokens_[position_++]; +} + +Token Parser::peek() { + return tokens_[position_]; +} + +bool Parser::isAtEnd() { + return position_ >= tokens_.size(); +} + +void Parser::error(std::string s) { + +} -- cgit v1.2.3