saqut-compiler/core/Parser/Parser.cpp

315 lines
6.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <string>
#include <stdlib.h>
#include <unordered_map>
#include <string_view>
#include "../Tokenizer.cpp"
#include "../Tools.cpp"
#include <cstdint>
#include <string_view>
#include "./ParserToken.cpp"
#include "./ASTNode.cpp"
#ifndef PARSER
#define PARSER
class Parser {
private:
ASTNode astroot;
public:
TokenList tokens;
void parse(TokenList tokens);
int current = 0;
ParserToken currentToken();
void nextToken();
ParserToken lookehead(uint32_t);
ParserToken parseToken(Token);
ParserToken getToken(int);
void primaryExpression();
ASTNode * volumeExpression(uint16_t precedence);
ASTNode * volumeNullDominatorExpression();
ASTNode * volumeLeftDominatorExpression(ASTNode * left);
};
ParserToken Parser::parseToken(Token token){
ParserToken pToken;
pToken.token = token;
if(token.gettype() == "string")
{
pToken.type = TokenType::STRING;
}
else if(token.gettype() == "number")
{
pToken.type = TokenType::NUMBER;
}
else if(token.gettype() == "operator")
{
pToken.type = OPERATOR_MAP.find(token.token)->second;
}
else if(token.gettype() == "delimiter")
{
pToken.type = OPERATOR_MAP.find(token.token)->second;
}
else if(token.gettype() == "keyword")
{
pToken.type = KEYWORD_MAP.find(token.token)->second;
}
else if(token.gettype() == "identifier")
{
pToken.type = TokenType::IDENTIFIER;
}
return pToken;
}
ParserToken Parser::getToken(int offset){
if(this->tokens.size() - 1 < this->current + offset)
{
ParserToken pToken;
pToken.type = TokenType::SVR_VOID;
return pToken;
}
return this->parseToken(this->tokens[this->current + offset]);
}
void Parser::nextToken(){
if(this->tokens.size() >= this->current + 1)
{
this->current++;
}
}
ParserToken Parser::lookehead(uint32_t forward){
return this->getToken(forward);
}
ParserToken Parser::currentToken(){
return this->getToken(0);
}
void Parser::parse(TokenList tokens){
this->tokens = tokens;
this->primaryExpression();
}
void Parser::primaryExpression()
{
auto currentToken = this->currentToken();
if(
currentToken.is({
TokenType::NUMBER,
TokenType::PLUS_PLUS,
TokenType::MINUS_MINUS,
TokenType::PLUS,
TokenType::MINUS,
TokenType::BANG,
TokenType::TILDE,
})
)
{
ASTNode * tree = this->volumeExpression(0);
tree->log(0);
}
}
// Expresssionu tamamen okuyup bitiren kısım burası
// Bir expressionda kendi içerisindeki operatörleri işler
// Terimler ile ilgilenmez yanlızca ifadelerin önceliğini belirler
// Sayılar, fonksionlar, tanımlamalar gibi şeyler burda işlenmez
ASTNode * Parser::volumeExpression(uint16_t precedence)
{
if (this->currentToken().type == TokenType::SVR_VOID)
{
return nullptr;
}
ASTNode* left = this->volumeNullDominatorExpression();
if (!left) {
return nullptr;
}
while(1)
{
auto nextToken = this->lookehead(+1);
if (nextToken.type == TokenType::RPAREN) {
break;
}
nextToken = this->lookehead(+1);
if(precedence < nextToken.getPowerOperator())
{
this->nextToken();
left = this->volumeLeftDominatorExpression(left);
}else{
break;
}
}
return left;
}
// Terimler burada işlenir tanımlamalar sayılar burada işlenir
// işlem önceliği işlenmez
// Tek yönlü operatörler !a b++ ++c burada işlenir
ASTNode * Parser::volumeNullDominatorExpression()
{
auto currentToken = this->currentToken();
if (currentToken.type == TokenType::SVR_VOID) {
// Hata: "Beklenmedik dosya sonu, bir değer bekleniyordu!"
return nullptr;
}
if (currentToken.type == TokenType::RPAREN) {
return nullptr;
}
if (currentToken.type == TokenType::LPAREN) {
this->nextToken();
ASTNode* expr = this->volumeExpression(0);
this->nextToken();
return expr;
}
if(currentToken.is({
TokenType::PLUS_PLUS,
TokenType::MINUS_MINUS,
TokenType::PLUS,
TokenType::MINUS,
TokenType::BANG,
TokenType::TILDE,
})) {
this->nextToken();
ASTNode * right = this->volumeExpression(currentToken.getPowerOperator());
BinaryExpressionNode * binNode = new BinaryExpressionNode();
binNode->Right = right;
binNode->Left = nullptr;
binNode->Operator = currentToken.type;
return binNode;
};
if(currentToken.is(TokenType::NUMBER)) {
LiteralNode * lNode = new LiteralNode();
lNode->lexerToken = currentToken.token;
lNode->parserToken = currentToken;
return lNode;
}
if(currentToken.is(TokenType::IDENTIFIER)) {
IdentifierNode * iNode = new IdentifierNode();
iNode->lexerToken = currentToken.token;
iNode->parserToken = currentToken;
return iNode;
}
return nullptr;
}
// Çift yönlü matematiksel işlemler burada işlenir
// [volume]+[volume] veya [volume] * [volume] gibi terimleri birbirine bağlayarak geri döner
ASTNode * Parser::volumeLeftDominatorExpression(ASTNode * left)
{
auto currentToken = this->currentToken();
if (currentToken.is({
TokenType::PLUS_PLUS,
TokenType::MINUS_MINUS
})) {
this->nextToken();
PostfixNode* node = new PostfixNode();
node->operand = left;
node->Operator = currentToken.type;
return node;
}
uint16_t precedence = currentToken.getPowerOperator();
this->nextToken();
auto right = this->volumeExpression(precedence);
BinaryExpressionNode * binNode = new BinaryExpressionNode();
binNode->Right = right;
binNode->Left = left;
binNode->Operator = currentToken.type;
return binNode;
}
#endif