saqut-compiler/src/parser/token.hpp

765 lines
28 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.

// ============================================================================
// saQut Compiler — Parser Token Tipleri ve Operatör Öncelik Tablosu
// ============================================================================
//
// DİZİN: src/parser/token.hpp
// KATMAN: Katman 3 — Tokenizer ile Parser arasında köprü
// BAĞIMLI: Tokenizer (src/tokenizer/tokenizer.hpp)
// KULLANAN: AST (src/parser/ast.hpp), Parser (src/parser/parser.hpp)
//
// AMAÇ:
// Tokenizer'ın ürettiği ham Token'ları (string tipli) Parser'ın anlayacağı
// anlamsal tiplere (TokenType enum) dönüştürür. Ayrıca operatör önceliğini
// (precedence) ve birleşme yönünü (associativity) merkezi olarak tanımlar.
//
// Bu dosya, Pratt parser'ın "kalbi"dir — tüm operatör önceliği ve birleşme
// kuralları burada tek bir yerde tanımlanır.
//
// ADR-002: Neden Merkezi Operatör Öncelik Tablosu?
// Recursive descent parser'larda operatör önceliği, her seviye için ayrı
// bir fonksiyon yazılarak (parseAddExpr, parseMulExpr, ...) kod tekrarına
// neden olur. Yeni bir operatör eklemek için yeni fonksiyon + mevcut
// fonksiyonları değiştirmek gerekir.
//
// Pratt parser'da tüm öncelik bilgisi TEK BİR TABLODA (TokenPrecedence)
// toplanır. Yeni operatör eklemek = tabloya bir satır eklemek.
//
// TASARIM KARARLARI:
// 1. TokenType enum: uint16_t tabanlı. Neden? 65K'dan fazla token tipi
// olmayacak, 2 byte yeterli. Bellek tasarrufu AST'de fark eder.
//
// 2. Üç harita (KEYWORD_MAP, OPERATOR_MAP, OPERATOR_MAP_REV, OPERATOR_MAP_STRREV):
// - KEYWORD_MAP: "if" → KW_IF, string'den TokenType'a
// - OPERATOR_MAP: "+" → PLUS, operatör string'inden TokenType'a
// - OPERATOR_MAP_REV: PLUS → "+", log çıktısı için ters harita
// - OPERATOR_MAP_STRREV: PLUS → "PLUS", enum ismini string olarak verir
// Neden dört harita? Çünkü std::unordered_map tek yönlüdür.
// bidirectional_map kütüphanesi kullanılabilirdi ama bağımlılık istemedik.
//
// 3. TokenPrecedence(): 18 seviyeli öncelik sistemi.
// C/C++/Java standartlarına uygun. Yüksek sayı = yüksek öncelik.
// Seviye 18 (en yüksek): üye erişimi (., ->, [], (), ::)
// Seviye 1 (en düşük): virgül (,)
// Seviye 0: önceliksiz (değerler, EOF, vb.)
//
// 4. RightAssociative(): Hangi operatörler sağdan sola birleşir?
// - Atama (=, +=, vb.)
// - Üs alma (**, ^) — matematiksel sağ birleşme: a^b^c = a^(b^c)
// - Ternary (?:)
// Diğer tüm operatörler soldan sağa birleşir.
//
// 5. ParserToken yapısı:
// Token* token: Tokenizer'ın ürettiği Token'a pointer. Değer kopyası
// DEĞİL. Neden pointer? Çünkü Token polimorfik (NumberToken, StringToken,
// vb.) ve değer kopyası object slicing'e neden olur.
// BUG FIX (commit 40579ca): Eskiden Token token (değer) vardı.
// TokenType type: Token'ın anlamsal tipi.
// is() / getPowerOperator() / isRightAssociative(): kolaylık metotları.
//
// BİLİNEN SINIRLAMALAR (TODO):
// TODO: Özel operatörler: ?., ??, |>, >>=, vb. (ileride eklenebilir)
// TODO: Kullanıcı tanımlı operatör önceliği (DSL'ler için)
// TODO: Token konum bilgisi (satır/sütun) ParserToken'a eklenmeli
//
// ============================================================================
#ifndef SAQUT_PARSER_TOKEN
#define SAQUT_PARSER_TOKEN
#include <cstdint>
#include <initializer_list>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "tokenizer/tokenizer.hpp"
// ============================================================================
// TokenList — Token Vektörü Tip Kısaltması
// ============================================================================
//
// Tokenizer::scan() tarafından üretilen, Parser::parse() tarafından tüketilen
// token listesi. Ham pointer'lar içerir — bellek yönetimi çağırana aittir.
//
// TODO: std::vector<std::unique_ptr<Token>> ile otomatik bellek yönetimi
//
typedef std::vector<Token*> TokenList;
// ============================================================================
// TokenType — Anlamsal Token Tipleri (Enum)
// ============================================================================
//
// Tokenizer'ın ürettiği string tipli token'ları ("number", "operator", ...)
// Parser'ın anlayacağı anlamsal tiplere dönüştürür.
//
// KATEGORİLER:
// 1. Değerler: IDENTIFIER, NUMBER, STRING, SVR_VOID (geçersiz/EOF)
// 2. Keyword'ler: KW_IF ... KW_NOEXCEPT (alfabetik sıralı)
// 3. Operatörler: Öncelik sırasına göre gruplanmış
// - Seviye 1: DOT, ARROW, LBRACKET, RBRACKET, LPAREN, RPAREN
// - Seviye 2: PLUS_PLUS, MINUS_MINUS (postfix)
// - Seviye 3: PLUS, MINUS, BANG, TILDE (unary prefix)
// - Seviye 4: STAR_STAR, CARET (üs)
// - Seviye 5: STAR, SLASH, PERCENT (çarpma/bölme)
// - Seviye 6-16: devamı...
// 4. Diğer: LBRACE, RBRACE, SEMICOLON, COMMA, COLON_COLON
// 5. Özel: END_OF_FILE, UNKNOWN, COMMENT, PREPROCESSOR
//
// NEDEN uint16_t? Bellek optimizasyonu. Her AST düğümü bir TokenType taşır.
// Binlerce düğümde 2 byte vs 4 byte fark eder.
//
enum class TokenType : uint16_t {
// --- Değerler ve Tanımlayıcılar ---
IDENTIFIER, // değişken/fonksiyon ismi
NUMBER, // 42, 0xFF, 0b1010, 3.14
STRING, // "merhaba"
SVR_VOID, // Geçersiz/EOF sinyali (Parser içinde kullanılır)
// --- Kontrol Akışı Keyword'leri ---
KW_IF, // if
KW_ELSE, // else
KW_FOR, // for
KW_WHILE, // while
KW_DO, // do
KW_SWITCH, // switch
KW_CASE, // case
KW_DEFAULT, // default
KW_BREAK, // break
KW_CONTINUE, // continue
KW_RETURN, // return
// --- OOP Keyword'leri ---
KW_CLASS, // class
KW_STRUCT, // struct
KW_INTERFACE, // interface
KW_ENUM, // enum
KW_EXTENDS, // extends
KW_IMPLEMENTS, // implements
KW_NEW, // new
KW_PUBLIC, // public
KW_PRIVATE, // private
KW_PROTECTED, // protected
KW_STATIC, // static
KW_FINAL, // final
KW_ABSTRACT, // abstract
// --- Tip Keyword'leri ---
KW_VOID, // void
KW_BOOL, // bool
KW_INT, // int
KW_FLOAT_TYPE, // float (FLOAT math.h'de tanımlı olabilir, TYPE eki var)
KW_DOUBLE, // double
KW_CHAR, // char
KW_STRING_TYPE, // string
// --- Literal Keyword'ler ---
KW_TRUE, // true
KW_FALSE, // false
KW_NULL, // null
// --- İstisna Yönetimi ---
KW_TRY, // try
KW_CATCH, // catch
KW_FINALLY, // finally
KW_THROW, // throw
KW_THROWS, // throws
KW_ASSERT, // assert
// --- Modül/Paket ---
KW_IMPORT, // import
KW_PACKAGE, // package
// --- C/C++ Ekleri ---
KW_NATIVE, // native (JNI)
KW_SYNCHRONIZED, // synchronized (Java)
KW_VOLATILE, // volatile
KW_TRANSIENT, // transient
KW_CONST, // const
KW_EXTERN, // extern
KW_TYPEDEF, // typedef
KW_SIZEOF, // sizeof
KW_ALIGNOF, // alignof
KW_DECLTYPE, // decltype
KW_AUTO, // auto
KW_CONSTEXPR, // constexpr
KW_NOEXCEPT, // noexcept
// ================================================================
// Operatörler — Öncelik sırasına göre gruplanmış
// ================================================================
// Seviye 1 (18): Üye erişimi ve çağrı — En yüksek öncelik
DOT, // .
ARROW, // ->
LBRACKET, // [
RBRACKET, // ]
LPAREN, // (
RPAREN, // )
// Seviye 2 (17): Postfix
PLUS_PLUS, // ++ (postfix)
MINUS_MINUS, // -- (postfix)
// Seviye 3 (16): Unary Prefix
PLUS, // + (unary)
MINUS, // - (unary)
BANG, // ! (mantıksal değil)
TILDE, // ~ (bitsel değil)
// Seviye 4 (15): Üs alma
STAR_STAR, // ** (Python tarzı üs)
CARET, // ^ (bazı dillerde üs)
// Seviye 5 (14): Çarpma/Bölme
STAR, // *
SLASH, // /
PERCENT, // %
// Seviye 6 (13): Toplama/Çıkarma — PLUS ve MINUS yukarıda (unary + binary)
// Seviye 7 (12): Bitsel kaydırma
LSHIFT, // <<
RSHIFT, // >>
// Seviye 8 (11): İlişkisel karşılaştırma
LESS, // <
LESS_EQUAL, // <=
GREATER, // >
GREATER_EQUAL, // >=
// Seviye 9 (10): Eşitlik
EQUAL_EQUAL, // ==
BANG_EQUAL, // !=
// Seviye 10 (9): Bitsel VE
AMPERSAND, // &
// Seviye 11 (8): Bitsel XOR — CARET yukarıda (üs veya XOR)
// Seviye 12 (7): Bitsel VEYA
PIPE, // |
// Seviye 13 (6): Mantıksal VE
AMPERSAND_AMPERSAND, // &&
// Seviye 14 (5): Mantıksal VEYA
PIPE_PIPE, // ||
// Seviye 15 (4): Üçlü koşul (ternary)
TERNARY, // ?
COLON, // : (ternary ve etiket için)
// Seviye 16 (3): Atama
EQUAL, // =
PLUS_EQUAL, // +=
MINUS_EQUAL, // -=
STAR_EQUAL, // *=
SLASH_EQUAL, // /=
PERCENT_EQUAL, // %=
AMPERSAND_EQUAL, // &=
PIPE_EQUAL, // |=
CARET_EQUAL, // ^=
LSHIFT_EQUAL, // <<=
RSHIFT_EQUAL, // >>=
// --- Diğer Semboller ---
LBRACE, // {
RBRACE, // }
SEMICOLON, // ;
COMMA, // ,
COLON_COLON, // ::
// --- Özel ---
END_OF_FILE, // Dosya sonu
UNKNOWN, // Bilinmeyen karakter
COMMENT, // Yorum (// veya /* */) — şu anda token üretilmez
PREPROCESSOR, // Önişlemci (#) — şu anda kullanılmıyor
};
// ============================================================================
// KEYWORD_MAP — Keyword String → TokenType
// ============================================================================
//
// Tokenizer'ın ürettiği KeywordToken'ların token değerini (örn: "if")
// Parser'ın anlayacağı TokenType'a (KW_IF) dönüştürür.
//
// std::unordered_map: O(1) ortalama arama. const: derleme zamanı sabiti.
// std::string_view: string kopyalamadan kaçınır.
//
// NOT: Bu harita, Tokenizer'daki keywords[] dizisi ile eşleşmelidir.
// Birinde ekleme yapılırsa diğerine de eklenmelidir.
//
inline const std::unordered_map<std::string_view, TokenType> KEYWORD_MAP = {
// --- Control flow ---
{"if", TokenType::KW_IF},
{"else", TokenType::KW_ELSE},
{"for", TokenType::KW_FOR},
{"while", TokenType::KW_WHILE},
{"do", TokenType::KW_DO},
{"switch", TokenType::KW_SWITCH},
{"case", TokenType::KW_CASE},
{"default", TokenType::KW_DEFAULT},
{"break", TokenType::KW_BREAK},
{"continue", TokenType::KW_CONTINUE},
{"return", TokenType::KW_RETURN},
// --- OOP ---
{"class", TokenType::KW_CLASS},
{"struct", TokenType::KW_STRUCT},
{"interface", TokenType::KW_INTERFACE},
{"enum", TokenType::KW_ENUM},
{"extends", TokenType::KW_EXTENDS},
{"implements", TokenType::KW_IMPLEMENTS},
{"new", TokenType::KW_NEW},
// --- Access modifiers ---
{"public", TokenType::KW_PUBLIC},
{"private", TokenType::KW_PRIVATE},
{"protected", TokenType::KW_PROTECTED},
{"static", TokenType::KW_STATIC},
{"final", TokenType::KW_FINAL},
{"abstract", TokenType::KW_ABSTRACT},
// --- Types ---
{"void", TokenType::KW_VOID},
{"bool", TokenType::KW_BOOL},
{"int", TokenType::KW_INT},
{"float", TokenType::KW_FLOAT_TYPE},
{"double", TokenType::KW_DOUBLE},
{"char", TokenType::KW_CHAR},
{"string", TokenType::KW_STRING_TYPE},
// --- Literals ---
{"true", TokenType::KW_TRUE},
{"false", TokenType::KW_FALSE},
{"null", TokenType::KW_NULL},
// --- Exception handling ---
{"try", TokenType::KW_TRY},
{"catch", TokenType::KW_CATCH},
{"finally", TokenType::KW_FINALLY},
{"throw", TokenType::KW_THROW},
{"throws", TokenType::KW_THROWS},
{"assert", TokenType::KW_ASSERT},
// --- Modules/packages ---
{"import", TokenType::KW_IMPORT},
{"package", TokenType::KW_PACKAGE},
// --- C/C++ specific ---
{"const", TokenType::KW_CONST},
{"extern", TokenType::KW_EXTERN},
{"typedef", TokenType::KW_TYPEDEF},
{"sizeof", TokenType::KW_SIZEOF},
{"auto", TokenType::KW_AUTO},
{"constexpr", TokenType::KW_CONSTEXPR},
{"noexcept", TokenType::KW_NOEXCEPT},
{"native", TokenType::KW_NATIVE},
{"synchronized",TokenType::KW_SYNCHRONIZED},
{"volatile", TokenType::KW_VOLATILE},
{"transient", TokenType::KW_TRANSIENT},
};
// ============================================================================
// OPERATOR_MAP — Operatör/Delimiter String → TokenType
// ============================================================================
//
// Tokenizer'ın ürettiği OperatorToken ve DelimiterToken'ları TokenType'a
// dönüştürür. Her iki token tipi de aynı haritayı kullanır çünkü parser
// seviyesinde delimiter'lar da operatör gibi işlenir.
//
// SIRALAMA ÖNEMLİ DEĞİL (unordered_map).
// Ama Tokenizer'daki operators[] ve delimiters[] dizilerindeki sıralama
// önemlidir — çok karakterliler önce gelmelidir.
//
inline const std::unordered_map<std::string_view, TokenType> OPERATOR_MAP = {
// --- 2 karakterli ---
{"->", TokenType::ARROW},
{"::", TokenType::COLON_COLON},
{"==", TokenType::EQUAL_EQUAL},
{"!=", TokenType::BANG_EQUAL},
{"<=", TokenType::LESS_EQUAL},
{">=", TokenType::GREATER_EQUAL},
{"&&", TokenType::AMPERSAND_AMPERSAND},
{"||", TokenType::PIPE_PIPE},
{"++", TokenType::PLUS_PLUS},
{"--", TokenType::MINUS_MINUS},
{"<<", TokenType::LSHIFT},
{">>", TokenType::RSHIFT},
{"**", TokenType::STAR_STAR},
// --- Birleşik atama ---
{"+=", TokenType::PLUS_EQUAL},
{"-=", TokenType::MINUS_EQUAL},
{"*=", TokenType::STAR_EQUAL},
{"/=", TokenType::SLASH_EQUAL},
{"%=", TokenType::PERCENT_EQUAL},
{"&=", TokenType::AMPERSAND_EQUAL},
{"|=", TokenType::PIPE_EQUAL},
{"^=", TokenType::CARET_EQUAL},
{"<<=", TokenType::LSHIFT_EQUAL},
{">>=", TokenType::RSHIFT_EQUAL},
// --- 1 karakterli operatörler ---
{"+", TokenType::PLUS},
{"-", TokenType::MINUS},
{"*", TokenType::STAR},
{"/", TokenType::SLASH},
{"%", TokenType::PERCENT},
{"<", TokenType::LESS},
{">", TokenType::GREATER},
{"^", TokenType::CARET},
{"!", TokenType::BANG},
{"~", TokenType::TILDE},
{"&", TokenType::AMPERSAND},
{"|", TokenType::PIPE},
{"=", TokenType::EQUAL},
// --- Delimiter'lar (operatör gibi işlenir) ---
{"[", TokenType::LBRACKET},
{"]", TokenType::RBRACKET},
{"(", TokenType::LPAREN},
{")", TokenType::RPAREN},
{"{", TokenType::LBRACE},
{"}", TokenType::RBRACE},
{";", TokenType::SEMICOLON},
{",", TokenType::COMMA},
{":", TokenType::COLON},
{".", TokenType::DOT},
{"?", TokenType::TERNARY},
};
// ============================================================================
// OPERATOR_MAP_REV — TokenType → Operatör String (Log için)
// ============================================================================
//
// AST ağacını konsola yazdırırken (log) TokenType enum değerini insan
// tarafından okunabilir operatör sembolüne dönüştürür.
// Örn: TokenType::PLUS → "+"
//
inline const std::unordered_map<TokenType, std::string_view> OPERATOR_MAP_REV = {
{TokenType::ARROW, "->"},
{TokenType::COLON_COLON, "::"},
{TokenType::EQUAL_EQUAL, "=="},
{TokenType::BANG_EQUAL, "!="},
{TokenType::LESS_EQUAL, "<="},
{TokenType::GREATER_EQUAL, ">="},
{TokenType::AMPERSAND_AMPERSAND,"&&"},
{TokenType::PIPE_PIPE, "||"},
{TokenType::PLUS_PLUS, "++"},
{TokenType::MINUS_MINUS, "--"},
{TokenType::LSHIFT, "<<"},
{TokenType::RSHIFT, ">>"},
{TokenType::STAR_STAR, "**"},
{TokenType::PLUS_EQUAL, "+="},
{TokenType::MINUS_EQUAL, "-="},
{TokenType::STAR_EQUAL, "*="},
{TokenType::SLASH_EQUAL, "/="},
{TokenType::PERCENT_EQUAL, "%="},
{TokenType::AMPERSAND_EQUAL, "&="},
{TokenType::PIPE_EQUAL, "|="},
{TokenType::CARET_EQUAL, "^="},
{TokenType::LSHIFT_EQUAL, "<<="},
{TokenType::RSHIFT_EQUAL, ">>="},
{TokenType::PLUS, "+"},
{TokenType::MINUS, "-"},
{TokenType::STAR, "*"},
{TokenType::SLASH, "/"},
{TokenType::PERCENT, "%"},
{TokenType::LESS, "<"},
{TokenType::GREATER, ">"},
{TokenType::CARET, "^"},
{TokenType::BANG, "!"},
{TokenType::TILDE, "~"},
{TokenType::AMPERSAND, "&"},
{TokenType::PIPE, "|"},
{TokenType::EQUAL, "="},
{TokenType::LBRACKET, "["},
{TokenType::RBRACKET, "]"},
{TokenType::LPAREN, "("},
{TokenType::RPAREN, ")"},
{TokenType::LBRACE, "{"},
{TokenType::RBRACE, "}"},
{TokenType::SEMICOLON, ";"},
{TokenType::COMMA, ","},
{TokenType::COLON, ":"},
{TokenType::DOT, "."},
{TokenType::TERNARY, "?"},
};
// ============================================================================
// OPERATOR_MAP_STRREV — TokenType → Enum İsmi (Log için)
// ============================================================================
//
// AST log çıktısında operatörün enum ismini gösterir.
// Örn: TokenType::PLUS → "PLUS"
//
inline const std::unordered_map<TokenType, std::string_view> OPERATOR_MAP_STRREV = {
{TokenType::ARROW, "ARROW"},
{TokenType::COLON_COLON, "COLON_COLON"},
{TokenType::EQUAL_EQUAL, "EQUAL_EQUAL"},
{TokenType::BANG_EQUAL, "BANG_EQUAL"},
{TokenType::LESS_EQUAL, "LESS_EQUAL"},
{TokenType::GREATER_EQUAL, "GREATER_EQUAL"},
{TokenType::AMPERSAND_AMPERSAND,"AMPERSAND_AMPERSAND"},
{TokenType::PIPE_PIPE, "PIPE_PIPE"},
{TokenType::PLUS_PLUS, "PLUS_PLUS"},
{TokenType::MINUS_MINUS, "MINUS_MINUS"},
{TokenType::LSHIFT, "LSHIFT"},
{TokenType::RSHIFT, "RSHIFT"},
{TokenType::STAR_STAR, "STAR_STAR"},
{TokenType::PLUS_EQUAL, "PLUS_EQUAL"},
{TokenType::MINUS_EQUAL, "MINUS_EQUAL"},
{TokenType::STAR_EQUAL, "STAR_EQUAL"},
{TokenType::SLASH_EQUAL, "SLASH_EQUAL"},
{TokenType::PERCENT_EQUAL, "PERCENT_EQUAL"},
{TokenType::AMPERSAND_EQUAL, "AMPERSAND_EQUAL"},
{TokenType::PIPE_EQUAL, "PIPE_EQUAL"},
{TokenType::CARET_EQUAL, "CARET_EQUAL"},
{TokenType::LSHIFT_EQUAL, "LSHIFT_EQUAL"},
{TokenType::RSHIFT_EQUAL, "RSHIFT_EQUAL"},
{TokenType::PLUS, "PLUS"},
{TokenType::MINUS, "MINUS"},
{TokenType::STAR, "STAR"},
{TokenType::SLASH, "SLASH"},
{TokenType::PERCENT, "PERCENT"},
{TokenType::LESS, "LESS"},
{TokenType::GREATER, "GREATER"},
{TokenType::CARET, "CARET"},
{TokenType::BANG, "BANG"},
{TokenType::TILDE, "TILDE"},
{TokenType::AMPERSAND, "AMPERSAND"},
{TokenType::PIPE, "PIPE"},
{TokenType::EQUAL, "EQUAL"},
{TokenType::LBRACKET, "LBRACKET"},
{TokenType::RBRACKET, "RBRACKET"},
{TokenType::LPAREN, "LPAREN"},
{TokenType::RPAREN, "RPAREN"},
{TokenType::LBRACE, "LBRACE"},
{TokenType::RBRACE, "RBRACE"},
{TokenType::SEMICOLON, "SEMICOLON"},
{TokenType::COMMA, "COMMA"},
{TokenType::COLON, "COLON"},
{TokenType::DOT, "DOT"},
{TokenType::TERNARY, "TERNARY"},
};
// ============================================================================
// TokenPrecedence — Operatör Öncelik Tablosu
// ============================================================================
//
// Pratt parser'ın kalbi. Her TokenType için bir öncelik seviyesi döndürür.
// Yüksek sayı = daha sıkı bağlanma (daha yüksek öncelik).
//
// ÖNCELİK SEVİYELERİ (yüksekten düşüğe):
// 18: Üye erişimi . -> [ ] ( )
// 17: Postfix ++ --
// 16: Unary prefix ! ~
// 15: Üs alma ** ^
// 14: Çarpma/Bölme * / %
// 13: Toplama/Çıkarma + -
// 12: Bitsel kaydırma << >>
// 11: İlişkisel < <= > >=
// 10: Eşitlik == !=
// 9: Bitsel VE &
// 8: Bitsel XOR ^ (üs olarak 15'te de var — bağlama göre)
// 7: Bitsel VEYA |
// 6: Mantıksal VE &&
// 5: Mantıksal VEYA ||
// 4: Ternary ?
// 3: Ternary else :
// 2: Atama = += -= vb.
// 1: Virgül ,
// 0: Önceliksiz (değerler, EOF, bilinmeyen)
//
// NOT: C/C++'da ^ operatörü bitsel XOR'tur (seviye 8), ama Python'da üs (seviye 15).
// saQut'ta ^ hem üs hem XOR olarak kullanılabilir (AST'de bağlam belirler).
// Şimdilik ^ seviye 15 (üs) olarak ayarlı.
//
// BUG FIX (commit 438bc0e): Seviye 8'deki ölü kod (CARET için case olmadan
// return 8) temizlendi. CARET zaten seviye 15'te STAR_STAR ile birlikte
// işleniyor.
//
inline uint16_t TokenPrecedence(TokenType type) {
switch (type) {
// Level 18: Member access / call
case TokenType::DOT:
case TokenType::ARROW:
case TokenType::LBRACKET:
case TokenType::LPAREN:
return 18;
// Level 17: Postfix
case TokenType::PLUS_PLUS:
case TokenType::MINUS_MINUS:
return 17;
// Level 16: Unary prefix — sadece her zaman prefix olanlar
case TokenType::BANG: // !
case TokenType::TILDE: // ~
return 16;
// Level 15: Exponentiation
case TokenType::STAR_STAR: // **
case TokenType::CARET: // ^ (Python tarzı üs)
return 15;
// Level 14: Multiplicative
case TokenType::STAR: // *
case TokenType::SLASH: // /
case TokenType::PERCENT: // %
return 14;
// Level 13: Additive — PLUS ve MINUS hem unary hem binary
case TokenType::PLUS: // +
case TokenType::MINUS: // -
return 13;
// Level 12: Bit shift
case TokenType::LSHIFT: // <<
case TokenType::RSHIFT: // >>
return 12;
// Level 11: Relational
case TokenType::LESS: // <
case TokenType::LESS_EQUAL:// <=
case TokenType::GREATER: // >
case TokenType::GREATER_EQUAL: // >=
return 11;
// Level 10: Equality
case TokenType::EQUAL_EQUAL: // ==
case TokenType::BANG_EQUAL: // !=
return 10;
// Level 9: Bitwise AND
case TokenType::AMPERSAND: // &
return 9;
// Level 8: Bitwise XOR — şu anda CARET seviye 15'te (üs)
// Level 7: Bitwise OR
case TokenType::PIPE: // |
return 7;
// Level 6: Logical AND
case TokenType::AMPERSAND_AMPERSAND: // &&
return 6;
// Level 5: Logical OR
case TokenType::PIPE_PIPE: // ||
return 5;
// Level 4: Ternary
case TokenType::TERNARY: // ?
return 4;
case TokenType::COLON: // : (ternary için)
return 3; // ternary'den düşük, atamadan yüksek
// Level 2: Assignment
case TokenType::EQUAL: // =
case TokenType::PLUS_EQUAL:// +=
case TokenType::MINUS_EQUAL:// -=
case TokenType::STAR_EQUAL:// *=
case TokenType::SLASH_EQUAL:// /=
case TokenType::PERCENT_EQUAL:// %=
case TokenType::AMPERSAND_EQUAL:// &=
case TokenType::PIPE_EQUAL:// |=
case TokenType::CARET_EQUAL:// ^=
case TokenType::LSHIFT_EQUAL:// <<=
case TokenType::RSHIFT_EQUAL:// >>=
return 2;
// Level 1: Comma
case TokenType::COMMA: // ,
return 1;
default:
return 0; // Önceliksiz: değerler, EOF, bilinmeyen
}
}
// ============================================================================
// RightAssociative — Sağdan Sola Birleşme Kontrolü
// ============================================================================
//
// Hangi operatörler sağdan sola birleşir?
//
// Sağ birleşmeli operatörler (a OP b OP c = a OP (b OP c)):
// - Üs alma: **, ^ (matematiksel: 2^3^2 = 2^(3^2) = 2^9 = 512)
// - Atama: =, +=, -=, vb. (a = b = 5 → a = (b = 5))
// - Ternary: ?: (a ? b : c ? d : e → a ? b : (c ? d : e))
//
// Sol birleşmeli operatörler (a OP b OP c = (a OP b) OP c):
// - Tüm diğerleri: +, -, *, /, ==, &&, vb.
//
inline bool RightAssociative(TokenType type) {
switch (type) {
case TokenType::STAR_STAR: // ** (üs)
case TokenType::CARET: // ^ (üs)
case TokenType::EQUAL: // =
case TokenType::PLUS_EQUAL: // +=
case TokenType::MINUS_EQUAL:// -=
case TokenType::STAR_EQUAL: // *=
case TokenType::SLASH_EQUAL:// /=
case TokenType::PERCENT_EQUAL:// %=
case TokenType::AMPERSAND_EQUAL:// &=
case TokenType::PIPE_EQUAL: // |=
case TokenType::CARET_EQUAL:// ^=
case TokenType::LSHIFT_EQUAL:// <<=
case TokenType::RSHIFT_EQUAL:// >>=
case TokenType::TERNARY: // ? (ternary)
return true;
default:
return false;
}
}
// ============================================================================
// ParserToken — Parser'ın Kullandığı Token Yapısı
// ============================================================================
//
// Tokenizer'ın ürettiği ham Token ile Parser'ın ihtiyaç duyduğu anlamsal
// tipi (TokenType) bir arada tutar.
//
// ALANLAR:
// token (Token*): Tokenizer'dan gelen orijinal token. Neden pointer?
// Çünkü Token polimorfik bir sınıf hiyerarşisidir. Değer kopyası (Token)
// object slicing'e neden olur — alt sınıf verileri (NumberToken.isFloat,
// StringToken.context) kaybolur.
// BUG FIX (commit 40579ca): Eskiden Token token (değer) tutuyordu.
//
// type (TokenType): Token'ın anlamsal tipi. Örn: NUMBER, PLUS, KW_IF.
//
// METOTLAR:
// is(TokenType): Bu token belirtilen tipte mi?
// is({...}): Bu token listedeki tiplerden biri mi?
// getPowerOperator(): Bu token bir operatör ise önceliğini döndür.
// isRightAssociative(): Bu operatör sağ birleşmeli mi?
//
struct ParserToken {
Token* token = nullptr; // Tokenizer'dan gelen orijinal token
TokenType type = TokenType::SVR_VOID; // Anlamsal tip
// Tek tip kontrolü
bool is(TokenType t) const {
return type == t;
}
// Çoklu tip kontrolü — örn: is({KW_INT, KW_FLOAT, KW_VOID})
bool is(std::initializer_list<TokenType> types) const {
for (TokenType t : types)
if (type == t) return true;
return false;
}
// Operatör önceliği (Pratt parser için)
uint16_t getPowerOperator() const {
return TokenPrecedence(type);
}
// Sağ birleşmeli mi?
bool isRightAssociative() const {
return RightAssociative(type);
}
};
#endif // SAQUT_PARSER_TOKEN