Esistono programmi in grado di "tradurre" il codice sorgente tra due lingue?


28

Esistono programmi in grado di "tradurre" il codice sorgente tra due lingue (supponendo che il traduttore abbia accesso alle librerie necessarie)?

In caso affermativo, come funzionano (tecniche utilizzate, conoscenze richieste, ecc.)? Come sarebbero fattibili?

In caso contrario, quali sono le restrizioni che impediscono il loro sviluppo? È un problema completo di intelligenza artificiale (la traduzione in lingua naturale è elencata come una sola)?

EDIT La conversione è prevista solo quando la lingua ha lo stesso potere espressivo, può risolvere lo stesso tipo di problemi e il codice da convertire può essere espresso nella lingua di destinazione. (Ad esempio, non è prevista la conversione da uno script di shell a MATLAB).



14
Cosa intendi con "due lingue"? Esistono sicuramente programmi che possono tradurre da una lingua all'altra. Si chiamano "compilatori". Questa è letteralmente la definizione di un compilatore: un programma che traduce i programmi da una lingua all'altra. Ma "due lingue qualsiasi"? Non penso sia possibile. Il traduttore deve conoscere sia la lingua di partenza che quella di destinazione e di solito è specifica per una particolare coppia di lingue.
Jörg W Mittag,

Al programma vengono fornite le lingue di origine e di destinazione. Sto pensando di scrivere un programma in C ++, tradurlo in Java, Python, Perl, Ruby, Go, ecc. Potrebbero esserci delle restrizioni (ad esempio, non mi aspetto che converta lo script della shell in MATLAB).
Tobi Alafin,

4
Sì, si chiamano compilatori, funzionano come compilatori e possono essere costruiti come compilatori.
user253751

1
Se per "due lingue qualsiasi" intendi letteralmente che il programma (finito) dovrebbe essere in grado di leggere e comprendere un numero infinito di lingue di input, la risposta è banalmente no . Tuttavia, prendi un set finito di lingue di input e puoi trovare un compilatore per tutte quelle lingue ..
Bakuriu,

Risposte:


57

TLDR; questo è possibile ma non pratico.

(supponendo che il traduttore abbia accesso alle librerie necessarie)?

