Pass 2Status: ✅ Vollständig implementiert

ParserPass - Parsing & Modul-Auflösung

Das Herzstück der Syntax-Analyse: Transformiert Quellcode in einen Abstract Syntax Tree (AST) und löst rekursiv alle Modul-Abhängigkeiten auf.

compiler/src/passes/parser.rs

Übersicht

Der ParserPass ist der zweite Pass im VelinScript Compiler (nach AutoFixPass). Er übernimmt die kritische Aufgabe, aus flachem Quelltext eine strukturierte Baumdarstellung zu erzeugen und das gesamte Projekt-Umfeld zu erfassen.

1

Lexikalische Analyse

Tokenisierung des Source-Codes

2

Syntax-Analyse

Erstellung des Abstract Syntax Tree (AST)

3

Modul-Auflösung

Rekursive Auflösung von use Statements

4

AST-Merging

Zusammenführung aller Module in einen globalen AST

Modul-Auflösung (Import Resolution)

Der Pass löst alle use Statements rekursiv auf und integriert sie nahtlos in den globalen Kontext.

Implementierungs-Details

// Modul-Pfad finden
let module_path = base_path.join(format!("{}.velin", first_segment));

// Rekursive Auflösung & Zyklus-Erkennung
if visited_modules.contains(&mod_path_str) {
    continue;  // Modul bereits geladen
}
visited_modules.insert(mod_path_str.clone());

Sicherheitsfeatures

Path-Traversal-Schutz

Verhindert Angriffe wie use ../parent oder absolute Pfade. Nur relative Pfade innerhalb des Projekts sind erlaubt.

Modulname-Validierung

Nur alphanumerische Zeichen, Unterstriche und Bindestriche sind zulässig. Sonderzeichen wie @ oder . werden blockiert.

Datenstrukturen

Der resultierende AST besteht aus verschiedenen Items, wobei importierte Module speziell gewrappt werden, um Namespacing zu ermöglichen.

Item::Module(Module {
    name: "models",           // Modulname
    items: [...],             // Alle Items aus models.velin
    visibility: Public,
    documentation: None,
})
Vorteil: Ermöglicht Namespacing wie models.User direkt im Code.

Fehlerbehandlung

Wenn der ParserPass fehlschlägt (z.B. Root-Modul nicht lesbar), stoppt der Compiler sofort. Fehler in Untermodulen werden gesammelt, um einen umfassenden Report zu generieren.

if context.has_errors() {
    if pass.name() == "Parser" {
        break;  // Kritischer Fehler: Stoppe Compiler
    }
}