È possibile convertire automaticamente il codice da un linguaggio di basso livello ad un linguaggio di alto livello?

5

Ho visto diverse applicazioni che pretendono di convertire il codice Java in C o anche C ++ validi. La conversione da un linguaggio di alto livello ad un linguaggio di basso livello è possibile, non c'è dubbio. Almeno in teoria, si può fare il contrario senza nessuna procedura manuale?

Ad esempio:

  • Conversione di assembly in C o codice macchina in Assembly?

  • Hardware Description Languages (HDL) to Assembly? (che mai è più basso?)

  • da C a C #?

posta AceofSpades 13.01.2012 - 17:26
fonte

4 risposte

9

Sebbene sia possibile, è probabile che il compilatore "lifting" finisca per generare codice la cui struttura emula il modello di programmazione del linguaggio di livello inferiore. Così, finirai con "COBOL in Haskell" o "ASM in Java" o cosa-hai-te, e sarà più complesso e meno efficiente della tua lingua di livello inferiore.

Ad esempio, se il linguaggio di livello inferiore ha una gestione esplicita della memoria e il tuo linguaggio di livello superiore no, non puoi semplicemente buttare via free s - forse il comportamento del programma sottostante dipende dal determinismo. Dovresti quindi modellare, nel tuo linguaggio di alto livello, il modello di memoria del linguaggio di basso livello (yuck). Allo stesso modo, se il linguaggio di livello inferiore ha goti arbitrari a la JMP dovresti generare un codice di alto livello in cui tali goto potrebbero essere eseguiti (limiti di funzione arbitrari).

Il motivo per cui i decompilatori non affrontano questo problema è che non stanno realmente lavorando con le funzionalità complete del codice macchina sottostante, a meno che non siano su una VM che è strettamente collegata al modello di programmazione di una lingua.

    
risposta data 13.01.2012 - 18:30
fonte
3

In teoria è possibile scrivere un compilatore da qualsiasi lingua completa di Turing in qualsiasi altra lingua completa di Turing.

In pratica, passare da una lingua di livello inferiore ad uno di livello superiore sarà altamente problematico, poiché si sta andando verso una più alta astrazione e che di solito richiede l'essere umani. Pensa a come non esiste un approccio "corretto" nell'orientamento agli oggetti ...

Per linguaggi di livello simile, è un po 'più facile, checkout code2code che traduce il codice C ++ traduce C # & VB.NET. E poiché un codice C ++ è un codice C valido, puoi dire che traduce anche C in C #, in una certa estensione.

    
risposta data 13.01.2012 - 17:52
fonte
3

C'è una differenza importante tra la conversione in un linguaggio di alto livello da qualcosa che è stato scritto manualmente rispetto a qualcosa che è stato generato automaticamente.

Nel primo caso, c'è poco, se non altro, nella direzione della traduzione inversa, quindi il tuo traduttore sarà "scrivere programmi Fortran in (qualche altro) linguaggio" .

Il secondo caso è diverso, tuttavia: i compilatori lasciano abbastanza "segni" per rendere possibile la traduzione inversa. Ad esempio, puoi esaminare il codice binario generato da C ++ e capire un sacco di cose sulle classi da cui è stato generato il codice:

  • Puoi imparare il layout dei campi in una classe esaminando il codice che accede a una classe
  • Puoi trovare le funzioni virtuali della classe esaminando i vtables
  • Puoi trovare le funzioni dei membri rimuovendo i nomi dai file .o
  • Puoi fare ipotesi plausibili sulle costanti definite in una classe
  • Puoi tradurre le espressioni in un formato leggibile dall'uomo, magari con un numero minore o maggiore di serie di parentesi
  • È possibile rilevare gli usi dei contenitori STL comuni espansi dai modelli

Certo, il risultato non sarà mai identico all'origine originale, perché cose belle come commenti e nomi di variabili locali sono irrimediabilmente persi. Ma otterresti sicuramente qualcosa di meglio di un pezzo di assemblaggio scritto usando la sintassi C ++.

    
risposta data 13.01.2012 - 20:02
fonte
0

Non molto. Tradurre da una lingua di livello superiore ad una lingua di livello inferiore significa re-implementare tutte le caratteristiche linguistiche di livello superiore usando solo quelle funzioni disponibili nella lingua di livello inferiore. Questo è fondamentalmente ciò che fa un compilatore. Per esempio. una riga potrebbe diventare molte, molte istruzioni di linguaggio assembly.

Se stai traducendo da una lingua di livello inferiore a una lingua di livello superiore, puoi (a) implementare esattamente lo stesso programma nella lingua di livello superiore, ad es. tradurre un programma di linguaggio macchina compilato in una sequenza di comandi python per "registri di modello che usano queste variabili, caricare questo valore in questo registro, aggiungere questi registri, memorizzare questo valore, saltare alla riga xxx" ecc. ecc. che è piuttosto inutile. (Per esempio, quasi tutti i programmi C sono già programmi C ++ validi, o quasi, semplicemente senza usare nessuna delle funzionalità che rendono utile l'uso di C ++).

Oppure (b) prova a indovinare quali caratteristiche della lingua originale sono state tradotte nella lingua di livello inferiore. Se il linguaggio di livello inferiore è stato originariamente compilato, questo può avere un certo successo: il decompilatore cerca i tipi di compilatori di codice che di solito generano e indovina quale potrebbe essere stato il codice originale. Un esempio scelto da google: link .

Tuttavia, ciò si applica solo se è stato originariamente compilato da quel linguaggio di livello superiore usando un compilatore conosciuto in primo luogo (o scritto a mano usando molti idiomi che hanno caratteristiche linguistiche corrispondenti).

Se hai una pila di codice C e vuoi convertirla in codice C ++, devi prendere decisioni di valore su quali bit del codice saranno estensibili, quali funzioni dovrebbero essere raggruppate in classi, come evitare lo stato globale ecc. ecc., che è ciò che fanno i programmatori e non possono essere immediatamente automatizzati.

    
risposta data 13.01.2012 - 18:28
fonte

Leggi altre domande sui tag