parser: function calls, struct, member/index access - Final.sqt parses successfully (289 tokens, 200+ AST nodes)
This commit is contained in:
parent
4d3150e811
commit
6aa0da2378
|
|
@ -0,0 +1,89 @@
|
|||
int fibonacci(int n) {
|
||||
if (n <= 1)
|
||||
return n;
|
||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||
}
|
||||
|
||||
void fibonacciIterative(int n) {
|
||||
int first = 0, second = 1, next;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i <= 1)
|
||||
next = i;
|
||||
else {
|
||||
next = first + second;
|
||||
first = second;
|
||||
second = next;
|
||||
}
|
||||
printf("%d ", next);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n = 10;
|
||||
|
||||
// Formatlı ifade kullanmadan, string concatenation mantığı ile
|
||||
printf("");
|
||||
printf(n);
|
||||
printf(" elemanlı Fibonacci dizisi (iterative):\n");
|
||||
fibonacciIterative(n);
|
||||
|
||||
printf("\n");
|
||||
printf("");
|
||||
printf(n);
|
||||
printf(". Fibonacci sayısı (recursive): ");
|
||||
printf(fibonacci(n - 1));
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct List {
|
||||
int arr[100];
|
||||
int length;
|
||||
};
|
||||
|
||||
struct List createList() {
|
||||
struct List list;
|
||||
list.length = 0;
|
||||
return list;
|
||||
}
|
||||
|
||||
void push(struct List* list, int value) {
|
||||
if (list->length < 100) {
|
||||
list->arr[list->length] = value;
|
||||
list->length++;
|
||||
}
|
||||
}
|
||||
|
||||
int get(struct List* list, int index) {
|
||||
if (index < list->length) {
|
||||
return list->arr[index];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void printList(struct List* list) {
|
||||
for (int i = 0; i < list->length; i++) {
|
||||
// println yerine direkt yaz
|
||||
int val = list->arr[i];
|
||||
// sayıyı göster
|
||||
}
|
||||
// yeni satır
|
||||
}
|
||||
|
||||
int main() {
|
||||
struct List myList = createList();
|
||||
|
||||
push(myList, 5);
|
||||
push(myList, 10);
|
||||
push(myList, 15);
|
||||
|
||||
// JavaScript benzeri kullanım
|
||||
// myList[0] gibi düşün
|
||||
|
||||
printList(myList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
11
source.sqt
11
source.sqt
|
|
@ -1,10 +1 @@
|
|||
int main() {
|
||||
int x = 0;
|
||||
while (x < 5) {
|
||||
x = x + 1;
|
||||
}
|
||||
do {
|
||||
x = x - 1;
|
||||
} while (x > 0);
|
||||
return x;
|
||||
}
|
||||
int main() { int x = 0; while (x < 5) { x = x + 1; } do { x = x - 1; } while (x > 0); return x; }
|
||||
|
|
|
|||
49
src/json.hpp
49
src/json.hpp
|
|
@ -49,6 +49,10 @@ inline const char* astKindName(ASTKind k) {
|
|||
case ASTKind::BreakStatement: return "BreakStatement";
|
||||
case ASTKind::ContinueStatement: return "ContinueStatement";
|
||||
case ASTKind::ExpressionStatement: return "ExpressionStatement";
|
||||
case ASTKind::Call: return "Call";
|
||||
case ASTKind::MemberAccess: return "MemberAccess";
|
||||
case ASTKind::IndexExpression: return "IndexExpression";
|
||||
case ASTKind::StructDecl: return "StructDecl";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
|
@ -158,6 +162,27 @@ inline void analyzeRecursive(ASTNode* node, int currentDepth, AstAnalysis& a) {
|
|||
if (es->expression) analyzeRecursive(es->expression, currentDepth + 1, a);
|
||||
break;
|
||||
}
|
||||
case ASTKind::Call: {
|
||||
auto* call = (CallExpressionNode*)node;
|
||||
if (call->callee) analyzeRecursive(call->callee, currentDepth + 1, a);
|
||||
for (auto* arg : call->arguments) analyzeRecursive(arg, currentDepth + 1, a);
|
||||
break;
|
||||
}
|
||||
case ASTKind::MemberAccess: {
|
||||
auto* ma = (MemberAccessNode*)node;
|
||||
if (ma->object) analyzeRecursive(ma->object, currentDepth + 1, a);
|
||||
break;
|
||||
}
|
||||
case ASTKind::IndexExpression: {
|
||||
auto* ie = (IndexExpressionNode*)node;
|
||||
if (ie->object) analyzeRecursive(ie->object, currentDepth + 1, a);
|
||||
if (ie->index) analyzeRecursive(ie->index, currentDepth + 1, a);
|
||||
break;
|
||||
}
|
||||
case ASTKind::StructDecl: {
|
||||
for (auto* child : node->getChildren()) analyzeRecursive(child, currentDepth + 1, a);
|
||||
break;
|
||||
}
|
||||
default: break; // Literal, Identifier, Break, Continue — yaprak düğüm
|
||||
}
|
||||
}
|
||||
|
|
@ -204,6 +229,9 @@ inline void collectSymbolsRecursive(ASTNode* node, std::vector<SymbolEntry>& sym
|
|||
if (node->kind == ASTKind::FunctionDecl) {
|
||||
auto* fn = (FunctionDeclNode*)node;
|
||||
symbols.push_back({fn->name, "function", fn->returnType});
|
||||
} else if (node->kind == ASTKind::StructDecl) {
|
||||
auto* st = (StructDeclNode*)node;
|
||||
symbols.push_back({st->name, "struct", ""});
|
||||
} else if (node->kind == ASTKind::VariableDecl) {
|
||||
auto* vd = (VariableDeclNode*)node;
|
||||
symbols.push_back({vd->name, "variable", vd->varType});
|
||||
|
|
@ -270,6 +298,27 @@ inline void collectSymbolsRecursive(ASTNode* node, std::vector<SymbolEntry>& sym
|
|||
if (es->expression) collectSymbolsRecursive(es->expression, symbols);
|
||||
break;
|
||||
}
|
||||
case ASTKind::Call: {
|
||||
auto* call = (CallExpressionNode*)node;
|
||||
if (call->callee) collectSymbolsRecursive(call->callee, symbols);
|
||||
for (auto* arg : call->arguments) collectSymbolsRecursive(arg, symbols);
|
||||
break;
|
||||
}
|
||||
case ASTKind::MemberAccess: {
|
||||
auto* ma = (MemberAccessNode*)node;
|
||||
if (ma->object) collectSymbolsRecursive(ma->object, symbols);
|
||||
break;
|
||||
}
|
||||
case ASTKind::IndexExpression: {
|
||||
auto* ie = (IndexExpressionNode*)node;
|
||||
if (ie->object) collectSymbolsRecursive(ie->object, symbols);
|
||||
if (ie->index) collectSymbolsRecursive(ie->index, symbols);
|
||||
break;
|
||||
}
|
||||
case ASTKind::StructDecl: {
|
||||
for (auto* child : node->getChildren()) collectSymbolsRecursive(child, symbols);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@ enum class ASTKind {
|
|||
BreakStatement, // break
|
||||
ContinueStatement, // continue
|
||||
ExpressionStatement, // ifade + ;
|
||||
Call, // Fonksiyon çağrısı f(args)
|
||||
MemberAccess, // Üye erişimi a.b, a->b
|
||||
IndexExpression, // Dizi erişimi a[i]
|
||||
StructDecl, // struct tanımı
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -669,4 +673,149 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// CallExpressionNode — Fonksiyon Çağrısı f(a, b, ...)
|
||||
// ============================================================================
|
||||
|
||||
class CallExpressionNode : public ASTNode {
|
||||
public:
|
||||
ASTNode* callee = nullptr;
|
||||
std::vector<ASTNode*> arguments;
|
||||
|
||||
CallExpressionNode() { kind = ASTKind::Call; }
|
||||
|
||||
void log(int indent = 0) override {
|
||||
std::cout << padRight("", indent) << "Call\n";
|
||||
if (callee) {
|
||||
std::cout << padRight("", indent + 2) << "Callee:\n";
|
||||
callee->log(indent + 4);
|
||||
}
|
||||
std::cout << padRight("", indent + 2) << "Args (" << arguments.size() << "):\n";
|
||||
for (auto* a : arguments) a->log(indent + 4);
|
||||
}
|
||||
|
||||
std::string toJson(int depth = 0) override {
|
||||
std::string in = jsonIndent(depth);
|
||||
std::ostringstream ss;
|
||||
ss << in << "{\n"
|
||||
<< in << " \"kind\": \"Call\"";
|
||||
if (callee) {
|
||||
ss << ",\n" << in << " \"callee\":\n"
|
||||
<< callee->toJson(depth + 2);
|
||||
}
|
||||
ss << ",\n" << in << " \"arguments\": [\n";
|
||||
for (size_t i = 0; i < arguments.size(); i++) {
|
||||
ss << arguments[i]->toJson(depth + 3);
|
||||
if (i + 1 < arguments.size()) ss << ",";
|
||||
ss << "\n";
|
||||
}
|
||||
ss << in << " ]\n" << in << "}";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// MemberAccessNode — Üye Erişimi a.b veya a->b
|
||||
// ============================================================================
|
||||
|
||||
class MemberAccessNode : public ASTNode {
|
||||
public:
|
||||
ASTNode* object = nullptr;
|
||||
std::string member;
|
||||
bool arrow = false;
|
||||
|
||||
MemberAccessNode() { kind = ASTKind::MemberAccess; }
|
||||
|
||||
void log(int indent = 0) override {
|
||||
std::cout << padRight("", indent) << "MemberAccess "
|
||||
<< (arrow ? "->" : ".") << " " << member << "\n";
|
||||
if (object) object->log(indent + 2);
|
||||
}
|
||||
|
||||
std::string toJson(int depth = 0) override {
|
||||
std::string in = jsonIndent(depth);
|
||||
std::ostringstream ss;
|
||||
ss << in << "{\n"
|
||||
<< in << " \"kind\": \"MemberAccess\",\n"
|
||||
<< in << " \"member\": \"" << jsonEscape(member) << "\",\n"
|
||||
<< in << " \"arrow\": " << (arrow ? "true" : "false");
|
||||
if (object) {
|
||||
ss << ",\n" << in << " \"object\":\n"
|
||||
<< object->toJson(depth + 2);
|
||||
}
|
||||
ss << "\n" << in << "}";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// IndexExpressionNode — Dizi Erişimi a[i]
|
||||
// ============================================================================
|
||||
|
||||
class IndexExpressionNode : public ASTNode {
|
||||
public:
|
||||
ASTNode* object = nullptr;
|
||||
ASTNode* index = nullptr;
|
||||
|
||||
IndexExpressionNode() { kind = ASTKind::IndexExpression; }
|
||||
|
||||
void log(int indent = 0) override {
|
||||
std::cout << padRight("", indent) << "IndexExpression\n";
|
||||
if (object) {
|
||||
std::cout << padRight("", indent + 2) << "Object:\n";
|
||||
object->log(indent + 4);
|
||||
}
|
||||
if (index) {
|
||||
std::cout << padRight("", indent + 2) << "Index:\n";
|
||||
index->log(indent + 4);
|
||||
}
|
||||
}
|
||||
|
||||
std::string toJson(int depth = 0) override {
|
||||
std::string in = jsonIndent(depth);
|
||||
std::ostringstream ss;
|
||||
ss << in << "{\n"
|
||||
<< in << " \"kind\": \"IndexExpression\"";
|
||||
if (object) {
|
||||
ss << ",\n" << in << " \"object\":\n"
|
||||
<< object->toJson(depth + 2);
|
||||
}
|
||||
if (index) {
|
||||
ss << ",\n" << in << " \"index\":\n"
|
||||
<< index->toJson(depth + 2);
|
||||
}
|
||||
ss << "\n" << in << "}";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// StructDeclNode — struct Tanımı
|
||||
// ============================================================================
|
||||
|
||||
class StructDeclNode : public ASTNode {
|
||||
public:
|
||||
std::string name;
|
||||
|
||||
StructDeclNode() { kind = ASTKind::StructDecl; }
|
||||
|
||||
void log(int indent = 0) override {
|
||||
std::cout << padRight("", indent) << "StructDecl " << name << "\n";
|
||||
for (auto* c : getChildren()) c->log(indent + 2);
|
||||
}
|
||||
|
||||
std::string toJson(int depth = 0) override {
|
||||
std::string in = jsonIndent(depth);
|
||||
std::ostringstream ss;
|
||||
ss << in << "{\n"
|
||||
<< in << " \"kind\": \"StructDecl\",\n"
|
||||
<< in << " \"name\": \"" << jsonEscape(name) << "\",\n"
|
||||
<< in << " \"children\": [\n"
|
||||
<< childrenToJson(this, depth + 3)
|
||||
<< in << " ]\n"
|
||||
<< in << "}";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
#endif // SAQUT_AST
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ private:
|
|||
// --- Deklarasyonlar ---
|
||||
ASTNode* parseDeclaration();
|
||||
ASTNode* parseFunctionDecl();
|
||||
ASTNode* parseStructDecl();
|
||||
ASTNode* parseVariableDecl();
|
||||
|
||||
// --- Statement'lar ---
|
||||
|
|
@ -267,7 +268,11 @@ inline ASTNode* Parser::parseDeclaration() {
|
|||
return parseVariableDecl();
|
||||
}
|
||||
|
||||
// Tip keyword'ü değil → statement (veya REPL ifadesi)
|
||||
// struct
|
||||
if (ct.type == TokenType::KW_STRUCT)
|
||||
return parseStructDecl();
|
||||
|
||||
// Tip keyword'ü değil → statement
|
||||
return parseStatement();
|
||||
}
|
||||
|
||||
|
|
@ -308,6 +313,29 @@ inline ASTNode* Parser::parseFunctionDecl() {
|
|||
|
||||
return fn;
|
||||
}
|
||||
// --------------------------------------------------------------------------
|
||||
// parseStructDecl: struct tanimi.
|
||||
// --------------------------------------------------------------------------
|
||||
inline ASTNode* Parser::parseStructDecl() {
|
||||
StructDeclNode* st = new StructDeclNode();
|
||||
nextToken();
|
||||
if (currentToken().type == TokenType::IDENTIFIER) {
|
||||
st->name = currentToken().token->token;
|
||||
nextToken();
|
||||
}
|
||||
if (currentToken().type == TokenType::LBRACE) {
|
||||
nextToken();
|
||||
while (currentToken().type != TokenType::RBRACE && currentToken().type != TokenType::SVR_VOID) {
|
||||
ASTNode* field = parseDeclaration();
|
||||
if (field) st->addChild(field);
|
||||
else break;
|
||||
}
|
||||
if (currentToken().type == TokenType::RBRACE) nextToken();
|
||||
}
|
||||
if (currentToken().type == TokenType::SEMICOLON) nextToken();
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// parseVariableDecl: Değişken tanımı.
|
||||
|
|
@ -805,9 +833,8 @@ inline ASTNode* Parser::parseLeftDenotation(ASTNode* left) {
|
|||
auto ct = currentToken();
|
||||
|
||||
// --- Postfix: expr++, expr-- ---
|
||||
// Operatör operand'dan SONRA gelir, sağ operand yok.
|
||||
if (ct.is({TokenType::PLUS_PLUS, TokenType::MINUS_MINUS})) {
|
||||
nextToken(); // Operatörü tüket
|
||||
nextToken();
|
||||
PostfixNode* pf = new PostfixNode();
|
||||
pf->operand = left;
|
||||
pf->Operator = ct.type;
|
||||
|
|
@ -815,13 +842,60 @@ inline ASTNode* Parser::parseLeftDenotation(ASTNode* left) {
|
|||
return pf;
|
||||
}
|
||||
|
||||
// --- Binary infix: expr OP expr ---
|
||||
// OP'nin önceliğine göre sağ operand'ı ayrıştır.
|
||||
uint16_t prec = ct.getPowerOperator();
|
||||
nextToken(); // Operatörü tüket
|
||||
// --- Fonksiyon cagrisi: expr(args) ---
|
||||
if (ct.type == TokenType::LPAREN) {
|
||||
nextToken();
|
||||
CallExpressionNode* call = new CallExpressionNode();
|
||||
call->callee = left;
|
||||
left->parent = call;
|
||||
|
||||
if (currentToken().type != TokenType::RPAREN) {
|
||||
call->arguments.push_back(parseExpression(0));
|
||||
while (currentToken().type == TokenType::COMMA) {
|
||||
nextToken();
|
||||
call->arguments.push_back(parseExpression(0));
|
||||
}
|
||||
}
|
||||
if (currentToken().type == TokenType::RPAREN)
|
||||
nextToken();
|
||||
return call;
|
||||
}
|
||||
|
||||
// --- Dizi erisimi: expr[index] ---
|
||||
if (ct.type == TokenType::LBRACKET) {
|
||||
nextToken();
|
||||
IndexExpressionNode* idx = new IndexExpressionNode();
|
||||
idx->object = left;
|
||||
left->parent = idx;
|
||||
idx->index = parseExpression(0);
|
||||
if (currentToken().type == TokenType::RBRACKET)
|
||||
nextToken();
|
||||
return idx;
|
||||
}
|
||||
|
||||
// --- Uye erisimi: expr.member / expr->member ---
|
||||
if (ct.type == TokenType::DOT || ct.type == TokenType::ARROW) {
|
||||
bool arrow = (ct.type == TokenType::ARROW);
|
||||
nextToken();
|
||||
|
||||
if (currentToken().type != TokenType::IDENTIFIER) {
|
||||
std::cerr << "Parser hatasi: uye ismi bekleniyor\n";
|
||||
return left;
|
||||
}
|
||||
|
||||
MemberAccessNode* ma = new MemberAccessNode();
|
||||
ma->object = left;
|
||||
ma->member = currentToken().token->token;
|
||||
ma->arrow = arrow;
|
||||
left->parent = ma;
|
||||
nextToken();
|
||||
return ma;
|
||||
}
|
||||
|
||||
// --- Binary infix: expr OP expr ---
|
||||
uint16_t prec = ct.getPowerOperator();
|
||||
nextToken();
|
||||
|
||||
// Sağ operand. prec parametresi, daha yüksek öncelikli operatörlerin
|
||||
// sağ operand içinde gruplanmasını sağlar.
|
||||
ASTNode* right = parseExpression(prec);
|
||||
|
||||
BinaryExpressionNode* bin = new BinaryExpressionNode();
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ enum class TokenType : uint16_t {
|
|||
|
||||
// --- OOP Keyword'leri ---
|
||||
KW_CLASS, // class
|
||||
KW_STRUCT, // struct
|
||||
KW_INTERFACE, // interface
|
||||
KW_ENUM, // enum
|
||||
KW_EXTENDS, // extends
|
||||
|
|
@ -302,6 +303,7 @@ inline const std::unordered_map<std::string_view, TokenType> KEYWORD_MAP = {
|
|||
|
||||
// --- OOP ---
|
||||
{"class", TokenType::KW_CLASS},
|
||||
{"struct", TokenType::KW_STRUCT},
|
||||
{"interface", TokenType::KW_INTERFACE},
|
||||
{"enum", TokenType::KW_ENUM},
|
||||
{"extends", TokenType::KW_EXTENDS},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
// ============================================================================
|
||||
// saQut Compiler — Token Sınıfları
|
||||
// ============================================================================
|
||||
//
|
||||
// DİZİN: src/tokenizer/token.hpp
|
||||
// KATMAN: Katman 2 — Tokenizer ile Parser arasında veri yapısı
|
||||
// BAĞIMLI: Yok (sadece <string>)
|
||||
//
|
||||
// AMAÇ:
|
||||
// Tüm token tiplerinin temel sınıfları. 6 adet polimorfik token tipi:
|
||||
// Token → NumberToken, StringToken, OperatorToken, DelimiterToken,
|
||||
// KeywordToken, IdentifierToken
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SAQUT_TOKENIZER_TOKEN
|
||||
#define SAQUT_TOKENIZER_TOKEN
|
||||
|
||||
#include <string>
|
||||
|
||||
class Token {
|
||||
protected:
|
||||
std::string type;
|
||||
public:
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
std::string token;
|
||||
std::string gettype() { return type; }
|
||||
virtual ~Token() = default;
|
||||
};
|
||||
|
||||
class StringToken : public Token {
|
||||
public:
|
||||
StringToken() { type = "string"; }
|
||||
std::string context;
|
||||
int size = 0;
|
||||
};
|
||||
|
||||
class NumberToken : public Token {
|
||||
public:
|
||||
NumberToken() { type = "number"; }
|
||||
bool isFloat = false;
|
||||
bool hasEpsilon = false;
|
||||
int base = 10;
|
||||
};
|
||||
|
||||
class OperatorToken : public Token {
|
||||
public:
|
||||
OperatorToken() { type = "operator"; }
|
||||
};
|
||||
|
||||
class DelimiterToken : public Token {
|
||||
public:
|
||||
DelimiterToken() { type = "delimiter"; }
|
||||
};
|
||||
|
||||
class KeywordToken : public Token {
|
||||
public:
|
||||
KeywordToken() { type = "keyword"; }
|
||||
};
|
||||
|
||||
class IdentifierToken : public Token {
|
||||
public:
|
||||
IdentifierToken() { type = "identifier"; }
|
||||
std::string context;
|
||||
int size = 0;
|
||||
};
|
||||
|
||||
#endif // SAQUT_TOKENIZER_TOKEN
|
||||
|
|
@ -73,124 +73,7 @@
|
|||
#include <vector>
|
||||
#include "lexer/lexer.hpp"
|
||||
|
||||
// ============================================================================
|
||||
// Token Temel Sınıfı
|
||||
// ============================================================================
|
||||
//
|
||||
// Tüm token tiplerinin ortak atası. Polimorfik kullanım için virtual destructor
|
||||
// içerir. type alanı, token'ın hangi alt sınıfa ait olduğunu string olarak tutar
|
||||
// (RTTI'ye alternatif, daha hafif).
|
||||
//
|
||||
// ALANLAR:
|
||||
// type : Token tipi ("number", "string", "operator", "delimiter", "keyword", "identifier")
|
||||
// token : Token'ın ham metin hali (örn: "42", "+", "if", "myVar")
|
||||
// start : Kaynak koddaki başlangıç offset'i (Lexer offset'i)
|
||||
// end : Kaynak koddaki bitiş offset'i
|
||||
//
|
||||
class Token {
|
||||
protected:
|
||||
std::string type; // Alt sınıf tarafından constructor'da atanır
|
||||
public:
|
||||
int start = 0; // Kaynak koddaki başlangıç konumu
|
||||
int end = 0; // Kaynak koddaki bitiş konumu
|
||||
std::string token; // Token'ın ham metin gösterimi
|
||||
|
||||
std::string gettype() { return type; }
|
||||
virtual ~Token() = default;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// StringToken — String Literal'ları ("...")
|
||||
// ============================================================================
|
||||
//
|
||||
// Örnek: "merhaba dünya", "satır\niki", "tırnak \" içinde"
|
||||
//
|
||||
// context: Escape sequence'ler çözümlenmiş gerçek string içeriği.
|
||||
// Örn: token="\"a\\nb\"" ise context="a\nb"
|
||||
// size: context'in uzunluğu (token'dan farklı olabilir)
|
||||
// token: Tırnak işaretleri ve escape sequence'ler dahil ham hali
|
||||
//
|
||||
class StringToken : public Token {
|
||||
public:
|
||||
StringToken() { type = "string"; }
|
||||
std::string context; // İşlenmiş string içeriği (escape'ler açılmış)
|
||||
int size = 0; // context uzunluğu
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// NumberToken — Sayısal Literal'lar (42, 0xFF, 3.14)
|
||||
// ============================================================================
|
||||
//
|
||||
// Sayı tabanı, float/整数 ayrımı, bilimsel gösterim bilgisi taşır.
|
||||
// Lexer'ın INumber yapısından dönüştürülür.
|
||||
//
|
||||
// isFloat: true ise float/double literal (nokta veya epsilon içerir)
|
||||
// hasEpsilon: true ise bilimsel gösterim (örn: 1e10)
|
||||
// base: Sayı tabanı: 2, 8, 10, 16
|
||||
// token: Sayının ham string hali (örn: "0xFF", "3.14e-2")
|
||||
//
|
||||
class NumberToken : public Token {
|
||||
public:
|
||||
NumberToken() { type = "number"; }
|
||||
bool isFloat = false; // Ondalıklı sayı mı?
|
||||
bool hasEpsilon = false; // Bilimsel gösterim (e/E) içeriyor mu?
|
||||
int base = 10; // Sayı tabanı
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// OperatorToken — Operatörler (+, -, *, /, ==, ++, vb.)
|
||||
// ============================================================================
|
||||
//
|
||||
// Aritmetik, karşılaştırma, mantıksal, bitsel, atama operatörleri.
|
||||
// Token değeri doğrudan operatörün string halidir: "+", "-", "==", "++".
|
||||
//
|
||||
class OperatorToken : public Token {
|
||||
public:
|
||||
OperatorToken() { type = "operator"; }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// DelimiterToken — Sınırlandırıcılar ({, }, (, ), [, ], ;, ,, ., ->, ::)
|
||||
// ============================================================================
|
||||
//
|
||||
// Kod yapısını belirleyen karakterler. Bloklar, parametre listeleri,
|
||||
// dizi indeksleri, ifade sonlandırma.
|
||||
//
|
||||
class DelimiterToken : public Token {
|
||||
public:
|
||||
DelimiterToken() { type = "delimiter"; }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// KeywordToken — Anahtar Kelimeler (if, for, while, int, void, ...)
|
||||
// ============================================================================
|
||||
//
|
||||
// Dilin rezerve edilmiş kelimeleri. Identifier olarak kullanılamazlar.
|
||||
// Tokenizer scope() fonksiyonu, keyword'leri identifier'lardan önce kontrol
|
||||
// eder. Keyword boundary check sayesinde "double" "do" olarak yanlış
|
||||
// eşleşmez.
|
||||
//
|
||||
class KeywordToken : public Token {
|
||||
public:
|
||||
KeywordToken() { type = "keyword"; }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// IdentifierToken — Tanımlayıcılar (değişken/fonksiyon isimleri)
|
||||
// ============================================================================
|
||||
//
|
||||
// Harf, rakam, _ ve $ karakterlerinden oluşan, keyword olmayan isimler.
|
||||
// Değişkenler, fonksiyonlar, sınıflar, metotlar için kullanılır.
|
||||
//
|
||||
// context: Şu anda token ile aynı (genişleme için ayrıldı)
|
||||
// size: Tanımlayıcının karakter uzunluğu
|
||||
//
|
||||
class IdentifierToken : public Token {
|
||||
public:
|
||||
IdentifierToken() { type = "identifier"; }
|
||||
std::string context; // Şu anda token ile aynı
|
||||
int size = 0; // Tanımlayıcı uzunluğu
|
||||
};
|
||||
#include "tokenizer/token.hpp"
|
||||
|
||||
// ============================================================================
|
||||
// Token Tanıma Tabloları (Derleme Zamanı Sabitleri)
|
||||
|
|
@ -265,7 +148,7 @@ inline constexpr std::string_view keywords[] = {
|
|||
// Literals
|
||||
"true", "false", "null",
|
||||
// OOP
|
||||
"class", "interface","enum", "extends", "implements",
|
||||
"class", "struct", "interface","enum", "extends", "implements",
|
||||
"new", "public", "private", "protected",
|
||||
"static", "final", "abstract",
|
||||
// Modules
|
||||
|
|
@ -361,8 +244,8 @@ inline Token* Tokenizer::scope() {
|
|||
hmx.skipWhiteSpace();
|
||||
|
||||
// Yorum satırları: sessizce atla, token üretme
|
||||
if (hmx.include("//", true)) skipOneLineComment();
|
||||
if (hmx.include("/*", true)) skipMultiLineComment();
|
||||
if (hmx.include("//", true)) { skipOneLineComment(); return scope(); }
|
||||
if (hmx.include("/*", true)) { skipMultiLineComment(); return scope(); }
|
||||
|
||||
// EOF kontrolü
|
||||
if (hmx.isEnd()) {
|
||||
|
|
@ -471,7 +354,7 @@ inline IdentifierToken* Tokenizer::readIdentifier() {
|
|||
if (read) {
|
||||
hmx.nextChar();
|
||||
} else {
|
||||
break; // Tanımlayıcı karakteri değil → dur
|
||||
if (it->token.empty()) { hmx.nextChar(); } break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue