feat(symbols): JSON çıktı + syntax hata toleransı
- symbols komutu artık JSON üretiyor: file, symbols[], diagnostics Her sembol: name, kind, type, typeDetail, definition (file+satır+sütun), references[], isBuiltin — LSP tüketimine hazır format - parser: parseProgram() ilerleme olmayana token atla (guard ekle) Bozuk top-level syntax (ör: `}`, eksik parametre listesi) artık ayrıştırmayı durdurmak yerine sonraki geçerli bildirimi bulmaya devam eder
This commit is contained in:
parent
73249c640a
commit
79d8618f03
Binary file not shown.
|
|
@ -15,3 +15,6 @@
|
|||
0 22 1781786586571540360 build.ninja 1876a59d627a585
|
||||
0 22 1781786586571540360 /home/saqut/Masaüstü/saqutcompiler/build/cmake_install.cmake 1876a59d627a585
|
||||
1 2086 1781786305407208932 CMakeFiles/saqut.dir/src/symbol/symbol_collector.cpp.o 3348f498f369213d
|
||||
10 1265 1781788264862998611 CMakeFiles/saqut.dir/src/parser/parser.cpp.o 2c65b7be26cead32
|
||||
10 2216 1781788264862423222 CMakeFiles/saqut.dir/src/main.cpp.o 110c26cb1d0c3a23
|
||||
2216 2383 1781788267068424572 saqut 8525928b86934b0a
|
||||
|
|
|
|||
|
|
@ -1,30 +1,93 @@
|
|||
// ============================================================================
|
||||
// saQut CLI — symbols komutu (sembol tablosu — Faz 2)
|
||||
// saQut CLI — symbols komutu (sembol tablosu — JSON çıktı, Faz 2)
|
||||
// ============================================================================
|
||||
|
||||
#ifndef SAQUT_CLI_SYMBOLS
|
||||
#define SAQUT_CLI_SYMBOLS
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "cli/args.hpp"
|
||||
#include "tokenizer/tokenizer.hpp"
|
||||
#include "parser/parser.hpp"
|
||||
#include "symbol/symbol_table.hpp"
|
||||
#include "symbol/symbol_collector.hpp"
|
||||
#include "diagnostic/diagnostic_engine.hpp"
|
||||
#include "tools.hpp"
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// symbolsToJson — sembol tablosunu JSON olarak serileştir
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
inline std::string symbolsToJson(const std::string& filePath,
|
||||
const SymbolTable& table,
|
||||
const DiagnosticEngine& diag) {
|
||||
auto symbols = table.allSymbols();
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "{\n";
|
||||
ss << " \"file\": \"" << jsonEscape(filePath) << "\",\n";
|
||||
ss << " \"symbols\": [";
|
||||
|
||||
bool firstSym = true;
|
||||
for (Symbol* s : symbols) {
|
||||
if (s->isBuiltin) continue;
|
||||
|
||||
if (!firstSym) ss << ",";
|
||||
firstSym = false;
|
||||
|
||||
ss << "\n {\n";
|
||||
ss << " \"name\": \"" << jsonEscape(s->name) << "\",\n";
|
||||
ss << " \"kind\": \"" << symbolKindName(s->kind) << "\",\n";
|
||||
ss << " \"type\": \"" << jsonEscape(s->type.toString()) << "\",\n";
|
||||
ss << " \"typeDetail\": " << s->type.toJson() << ",\n";
|
||||
ss << " \"definition\": " << s->definitionLoc.toJson() << ",\n";
|
||||
ss << " \"isBuiltin\": " << (s->isBuiltin ? "true" : "false") << ",\n";
|
||||
|
||||
// referanslar
|
||||
ss << " \"references\": [";
|
||||
bool firstRef = true;
|
||||
for (const SourceLocation& ref : s->references) {
|
||||
if (!firstRef) ss << ", ";
|
||||
firstRef = false;
|
||||
ss << ref.toJson();
|
||||
}
|
||||
ss << "]\n";
|
||||
|
||||
ss << " }";
|
||||
}
|
||||
|
||||
if (!firstSym) ss << "\n ";
|
||||
ss << "],\n";
|
||||
|
||||
// tanılar (diagnostic engine'den hazır JSON al, iç kısmını sar)
|
||||
ss << " \"diagnostics\": " << diag.toJson() << "\n";
|
||||
ss << "}\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// cmdSymbols — giriş noktası
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
inline int cmdSymbols(const CliArgs& args) {
|
||||
std::string source = readSource(args);
|
||||
std::string filePath = inputFilePath(args);
|
||||
std::string source = readSource(args);
|
||||
if (source.empty()) return 1;
|
||||
|
||||
Tokenizer tokenizer;
|
||||
auto tokens = tokenizer.scan(source, inputFilePath(args));
|
||||
auto tokens = tokenizer.scan(source, filePath);
|
||||
|
||||
Parser parser;
|
||||
ASTNode* ast = parser.parse(tokens);
|
||||
|
||||
if (!ast) {
|
||||
std::cerr << "Hata: AST üretilemedi\n";
|
||||
// AST null olursa boş ama geçerli bir JSON çıktısı üret
|
||||
DiagnosticEngine diag;
|
||||
diag.report("E000", SourceLocation{}, "AST üretilemedi");
|
||||
SymbolTable empty;
|
||||
std::cout << symbolsToJson(filePath, empty, diag);
|
||||
for (auto* t : tokens) delete t;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -33,32 +96,7 @@ inline int cmdSymbols(const CliArgs& args) {
|
|||
DiagnosticEngine diag;
|
||||
SymbolCollector(table, diag).collect(ast);
|
||||
|
||||
auto symbols = table.allSymbols();
|
||||
|
||||
std::cout << "Sembol Tablosu (" << symbols.size() << " sembol):\n";
|
||||
std::cout << "────────────────────────────────────────────\n";
|
||||
|
||||
if (symbols.empty()) {
|
||||
std::cout << " (sembol bulunamadı)\n";
|
||||
}
|
||||
|
||||
for (Symbol* s : symbols) {
|
||||
if (s->isBuiltin) continue; // builtinleri çıktıda gösterme
|
||||
std::cout << " [" << symbolKindName(s->kind) << "] "
|
||||
<< s->type.toString() << " " << s->name
|
||||
<< " @" << s->definitionLoc.shortString()
|
||||
<< " refs(" << s->references.size() << "):";
|
||||
for (auto& r : s->references)
|
||||
std::cout << " " << r.shortString();
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
std::cout << "────────────────────────────────────────────\n";
|
||||
|
||||
if (diag.hasErrors()) {
|
||||
std::cerr << "\n";
|
||||
diag.printAll(std::cerr);
|
||||
}
|
||||
std::cout << symbolsToJson(filePath, table, diag);
|
||||
|
||||
delete ast;
|
||||
for (auto* t : tokens) delete t;
|
||||
|
|
|
|||
|
|
@ -63,11 +63,13 @@ ASTNode* Parser::parseProgram() {
|
|||
ProgramNode* program = new ProgramNode();
|
||||
|
||||
while (currentToken().type != TokenType::SVR_VOID) {
|
||||
int prevPos = current;
|
||||
ASTNode* decl = parseDeclaration();
|
||||
if (decl)
|
||||
program->addChild(decl);
|
||||
else
|
||||
break;
|
||||
// İlerleme olmadıysa token atla — syntax hatasında sonsuz döngüyü önler
|
||||
if (current == prevPos)
|
||||
nextToken();
|
||||
}
|
||||
|
||||
return program;
|
||||
|
|
|
|||
Loading…
Reference in New Issue