Questo è un compito abbastanza grande. Ma poi di nuovo, anche la maggior parte delle cose vale la pena fare in programmazione. Iniziamo suddividendoli in compiti sempre più piccoli finché non li riduciamo al livello di un problema che sappiamo come risolvere.
Hai ragione nel fatto che il tuo compito generale è un compilatore fonte-sorgente e che devi iniziare con un parser. Sfortunatamente, C (e per estensione qualsiasi superset della lingua, come Objective-C) è difficile da analizzare. Dal vocabolario che stai utilizzando, potresti già conoscere alcune cose sulla teoria dell'analisi e sulla gerarchia di Chomsky . In caso contrario, leggere su di esso. Definisce quattro livelli di complessità del linguaggio da 0 (molto difficile da analizzare) a 3 (molto facile da analizzare). I linguaggi di programmazione più moderni sono di livello 2, lingue senza contesto , perché è difficile creare un linguaggio utile senza una grammatica ricorsiva, che è ciò che differenzia il livello 2 dal livello 3. C e Objective-C sono il livello 1, lingue sensibili al contesto , a causa del modo in cui funzionano typedef: la stessa stringa di codice può analizzare in due modi diversi, con due significati diversi, a seconda che il simbolo che sta leggendo sia o meno un tipo. Ciò rende la creazione di un parser appropriato per loro molto più difficile. Fino a quando non avrai molta esperienza con il lavoro del compilatore, sarebbe meglio trovare un parser esistente piuttosto che provare a crearne uno tuo.
Una volta che hai un parser, molto lavoro è fatto, ma c'è ancora un sacco di sfide interessanti per te. È possibile eseguire il parser sul codice Objective-C e ottenere un Abstract Syntax Tree (AST). Si spera che si abbia una buona conoscenza degli alberi e della ricorsione, perché il lavoro del compilatore li usa ovunque . Non sto scherzando.
Una volta che hai il tuo AST, il passo successivo è analisi semantica. Questo è un modo formale per dire "prendi questo AST e capisci quale sia il suo significato". Esattamente come si esegue l'analisi semantica dipende molto dalle specifiche di come funziona il tuo AST e da cosa stai cercando di fare. In questo caso specifico, quello che stai cercando di determinare è la semantica corretta per il codice in questione per essere mappabile alla semantica Swift. (Questo, ovviamente, richiede una profonda conoscenza di come funzionano sia Swift che Objective-C.) La tua analisi semantica dovrebbe produrre un nuovo AST o annotare l'AST dal parser in qualche modo, e quando hai finito, tu avere un albero semantico.
La fase finale è la generazione del codice. Qui è dove si cammina l'albero semantico, si ispeziona la semantica dell'albero e si produce codice nella lingua di destinazione.
Sul lato Swift, ci sono alcune buone notizie e alcune cattive notizie. La buona notizia è che Apple ha aperto la lingua Swift, quindi puoi prendere in prestito il loro AST ufficiale , inclusa una classe chiamata ASTPrinter
che sembra prendere un AST rapido e generare codice Swift da esso. (Ciò significa che la fase di analisi semantica può trasformare il tuo AST Objective-C in un AST Swift equivalente e la fase di generazione del codice è già gestita.) Le cattive notizie, se vuoi seguire questa strada, è il codice di Apple è in C ++, che è un linguaggio davvero orribile in cui lavorare. Ma per lo meno, puoi usare il loro codice AST per l'ispirazione.
Comunque, questa è una panoramica di alto livello su come scrivere un compilatore source-to-source. Non ho inserito troppi dettagli, perché i dettagli variano molto a seconda delle specifiche di ciò che stai facendo, ma spero che sia utile, almeno per darti un'idea di cosa devi fare.