Questo finisce per essere un po 'complicato, ed è parte del motivo per cui cose come questa non finiscono per essere utilizzate nella pratica.

  1. Tutti i compilatori sono traduttori. La traduzione da una lingua all'altra è sicuramente possibile, e questo è letteralmente tutto ciò che un compilatore sta facendo. Il linguaggio che un compilatore sputa come output è generalmente codice macchina o assembly, ma questa è solo un'altra lingua e ci sono compilatori (a volte chiamati transpiler o transcompiler) che traducono tra due lingue . Ad esempio, esiste una gamma di linguaggi di compilazione in Javascript come PureScript, Elm, ClojureScript, ecc.

  2. La traduzione tra due lingue Turing complete è sempre possibile. Ignorare cose come chiamate in biblioteca e FFI e altre brutte cose pratiche che si frappongono, cioè. Se una lingua è Turing Complete, allora hai:

    • Una traduzione che converte una Turing Machine in codice in questa lingua
    • Una traduzione da questa lingua in una macchina di Turing

    Quindi, per tradurre dalla lingua A alla lingua B, converti il ​​codice A in una macchina di Turing, quindi converti quella macchina in codice B.

    Ovviamente, in pratica, i bit pratici si frappongono e ciò richiede anche che le traduzioni siano accessibili a te. Esistono praticamente per tutte le lingue, ma ciò non significa che qualcuno abbia avuto il tempo di scriverle.

  3. Fare questa traduzione in modo efficiente è difficile . Lingue diverse danno priorità a cose diverse. Ad esempio, se traduci da C a Python, probabilmente dovrai finire per simulare la memoria di C come dizionario Python, in modo da poter eseguire l'aritmetica del puntatore. Ci sarà un sovraccarico associato a questo, perché ora non stai accedendo alle istruzioni di memoria bare metal.

    Lingue diverse hanno priorità di prestazione diverse, quindi qualcosa che una lingua ottimizza (o meglio, un'implementazione di una lingua ottimizza) potrebbe essere impossibile da eseguire rapidamente in un'altra lingua. La traduzione di una lingua funzionale con le chiamate di coda appropriate avrà un rallentamento se la traduci in una lingua senza chiamate di coda adeguate.

  4. Fare questa traduzione non rende il codice leggibile . È facile ottenere un pezzo di codice nella lingua B che si comporta come il codice dalla lingua A. È difficile far sembrare il codice che un essere umano avrebbe scritto in B, per una serie di ragioni. A e B potrebbero avere diversi strumenti di astrazione e il computer non ha idea di cosa renda il codice leggibile. Ciò sarà particolarmente vero se finirai per usare la traduzione di Turing Machine che ho descritto in precedenza.

    Ciò solleva la domanda: qual è il punto di tale traduzione? Se alla fine otteniamo un blocco di codice lento e illeggibile, perché non compilarlo semplicemente in codice macchina e usare una sorta di FFI o comunicazione tra processi per collegare i pezzi?

    Ci sono alcune eccezioni a questo. A volte hai bisogno di cose in una certa lingua (come JavaScript). A volte la lingua è simile e una traduzione ragionevole è facile. A volte una lingua non è pensata per essere eseguita, ma per avere il suo codice estratto in un'altra lingua (come Coq).

    Ma in generale, non è una cosa molto pratica.


5
Un esempio per il punto 4 è asm.js . Oggi, è possibile renderlo sorta leggibile, utilizzando mappe sorgente JavaScript e l'ispettore Element, ma nessuno vorrà farlo ...
Ismael Miguel

1
Modelica è un altro esempio di un linguaggio progettato per la compilazione in un'altra lingua (in questo caso C).
Ripristina Monica il

Webassembly che traduce da C ++ a javascript.
Surt,

Esistono numerosi esempi di transpiler da X a Y, ma questo è diverso da un compilatore universale di qualsiasi cosa. Ci sono ovviamente casi in cui la trasplicazione ha senso.
jmite,

Un'eccezione importante che manca all'IMO: compilare in C. Il motivo è che molti sistemi non comuni hanno un compilatore C esistente, che generalmente può emettere un codice macchina abbastanza ragionevole. Quindi, compilando un linguaggio in C, non è necessario avere backend per quelle rare architetture.
Salterio

2

Esistono tali programmi. Ad esempio i traduttori da Lisp a Fortran, che erano ampiamente utilizzati al loro tempo. I compilatori Sole Lisp non compilano direttamente Lisp, ma generano codice C che viene quindi compilato da un normale compilatore C. Un altro esempio potrebbe essere la Vala che non viene compilata direttamente ma prima tradotta in C ++ prima della compilazione del codice C ++. Qt è scritto in MOC, un linguaggio che viene tradotto in C ++ per compilarlo (ma dato che MOC è solo C ++ con alcuni comandi aggiuntivi si può discutere se deve davvero essere chiamato un "nuovo linguaggio") - e prima c'erano compilatori C ++ c'erano traduttori C ++ - to-C. E alcuni progetti sono stati scritti in Pascal e poi tradotti in C. Anche clang e Java tendono ad essere una specie di cosa in quanto traducono il codice C ++ e Java in un linguaggio intermedio che può quindi essere ulteriormente elaborato.

Quello che non puoi aspettarti dall'output di un traduttore di lingua è che il risultato ha senso per un lettore umano: il compito del programma è quello di scrivere codice che dia come risultato un programma che fa lo stesso del codice originale (che nella mia esperienza potrebbe o potrebbe non funziona, a seconda delle funzionalità della lingua e delle librerie esterne che si stavano utilizzando). Ma poiché non conosce lo scopo, questo compito per il resto del significato del programma potrebbe essere perso in larga misura.


0

Non è una risposta diretta, ma è presente uno strumento chiamato ILSpy , che è stato scritto per il .Net Framework e consente di decompilare un assembly .Net in C # o VB.Net.

Se non hai familiarità con la natura di .Net, puoi scrivere il codice .Net in molte lingue ma principalmente C # o VB.Net. Quando il compilatore compila l'applicazione, traduce il codice in un codice "Intermediate Language" (o IL in breve). Questo codice viene quindi compilato in binari .Net.

Poiché le applicazioni .Net sono binarie compilate dal codice IL, ILSpy può prendere l'applicazione .Net, invertirla in codice IL e, successivamente, fare un passo ulteriore e invertirla in C # o VB.Net.

Usando questo strumento, tutto ciò che devi fare è compilare un'applicazione, quindi puoi sfogliare i file compilati come codice IL, C # o VB.Net. Per essere chiari, non importa in quale lingua è stato inizialmente scritto il codice. Fintanto che il binario è un assembly .Net, può decodificare i file compilati e produrre il contenuto in una di queste tre lingue.

So che questo non è esattamente un compilatore, ma è uno strumento che offre un risultato finale simile a quello che stai cercando e, in effetti, l'ho usato per "tradurre" i progetti VB.Net in qualcosa di un po ' più familiare per me-- C #.


0

Per il tuo caso d'uso (basato sui commenti), sembra che SWIG possa essere utile.

SWIG è uno strumento di sviluppo software che collega i programmi scritti in C e C ++ con una varietà di linguaggi di programmazione di alto livello. SWIG viene utilizzato con diversi tipi di lingue di destinazione, inclusi linguaggi di scripting comuni come Javascript, Perl, PHP, Python, Tcl e Ruby. L'elenco delle lingue supportate include anche linguaggi non di scripting come C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go language, Java compreso Android, Lua, Modula-3, OCAML, Octave, Scilab e R Sono inoltre supportate diverse implementazioni dello schema interpretate e compilate (Guile, MzScheme / Racket, Chicken).


0

Ricordo il venerabile f2c , che traduce da fonte a fonte da Fortran 77 a C.

È stato (a volte è ...) utilizzato principalmente per tradurre il codice numerico di decenni fa senza dover integrare un compilatore fortran nella tua toolchain.


0

Il pezzo di teoria che ti dice che tali programmi esistono, in linea di principio, si chiama numerazioni ammissibili . Possiamo provare che ci sono compilatori calcolabili tra due di queste numerazioni, e ogni formalismo (o linguaggio di programmazione) completo di Turing è, in sostanza, uno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.