1

Implement part of the parser

This commit is contained in:
2023-03-21 14:33:29 +01:00
parent 6993388645
commit 306e631e64
2 changed files with 131 additions and 0 deletions

95
src/parser/Parser.cpp Normal file
View File

@ -0,0 +1,95 @@
//
// Created by christoph on 20.03.23.
//
#include "Parser.h"
#include "../ast/nodes/RootNode.h"
#include "../ast/nodes/MovNode.h"
#include "../ast/nodes/ConstNode.h"
#include "../ast/nodes/RegNode.h"
#include "../ast/nodes/AluNode.h"
#include <map>
// ! Helper Functions
// ! Public Functions
Parser::Parser(const std::vector<Token> &tokens) : tokens(tokens), position(tokens.begin()) {}
auto Parser::parse() -> std::unique_ptr<Node> {
auto root = std::make_unique<RootNode>();
while (peek().getType() != Token::END) {
if (peek().getType() != Token::MNEMONIC) {
throw "Parser Error: Expected Mnemonic!";
}
// TODO: Put these functions in a map, mapped to the mnemonic name string
if (static_cast<std::string_view>(peek()) == "MOV") {
root->addChild(std::move(mov()));
continue;
}
if (static_cast<std::string_view>(peek()) == "ADD") {
root->addChild(std::move(alu()));
continue;
}
}
return std::move(root);
}
// ! Private Functions
auto Parser::peek() const -> const Token & {
return *position;
}
auto Parser::get() -> const Token & {
return *(position++);
}
auto Parser::mov() -> std::unique_ptr<Node> {
if (peek().getType() != Token::MNEMONIC || static_cast<std::string_view>(peek()) != "MOV") {
throw "Parser Error: Expected 'MOV'!";
}
get(); // Eat 'MOV'
std::unique_ptr<Node> sourceNode;
if (peek().getType() == Token::NUMBER) {
sourceNode = std::make_unique<ConstNode>(static_cast<uint8_t>(peek()));
} else if (peek().getType() == Token::IDENTIFIER) {
sourceNode = std::make_unique<RegNode>(static_cast<uint8_t>(peek()));
} else {
throw "Parser Error: Expected Constant or Register!";
}
get(); // Eat source
const Token identifier = peek().subtoken(0, 3);
const Token reg = peek().subtoken(3, 1); // Get reg number
if (peek().getType() != Token::IDENTIFIER || static_cast<std::string_view>(identifier) != "reg") {
throw "Parser Error: Expected Register!";
}
std::unique_ptr<Node> targetNode = std::make_unique<RegNode>(static_cast<uint8_t>(reg));
get(); // Eat target
return std::move(std::make_unique<MovNode>(std::move(sourceNode), std::move(targetNode)));
}
auto Parser::alu() -> std::unique_ptr<Node> {
std::map<std::string, AluNode::AluOperation> aluMap = {{"AND", AluNode::AND},
{"OR", AluNode::OR},
{"NAND", AluNode::NAND},
{"NOR", AluNode::NOR},
{"ADD", AluNode::ADD},
{"SUB", AluNode::SUB}};
if (peek().getType() != Token::MNEMONIC) {
throw "Parser Error: Expected Mnemonic!";
}
if (!aluMap.contains(static_cast<std::string>(peek()))) {
throw "Parser Error: Invalid ALU operation!";
}
return std::move(std::make_unique<AluNode>(aluMap[static_cast<std::string>(get())])); // Eat alu
}

36
src/parser/Parser.h Normal file
View File

@ -0,0 +1,36 @@
//
// Created by christoph on 20.03.23.
//
#ifndef LOGISIMASSEMBLER_PARSER_H
#define LOGISIMASSEMBLER_PARSER_H
#include <memory>
#include <vector>
#include "../lexer/Token.h"
#include "../ast/Node.h"
class Parser {
public:
Parser(const std::vector<Token> &tokens);
Parser(std::vector<Token> &&tokens) = delete;
auto parse() -> std::unique_ptr<Node>;
private:
[[nodiscard]] auto peek() const -> const Token &;
auto get() -> const Token &;
auto mov() -> std::unique_ptr<Node>;
auto alu() -> std::unique_ptr<Node>;
private:
const std::vector<Token> &tokens;
std::vector<Token>::const_iterator position;
};
#endif //LOGISIMASSEMBLER_PARSER_H