saqut-compiler/src/parser/token.hpp

999 lines
44 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, Operatör Öncelik Tablosu ve ParserToken
// ============================================================================
//
// DİZİN: src/parser/token.hpp
// KATMAN: Katman 3 — Tokenizer ile Parser Arasında Köprü
// AMAÇ: Tokenizer'ın ham token'larını anlamsal tiplere dönüştürmek,
// operatör öncelik ve birleşme kurallarını merkezi olarak tanımlamak
//
// BAĞIMLILIKLAR:
// - tokenizer/tokenizer.hpp: Token sınıf hiyerarşisi (Token, NumberToken, vs.)
// - KULLANAN: parser/ast.hpp, parser/parser.hpp
//
// BU DOSYANIN İÇERDİKLERİ:
// 1. TokenType enum (uint16_t): 100+ token tipi (keyword'ler, operatörler, delimiter'lar)
// 2. KEYWORD_MAP: string → TokenType (keyword çözümleme)
// 3. OPERATOR_MAP: string → TokenType (operatör çözümleme)
// 4. OPERATOR_MAP_REV: TokenType → string (log çıktısı için ters harita)
// 5. OPERATOR_MAP_STRREV: TokenType → string (enum ismi, debug için)
// 6. TokenPrecedence(): Öncelik tablosu (18 seviye, Pratt parser'ın kalbi)
// 7. RightAssociative(): Sağ birleşme kontrolü (atama, üs, ternary)
// 8. ParserToken: Parser'ın kullandığı token yapısı (Token* + TokenType)
//
// TASARIM KARARLARI (ADR-002):
// Neden TokenType enum'ı burada tanımlı, Tokenizer'da değil?
// -> Tokenizer sadece ham token'lar üretir. Anlamsal tipler Parser'ın işidir.
// -> Tokenizer'ın Tokenizer'ın ham yapısını değiştirmeden yeni diller eklenebilir.
//
// Neden uint16_t tabanlı enum?
// -> 65K token tipi fazlasıyla yeterli. 2 byte = bellek tasarrufu.
// -> Her AST düğümünde TokenType saklanabilir (opsiyonel).
//
// Neden dört ayrı map?
// -> unordered_map tek yönlüdür. Her yön için ayrı map gerekir.
// -> OPERATOR_MAP_REV: log çıktısında "+" göstermek için.
// -> OPERATOR_MAP_STRREV: enum ismini string olarak (debug, AST dump).
//
// Neden bu kadar çok keyword?
// -> saQut hem C/C++ hem Java hem de kendi sözdizimini destekler.
// -> Tüm keyword'ler tek enum'da toplanmıştır.
//
// ============================================================================
#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.
//
/* ================================================================
* TokenType — Anlamsal Token Tipleri
* ================================================================
*
* Tokenizer'ın ürettiği ham token'ları (string tipli) Parser'ın
* anlayacağı anlamsal tiplere dönüştürür.
*
* uint16_t tabanlı — 65K token tipi yeterli.
* Bellek: AST düğümlerinde taşınabilir (2 byte).
*
* KATEGORİLER (öncelik sırasına göre):
* 1. Değerler: IDENTIFIER, NUMBER, STRING, SVR_VOID
* 2. Keyword'ler: KW_IF ... KW_NOEXCEPT (C/C++/Java ortak)
* 3. Operatörler: DOT(18) ... COMMA(1) (Pratt öncelik seviyesi)
* 4. Delimiter'lar: LBRACE, RBRACE, SEMICOLON, vb.
* 5. Özel: END_OF_FILE, UNKNOWN, COMMENT, PREPROCESSOR
*
* ================================================================ */
enum class TokenType : uint16_t {
/* ====== Değerler ve Tanımlayıcılar ====== */
IDENTIFIER, // Değişken/fonksiyon/sınıf ismi.
// Tokenizer'da IdentifierToken olarak üretilir.
// Örn: x, main, Point, calculateAverage
NUMBER, // Sayısal sabit: 42, 0xFF, 0b1010, 3.14, 1e-5
// Tokenizer'da NumberToken olarak üretilir.
// .isFloat alanı ile tamsayı/ondalık ayrımı yapılır.
STRING, // Metin sabiti: "merhaba", "selam"
// Tokenizer'da StringToken olarak üretilir.
// Kaçış dizileri (\n, \t, \") tokenizer'da çözülür.
SVR_VOID, // Geçersiz/EOF sinyali.
// Parser içinde kullanılır. Tokenizer ÜRETMEZ.
// currentToken() geçersiz indeks gösterdiğinde döner.
/* ====== Kontrol Akışı Keyword'leri ====== */
KW_IF, // if (koşullu dal)
// Sözdizimi: if (koşul) gövde [else gövde]
KW_ELSE, // else (if'in alternatif dalı)
// Sözdizimi: if (...) ... else ...
// Parser'da if'ten sonra else opsiyoneldir.
KW_FOR, // for (tekrarlı döngü)
// Sözdizimi: for (init; koşul; artım) gövde
KW_WHILE, // while (koşullu döngü)
// Sözdizimi: while (koşul) gövde
KW_DO, // do (en az bir kez çalışan döngü)
// Sözdizimi: do gövde while (koşul);
KW_SWITCH, // switch (çoklu dal — henüz implemente edilmedi)
KW_CASE, // case (switch dalı — henüz implemente edilmedi)
KW_DEFAULT, // default (switch varsayılan — henüz implemente edilmedi)
KW_BREAK, // break (döngü/switch'ten çık)
// Sadece döngü veya switch içinde geçerlidir.
KW_CONTINUE, // continue (döngünün bir sonraki iterasyonuna geç)
// Sadece döngü içinde geçerlidir.
KW_RETURN, // return (fonksiyondan dön)
// İsteğe bağlı dönüş değeri: return expr;
/* ====== OOP Keyword'leri ====== */
KW_CLASS, // class (sınıf tanımı — Java/C++ tarzı)
KW_STRUCT, // struct (yapı tanımı — C tarzı)
// saQut'ta class ve struct ikisi de desteklenir.
KW_INTERFACE, // interface (soyut tip — Java tarzı)
KW_ENUM, // enum (sabit listesi — C/C++/Java tarzı)
KW_EXTENDS, // extends (kalıtım — Java tarzı)
KW_IMPLEMENTS, // implements (interface gerçekleme — Java tarzı)
KW_NEW, // new (nesne oluşturma — Java/C++ tarzı)
KW_PUBLIC, // public (erişim belirteci)
KW_PRIVATE, // private (erişim belirteci)
KW_PROTECTED, // protected (erişim belirteci — alt sınıflara açık)
KW_STATIC, // static (sınıf üyesi / dosya içi bağlantı)
KW_FINAL, // final (değiştirilemez — Java tarzı)
KW_ABSTRACT, // abstract (soyut sınıf/metot — Java tarzı)
/* ====== Tip Keyword'leri ====== */
KW_VOID, // void (değer döndürmeyen fonksiyon / tip yok)
// C/C++/Java uyumluluğu için.
KW_BOOL, // bool (mantıksal tip: true/false)
// C++ bool ile aynı.
KW_INT, // int (tamsayı tipi: 32-bit işaretli)
// Varsayılan tamsayı tipi.
KW_FLOAT_TYPE, // float (32-bit ondalıklı sayı)
// FLOAT_MATH hatasından kaçınmak için _TYPE eki.
// math.h'deki float tanımıyla çakışmaz.
KW_DOUBLE, // double (64-bit ondalıklı sayı)
KW_CHAR, // char (8-bit karakter)
// Tek tırnak içindeki karakterler için: 'A'
KW_STRING_TYPE, // string (metin tipi)
// string.h'daki string işlevleriyle çakışmaz.
/* ====== Literal Keyword'ler ====== */
KW_TRUE, // true (mantıksal doğru sabiti)
// Boolean literal: if (true) { ... }
KW_FALSE, // false (mantıksal yanlış sabiti)
// Boolean literal: while (false) { ... }
KW_NULL, // null (boş referans sabiti)
// Pointer/referans tipleri için: Object obj = null;
/* ====== İstisna Yönetimi ====== */
KW_TRY, // try (istisna deneme bloğu — Java/C++ tarzı)
// Sözdizimi: try { ... } catch (Ex e) { ... }
KW_CATCH, // catch (istisna yakalama bloğu)
KW_FINALLY, // finally (her durumda çalışan blok — Java tarzı)
KW_THROW, // throw (istisna fırlatma — C++/Java tarzı)
// Sözdizimi: throw new Exception("hata");
KW_THROWS, // throws (metot imzasında istisna bildirimi — Java)
KW_ASSERT, // assert (debug assertions — C/Java tarzı)
/* ====== Modül/Paket ====== */
KW_IMPORT, // import (modül içe aktarma — Java/Python tarzı)
// Sözdizimi: import java.util.List;
KW_PACKAGE, // package (modül bildirimi — Java tarzı)
// Sözdizimi: package com.saqut.compiler;
/* ====== C/C++ Ekleri ====== */
KW_NATIVE, // native (yerel kod bildirimi — JNI)
// Java native metotları için.
KW_SYNCHRONIZED, // synchronized (iş parçacığı senkronizasyonu — Java)
KW_VOLATILE, // volatile (derleyici optimizasyonunu engelle — C/C++/Java)
KW_TRANSIENT, // transient (serileştirmeyi atla — Java)
KW_CONST, // const (değişmez değer — C/C++ tarzı)
// Örn: const int MAX = 100;
KW_EXTERN, // extern (harici bağlantı — C/C++ tarzı)
KW_TYPEDEF, // typedef (tip takma adı — C/C++ tarzı)
KW_SIZEOF, // sizeof (tip/boyut sorgulama — C/C++ tarzı)
// Sözdizimi: sizeof(int) veya sizeof x
KW_ALIGNOF, // alignof (hizalama sorgulama — C++11)
KW_DECLTYPE, // decltype (ifade tipi çıkarımı — C++11)
KW_AUTO, // auto (otomatik tip çıkarımı — C++11)
KW_CONSTEXPR, // constexpr (derleme zamanı sabiti — C++11)
KW_NOEXCEPT, // noexcept (istisna fırlatmayan bildirimi — C++11)
/* ================================================================
* Operatörler — Öncelik sırasına göre gruplanmış
*
* Her operatörün yanında Pratt parser öncelik seviyesi yazılıdır.
* Yüksek sayı = daha sıkı bağlanma (önce işlenir).
*
* Seviye 18 (en yüksek): Üye erişimi ve çağrı
* Seviye 17: Postfix ++ --
* Seviye 16: Unary prefix + - ! ~
* Seviye 15: Üs alma ** ^
* Seviye 14: Çarpma/Bölme * / %
* Seviye 13: Toplama/Çıkarma + -
* Seviye 12: Bitsel kaydırma << >>
* Seviye 11: İlişkisel < <= > >=
* Seviye 10: Eşitlik == !=
* Seviye 9: Bitsel VE &
* Seviye 8: Bitsel XOR ^ (CARET üs olarak 15'te)
* Seviye 7: Bitsel VEYA |
* Seviye 6: Mantıksal VE &&
* Seviye 5: Mantıksal VEYA ||
* Seviye 4: Ternary ?
* Seviye 3: Ternary else :
* Seviye 2: Atama = += -= vb.
* Seviye 1 (en düşük): Virgül ,
* ================================================================ */
// Seviye 18: Üye erişimi ve çağrı — En yüksek öncelik
DOT, // . (üye erişimi) — obj.field
// Öncelik 18. En sıkı bağlanan operatör.
ARROW, // -> (pointer üye erişimi) — ptr->field
// C++ tarzı. Öncelik 18.
LBRACKET, // [ (dizi/indeks erişimi başlangıcı) — a[i]
// Açılış köşeli parantez. Öncelik 18.
RBRACKET, // ] (dizi/indeks erişimi bitişi) — a[i]
// Kapanış köşeli parantez. Tek başına kullanılmaz.
LPAREN, // ( (fonksiyon çağrısı/grouping başlangıcı)
// İki anlamı: f(args) çağrı, (expr) gruplama.
// Öncelik 18.
RPAREN, // ) (fonksiyon çağrısı/grouping bitişi)
// Kapanış parantez. Tek başına kullanılmaz.
// Seviye 17: Postfix — Soldaki ifadeye sonradan uygulanan operatörler
PLUS_PLUS, // ++ (postfix artım) — x++
// Önce x'in değerini döndür, sonra artır.
// Öncelik 17. Sağ birleşmeli DEĞİL.
MINUS_MINUS, // -- (postfix azaltım) — x--
// Önce x'in değerini döndür, sonra azalt.
// Öncelik 17.
// Seviye 16: Unary Prefix — Sağındaki ifadeye uygulanan tekli operatörler
PLUS, // + (unary plus / binary toplama)
// Unary: +x (pozitif işareti, genelde etkisiz).
// Binary: a + b (toplama, öncelik 13).
// Hangi anlamda kullanıldığı parse bağlamında belirlenir.
MINUS, // - (unary minus / binary çıkarma)
// Unary: -x (negatif yap).
// Binary: a - b (çıkarma, öncelik 13).
BANG, // ! (mantıksal değil) — !x
// Örn: if (!flag) { ... }
// Sadece prefix. Öncelik 16.
TILDE, // ~ (bitsel değil) — ~x
// Bitwise NOT. Sadece prefix. Öncelik 16.
// Seviye 15: Üs alma — Sağ birleşmeli
STAR_STAR, // ** (üs alma) — a ** b = a^b
// Python tarzı. Öncelik 15. Sağ birleşmeli.
// 2 ** 3 ** 2 = 2 ** (3 ** 2) = 512
CARET, // ^ (üs alma veya bitsel XOR)
// saQut'ta varsayılan: üs alma (öncelik 15).
// C/C++'da XOR (öncelik 8) — bağlama göre değişebilir.
// Seviye 14: Çarpma/Bölme — Sol birleşmeli
STAR, // * (çarpma) — a * b
// Öncelik 14.
SLASH, // / (bölme) — a / b
// Tamsayı bölmesi: int / int = int.
// Ondalık bölme: float / float = float.
PERCENT, // % (mod alma) — a % b
// Sadece tamsayılar için.
// Seviye 13: Toplama/Çıkarma
// PLUS ve MINUS yukarıda tanımlandı (hem unary 16 hem binary 13).
// Pratt parser bağlama göre doğru önceliği kullanır.
// Seviye 12: Bitsel kaydırma
LSHIFT, // << (sola kaydırma) — a << b
// a * 2^b. Öncelik 12.
RSHIFT, // >> (sağa kaydırma) — a >> b
// a / 2^b (işaretli: arithmetic, işaretsiz: logical).
// Seviye 11: İlişkisel karşılaştırma
LESS, // < (küçüktür) — a < b
// true/false döndürür.
LESS_EQUAL, // <= (küçük eşittir) — a <= b
GREATER, // > (büyüktür) — a > b
GREATER_EQUAL, // >= (büyük eşittir) — a >= b
// Seviye 10: Eşitlik
EQUAL_EQUAL, // == (eşittir) — a == b
// Değer eşitliği. Öncelik 10.
BANG_EQUAL, // != (eşit değildir) — a != b
// Seviye 9: Bitsel VE
AMPERSAND, // & (bitsel VE) — a & b
// Bitwise AND. Öncelik 9.
// Seviye 8: Bitsel XOR
// ^ (CARET) yukarıda (üs olarak seviye 15'te).
// Gelecekte XOR için ayrı token eklenebilir.
// Seviye 7: Bitsel VEYA
PIPE, // | (bitsel VEYA) — a | b
// Bitwise OR. Öncelik 7.
// Seviye 6: Mantıksal VE
AMPERSAND_AMPERSAND, // && (mantıksal VE) — a && b
// Kısa devre (short-circuit): a false ise b değerlendirilmez.
// Öncelik 6.
// Seviye 5: Mantıksal VEYA
PIPE_PIPE, // || (mantıksal VEYA) — a || b
// Kısa devre: a true ise b değerlendirilmez.
// Öncelik 5.
// Seviye 4: Üçlü koşul (ternary) — Sağ birleşmeli
TERNARY, // ? (ternary if) — a ? b : c
// Öncelik 4. Sağ birleşmeli.
// a ? b : c ? d : e = a ? b : (c ? d : e)
COLON, // : (ternary else / etiket) — ternary'in ikinci kısmı
// Ternary'de öncelik 3 (0 değil!).
// Ayrıca switch/case etiketleri için de kullanılır.
// Seviye 2: Atama — Sağ birleşmeli
EQUAL, // = (basit atama) — a = b
// Öncelik 2. Sağ birleşmeli.
// a = b = 5 = a = (b = 5)
PLUS_EQUAL, // += (topla ve ata) — a += b → a = a + b
MINUS_EQUAL, // -= (çıkar ve ata) — a -= b → a = a - b
STAR_EQUAL, // *= (çarp ve ata) — a *= b → a = a * b
SLASH_EQUAL, // /= (böl ve ata) — a /= b → a = a / b
PERCENT_EQUAL, // %= (mod al ve ata) — a %= b → a = a % b
AMPERSAND_EQUAL, // &= (bitsel VE ve ata) — a &= b → a = a & b
PIPE_EQUAL, // |= (bitsel VEYA ve ata) — a |= b → a = a | b
CARET_EQUAL, // ^= (XOR ve ata) — a ^= b → a = a ^ b
LSHIFT_EQUAL, // <<= (sola kaydır ve ata) — a <<= b → a = a << b
RSHIFT_EQUAL, // >>= (sağa kaydır ve ata) — a >>= b → a = a >> b
/* ====== Diğer Semboller ====== */
LBRACE, // { (açılış süslü parantez) — blok başlangıcı
// Sözdizimi: { statement1; statement2; }
RBRACE, // } (kapanış süslü parantez) — blok bitişi
SEMICOLON, // ; (noktalı virgül) — ifade sonu belirteci
// C/C++/Java tarzında her ifade ; ile biter.
COMMA, // , (virgül) — ifade ayırıcı
// Örn: int a, b, c; veya f(1, 2, 3)
// Öncelik 1 (en düşük).
COLON_COLON, // :: (kapsam çözümleme) — Class::method
// C++ tarzı. Şu anda sadece token tanımlı, parse yok.
/* ====== Özel Token'lar ====== */
END_OF_FILE, // Dosya sonu belirteci.
// Tokenizer dosya sonuna gelindiğinde üretir.
// Parser'ın durma koşuludur.
UNKNOWN, // Bilinmeyen/tanınamayan karakter.
// Tokenizer'ın çözemediği her şey.
// Hata raporlamada kullanılır.
COMMENT, // Yorum token'ı (// veya /* */).
// ŞU ANDA TOKEN ÜRETİLMEZ — tokenizer yorumları atlar.
// Gelecekte belge yorumları (///, /** */) için kullanılabilir.
PREPROCESSOR, // Önişlemci direktifi (#).
// ŞU ANDA KULLANILMIYOR — C önişlemcisi yok.
// Gelecekte #include, #define için.
};
// ============================================================================
// KEYWORD_MAP — Keyword String → TokenType Dönüşüm Haritası
// ============================================================================
//
// AMAÇ: Tokenizer'ın ürettiği KeywordToken'ların token değerini (örn: "if")
// Parser'ın anlayacağı TokenType'a (KW_IF) dönüştürür.
//
// ANAHTAR: std::string_view — keyword string'i (kopyalanmaz, salt okunur)
// DEĞER: TokenType — Parser'ın anlayacağı anlamsal tip
//
// VERİ YAPISI: std::unordered_map<string_view, TokenType>
// - O(1) ortalama arama süresi
// - constexpr: derleme zamanı sabiti (derleyici tabloya gömer)
// - std::string_view: string kopyalamadan kaçınır (performans)
//
// BOYUT: ~60 girdi (tüm keyword'ler)
// NEDEN unordered_map, neden map değil?
// - Arama sıklığı: her token için bir kez
// - unordered_map O(1) vs map O(log n) — fark küçük ama var
// - Sıralı erişim gerekmez
//
// SENKRONİZASYON UYARISI:
// Bu harita, Tokenizer'daki keywords[] dizisi İLE EŞLEŞMELİDİR.
// Birinde ekleme yapılırsa diğerine de eklenmelidir.
// TODO: İki listeyi ortak bir kaynaktan üretecek bir makro/kod üreteci.
//
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 Dönüşüm Haritası
// ============================================================================
//
// AMAÇ: 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.
//
// ANAHTAR: std::string_view — operatör/delimiter string'i (örn: "+", "->", "{")
// DEĞER: TokenType — Parser'ın anlayacağı anlamsal tip
//
// VERİ YAPISI: std::unordered_map<string_view, TokenType>
// - O(1) ortalama arama
// - const: derleme zamanı sabiti
// - Boyut: ~40 girdi
//
// NEDEN İKİ AYRI HARİTA DEĞİL (operator + delimiter)?
// - Parser seviyesinde fark yok: {, }, ; hepsi operatör gibi işlenir.
// - Tek harita = tek arama = daha basit kod.
//
// SIRALAMA UYARISI:
// Bu haritada sıralama önemli DEĞİL (unordered_map).
// ANCAK Tokenizer'daki operators[] ve delimiters[] dizilerindeki
// sıralama ÖNEMLİDİR — çok karakterliler önce gelmelidir!
// Örn: "->" önce, "-" sonra kontrol edilmelidir.
//
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/Görüntüleme İçin)
// ============================================================================
//
// AMAÇ: TokenType enum değerini insan tarafından okunabilir operatör
// sembolüne dönüştürür. Log çıktısı ve hata mesajları için kullanılır.
//
// ANAHTAR: TokenType — enum değeri (örn: TokenType::PLUS)
// DEĞER: std::string_view — operatör sembolü (örn: "+")
//
// KULLANIM:
// auto it = OPERATOR_MAP_REV.find(type);
// if (it != OPERATOR_MAP_REV.end()) std::cout << it->second;
//
// NOT: TokenType::IDENTIFIER, NUMBER, STRING, KW_* ve özel token'lar
// bu haritada YOKTUR (operatör değiller). Onlar için ayrı dönüşüm gerekir.
//
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 (Debug/Log İçin)
// ============================================================================
//
// AMAÇ: AST log çıktısında operatörün enum ismini (string olarak) gösterir.
// OPERATOR_MAP_REV'den farkı: sembol yerine enum adı döndürür.
//
// KULLANIM:
// AST dump/debug çıktısı: TokenPrecedence(PLUS) yerine "PLUS(13)" gösterimi.
//
// ANAHTAR: TokenType — enum değeri (örn: TokenType::PLUS)
// DEĞER: std::string_view — enum ismi (örn: "PLUS")
//
// ÖRN: TokenType::PLUS → "PLUS"
// TokenType::PLUS_EQUAL → "PLUS_EQUAL"
//
// NOT: İki harita da (REV ve STRREV) aynı anahtarları içerir ama farklı değerler.
// REV: "+" (operatör sembolü)
// STRREV: "PLUS" (enum ismi)
//
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)
// ============================================================================
//
// AMAÇ: Her TokenType için bir öncelik seviyesi döndürür.
// Yüksek sayı = daha sıkı bağlanma (önce işlenir).
//
// PARAMETRE: type — sorgulanan token tipi
// DÖNÜŞ: uint16_t — öncelik seviyesi (0-18)
// KARMAŞIKLIK: O(1) — switch/case (derleyici jump table üretir)
//
// KULLANIM:
// uint16_t prec = TokenPrecedence(current.type);
// if (prec >= minPrec) { parseLeftDenotation(left); }
//
// ÖNCELİK SEVİYELERİ (yüksekten düşüğe):
// 18: Üye erişimi . -> [ ] ( ) — En yüksek
// 17: Postfix ++ --
// 16: Unary prefix ! ~ + -
// 15: Üs alma ** ^ — Sağ birleşmeli
// 14: Çarpma/Bölme * / %
// 13: Toplama/Çıkarma + -
// 12: Bitsel kaydırma << >>
// 11: İlişkisel < <= > >=
// 10: Eşitlik == !=
// 9: Bitsel VE &
// 8: Bitsel XOR ^ (şu anda üs olarak 15'te)
// 7: Bitsel VEYA |
// 6: Mantıksal VE &&
// 5: Mantıksal VEYA ||
// 4: Ternary ?
// 3: Ternary else :
// 2: Atama = += -= vb. — Sağ birleşmeli
// 1: Virgül ,
// 0: Önceliksiz (değerler, EOF, bilinmeyen)
//
// KARAR: Neden ^ (CARET) seviye 15 (üs) olarak ayarlı?
// - C/C++'da ^ bitsel XOR'tur (seviye 8).
// - Python'da ** üs, ^ XOR'tur.
// - saQut'ta ^ varsayılan olarak üs alma olarak kullanılır.
// - Gelecekte XOR için ayrı token (CARET_CARET ^^) eklenebilir.
//
// BUG FIX (commit 438bc0e):
// Seviye 8'de CARET için ölü kod (case olmadan return 8) vardı.
// 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 (Associativity) Kontrolü
// ============================================================================
//
// AMAÇ: Bir operatörün sağdan sola mı, yoksa soldan sağa mı birleştiğini
// belirler. Pratt parser'da doğru ağaç yapısını oluşturmak için kritik.
//
// PARAMETRE: type — sorgulanan operatör tipi
// DÖNÜŞ: bool — true: sağ birleşmeli, false: sol birleşmeli
// KARMAŞIKLIK: O(1) — switch/case
//
// Sağ birleşmeli operatörler (a OP b OP c = a OP (b OP c)):
// - STAR_STAR (üs alma): 2 ** 3 ** 2 = 2 ** (3 ** 2) = 2^9 = 512
// (matematiksel kural: üs sağdan sola birleşir)
// - CARET (üs alma): 2 ^ 3 ^ 2 = 2 ^ (3 ^ 2) = 512
// - EQUAL (atama): a = b = 5 → a = (b = 5)
// (önce b = 5 çalışır, sonra a = b)
// - +=, -=, *=, vb. (birleşik atama): a += b += 5 → a += (b += 5)
// - TERNARY (üçlü koşul): a ? b : c ? d : e → a ? b : (c ? d : e)
// (iç içe ternary'lerde sağdan sola)
//
// Sol birleşmeli operatörler (a OP b OP c = (a OP b) OP c):
// - Tüm diğerleri: +, -, *, /, ==, &&, ||, vb.
// (a + b + c = (a + b) + c, yani önce a+b, sonuç + c)
//
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ı (Köprü)
// ============================================================================
//
// AMAÇ: Tokenizer'ın ürettiği ham Token ile Parser'ın ihtiyaç duyduğu
// anlamsal tipi (TokenType) bir arada tutar. İki katman arasında
// köprü görevi görür.
//
// ALANLAR:
//
// token (Token*):
// Tokenizer'dan gelen orijinal token'a pointer.
// Neden pointer, neden değer (Token token) değil?
//
// Çünkü Token polimorfik bir sınıf hiyerarşisidir:
// Token (base)
// +-- NumberToken (isFloat, numberValue alanları)
// +-- StringToken (context alanı)
// +-- IdentifierToken
// +-- OperatorToken
// +-- DelimiterToken
// +-- KeywordToken
//
// Değer kopyası (Token token) OBJECT SLICING'e neden olur:
// NumberToken → Token'a kopyalanırken isFloat, numberValue KAYBOLUR.
//
// BUG FIX (commit 40579ca):
// Eskiden "Token token" (değer) olarak tanımlanmıştı.
// NumberToken.isFloat her zaman false dönüyordu çünkü slicing oluyordu.
// "Token* token" (pointer) olarak değiştirildi.
//
// type (TokenType):
// Token'ın anlamsal tipi. Örn: NUMBER, PLUS, KW_IF.
// Tokeni parselerken parseToken() tarafından atanır.
//
// METOTLAR:
// is(TokenType): Tek tip kontrolü (O(1))
// is(initializer_list): Çoklu tip kontrolü (O(k), k = liste boyutu)
// getPowerOperator(): Öncelik sorgulama (O(1), TokenPrecedence'a yönlendirir)
// isRightAssociative(): Birleşme yönü sorgulama (O(1))
//
struct ParserToken {
/* ====== Alanlar ====== */
// Tokenizer'dan gelen orijinal token pointer'ı.
// nullptr olabilir mi? Hayır — geçerli bir token her zaman vardır.
// SVR_VOID durumunda token nullptr olabilir (EOF sinyali).
Token* token = nullptr;
// Token'ın anlamsal tipi.
// Varsayılan: SVR_VOID (geçersiz/başlangıç değeri).
// parseToken() tarafından atanır.
TokenType type = TokenType::SVR_VOID;
/* ====== Kolaylık Metotları ====== */
// is() — Tek tip kontrolü
// PARAMETRE: t — sorgulanan token tipi
// DÖNÜŞ: true — bu token t tipinde
// KARMAŞIKLIK: O(1)
// KULLANIM: if (current.is(TokenType::SEMICOLON)) { ... }
bool is(TokenType t) const {
return type == t;
}
// is() — Çoklu tip kontrolü
// PARAMETRE: types — kontrol edilecek tipler listesi
// DÖNÜŞ: true — bu token listedeki tiplerden birine aitse
// KARMAŞIKLIK: O(k) — k = liste boyutu
// KULLANIM:
// if (current.is({KW_INT, KW_FLOAT, KW_VOID})) { ... }
// if (current.is({TokenType::SEMICOLON, TokenType::RPAREN})) { ... }
bool is(std::initializer_list<TokenType> types) const {
for (TokenType t : types)
if (type == t) return true;
return false;
}
// getPowerOperator() — Operatör önceliği sorgulama (Pratt parser için)
// DÖNÜŞ: uint16_t — öncelik seviyesi (0-18)
// KARMAŞIKLIK: O(1) — TokenPrecedence'a yönlendirir
// KULLANIM:
// uint16_t prec = current.getPowerOperator();
// while (prec >= minPrec) { ... parseLeftDenotation(left); }
uint16_t getPowerOperator() const {
return TokenPrecedence(type);
}
// isRightAssociative() — Birleşme yönü sorgulama
// DÖNÜŞ: true — sağ birleşmeli (atama, üs, ternary)
// false — sol birleşmeli (toplama, çarpma, vb.)
// KARMAŞIKLIK: O(1) — RightAssociative'a yönlendirir
// KULLANIM:
// bool rightAssoc = current.isRightAssociative();
// uint16_t nextPrec = rightAssoc ? prec : prec + 1;
bool isRightAssociative() const {
return RightAssociative(type);
}
};
#endif // SAQUT_PARSER_TOKEN