Perché non ci sono traduttori automatici da un linguaggio di programmazione a un altro? [chiuso]


37

La maggior parte dei linguaggi di programmazione sono Turing completi, il che significa che qualsiasi attività che può essere risolta in una lingua può essere risolta in un'altra, o persino sulla macchina di Turing. Allora perché non ci sono traduttori automatici in grado di convertire i programmi da una determinata lingua in un'altra lingua? Ho visto tentativi di coppia per due lingue, ma funzionano sempre solo su un sottoinsieme limitato di una lingua e difficilmente possono essere utilizzati per convertire progetti reali.

È possibile, almeno in teoria, scrivere un traduttore corretto al 100% tra tutte le lingue? Quali sono le sfide in pratica? Ci sono traduttori esistenti che funzionano?


5
Ricorda, "tutte le lingue" include anche quelle stupide come Oook! (La completezza di Turing non è tutta la storia; in pratica hai bisogno anche delle tute.)
Donal Fellows

Ci sono alcuni. I traduttori da C a Pascal e Pascal a C erano abbastanza comuni ad un certo punto. Come suggeriscono le risposte di seguito, l'output di solito non era così leggibile senza almeno un riordino manuale. E questi sono linguaggi relativamente semplici con librerie relativamente semplici: fare bene il lavoro, ad esempio da C ++ a Haskell o viceversa, sarebbe probabilmente impossibile.
Steve314,

Dai un'occhiata al compilatore .net di Roslyn come servizio che ha la capacità di tradurre C # in VB e viceversa.
Daniel Little,

2
Tutti i compilatori traducono un PL in un altro, ma non garantiscono che il codice nel PL di destinazione sia di facile lettura
jk.

Dopo aver visto l'accuratezza della traduzione di Google, sono convinto che vedrò un traduttore universale nella mia vita. Sì, sarà uno sforzo impegnativo e potrebbe richiedere un enorme effetto come nel caso dell'analisi di basi di codice di grandi dimensioni come github o stackoverflow, ma questo accadrà e anche la domanda di tale strumento aumenterà nei prossimi anni, ora soprattutto che esiste un buon numero di programmatori per studiare AI e ML. Potrebbe non esserci una persona che sviluppa tale strumento da solo. Tuttavia, si potrebbe sviluppare un bot per sviluppare robot per affrontare questo problema.
Ganesh Kamath - 'Code Frenzy'

Risposte:


32

Il problema più grande non è la traduzione effettiva del codice del programma, ma il porting dell'API della piattaforma.

Prendi in considerazione un traduttore da PHP a Java. L'unico modo possibile per farlo senza incorporare parte del binario PHP è reimplementare tutti i moduli e le API di PHP in Java. Ciò comporta l'implementazione di oltre 10.000 funzioni. Rispetto a ciò il compito di tradurre effettivamente la sintassi è facile come una torta. E anche dopo tutto quel lavoro non avresti il ​​codice Java, avresti una sorta di mostruosità che sembra funzionare sulla piattaforma Java, ma che era strutturata come PHP all'interno.

Questo è il motivo per cui gli unici strumenti che vengono in mente riguardano la traduzione del codice per distribuirlo, non per mantenerlo in seguito. GWT di Google "compila" Java in JavaScript. L'hiphop di Facebook compila PHP in C.



Sembra che qualcuno abbia creato un traduttore PHP per Java e abbia effettivamente incorporato il binario PHP. D'accordo anche se non cambia il tuo punto. runtimeconverter.com/single-post/2017/09/15/…
user1122069

20

Se hai un formato intermedio, allora potresti implementare qualcosa che traduce un programma in Lingua X in quel formato, e anche da quel formato in Lingua Y. Implementa quelle conversioni per tutte le lingue che ti interessano e il gioco è fatto, giusto?

Bene sai una cosa? Tale formato esiste già: assembly. Il compilatore esegue già la conversione "Lingua da X a assembly" e disassemblatori alla conversione "Da assembly a Lingua Y".

Ora, assembly non è un linguaggio eccezionale per fare la conversione inversa, ma MSIL non è poi così male. Scarica Reflector e vedrai che ha le opzioni per disassemblare un assembly .NET in un sacco di lingue diverse (e i plugin ne forniscono ancora di più). Quindi è del tutto possibile prendere un programma in C #, compilarlo in una DLL (cioè MSIL), quindi usare il riflettore per disassemblarlo in VB, C ++ / CLI, F # e molti altri. Naturalmente, anche tutte le altre conversioni funzionano. Prendi un file F #, compila in una DLL, usa Reflector per convertirlo in C #.

Naturalmente, i due grandi problemi che troverai sono:

  1. Il codice è sostanzialmente illeggibile. MSIL (anche con informazioni di debug) rimuove molte informazioni dalla fonte originale, quindi la versione tradotta non ha fedeltà al 100% (teoricamente facendo una conversione C # -> MSIL-> C # dovrebbe restituirti il ​​codice originale, ma esso non lo faranno).
  2. Molti linguaggi .NET hanno le loro librerie personalizzate (ad esempio la libreria di runtime VB, la libreria F # e così via). Dovrebbero essere inclusi (o convertiti) anche quando esegui la conversione.

Non c'è davvero nulla da aggirare # 2, ma probabilmente potresti aggirare # 1 con alcune annotazioni aggiuntive nel MSIL (tramite attributi, forse). Sarebbe un lavoro aggiuntivo, ovviamente.


Molti dei metadati dalla fonte originale sono inclusi in MSIL (compresi i commenti XML e il metodo originale, proprietà e nomi dei membri), quindi non penso che la conversione in C # sia illeggibile come dici tu. Prova a smontare parti di .NET framework; è molto leggibile. Naturalmente, la situazione potrebbe essere diversa per una conversione da F # a C #.
Robert Harvey,

@Robert: i commenti XML non sono inclusi in MSIL. Se cerchi Microsoft.NET\Framework\v2.0.50727\enad esempio, puoi vedere tutta la documentazione XML per le librerie di sistema. Questo è ciò che Reflector (et al) usano per visualizzare i commenti. La conversione non è illeggibile, tutto quello che stavo dicendo è che non è la fedeltà al 100% che ci si potrebbe aspettare da una traduzione a livello di fonte.
Dean Harding,

2
Un disassemblatore converte il file binario eseguibile della macchina in assemblatore per quel particolare tipo di processore (Non tutto il mondo è un x86). Intendi davvero un decompilatore per riportare il codice compilato alla fonte. Questo è un compito orribilmente difficile poiché ogni compilatore, di ciascun produttore, ad ogni livello di ottimizzazione convertirà le linee di origine in una diversa forma binaria di output.
uɐɪ

20

È possibile, almeno in teoria, scrivere un traduttore corretto al 100% tra tutte le lingue? Quali sono le sfide in pratica?

  • La traduzione da una lingua più strutturata a una lingua meno strutturata che è ancora Turing completa, è sempre possibile.
    • Questa affermazione deve essere considerata in senso strettamente tecnico: significa che il programma tradotto produrrà esattamente lo stesso risultato quando viene eseguito.
    • Non è implicito nulla sulla leggibilità del codice tradotto o sulla conservazione delle strutture del programma originale.
  • È possibile tradurre da una lingua meno strutturata a una lingua più strutturata, ma il codice tradotto rimarrà nella sua forma meno strutturata.

1
Hai colpito il chiodo sulla testa. Prova a leggere il codice che esce dal backend C di LLVM. È tecnicamente legale codice C ma non è carino (TM).
dsimcha,

1
@dsimcha: leggibilità a parte il fatto che il backend C rende l'output molto più facile da leggere rispetto al debug o allo smontaggio. Sono così felice che abbiano riportato di nuovo quel backend, dopo che è rimasto fuori servizio per un breve periodo.
JM Becker,

10

Perché vorresti convertire un programma?

Entrambe le lingue, la sorgente e la lingua di destinazione sono comunque compilate in (virtual) machinecode *, quindi per motivi tecnici non è necessario disporre di un compilatore in un'altra lingua di alto livello.

Le lingue sono per l'uomo. Quindi, il requisito implicito della tua domanda è: "perché non esiste un traduttore che generi codice leggibile " , e la risposta sarebbe (imho): perché se ci sono due lingue sufficientemente diverse, i modi in cui è scritto il "codice leggibile" è diverso in un modo che non richiederebbe solo di tradurre gli algoritmi, ma prendere algoritmi diversi.

Ad esempio, confronta una tipica iterazione in C e una in lisp. O pitoni "un modo migliore" con rubino idiomatico.

Qui, iniziano a presentarsi gli stessi problemi che hai nelle lingue reali, come se traduci "Piove a catinelle" in qualcosa con il significato di "Sta riversando come se fosse dai secchi" quando traduci dall'inglese al tedesco, non puoi traduci più parola per parola, ma devi cercare il significato.

E "significato" non è un concetto facile su cui lavorare.

*) beh, c'è un coffeescript ...


1
Buona risposta. Si potrebbe aggiungere che se due lingue avessero esattamente lo stesso insieme di funzioni e modi di dire, sarebbe possibile tradurre una lingua in un'altra in modo abbastanza efficiente, ma la maggior parte delle lingue sono progettate allo scopo di supportare caratteristiche e modi di dire che i loro creatori ritengono non adeguatamente adeguati supportato in altre lingue . La traduzione meccanica del codice gestibile è talvolta praticabile quando le caratteristiche e gli idiomi nella lingua di destinazione sono un superset di quelli nella lingua di origine, ma tali situazioni non sono terribilmente comuni.
supercat

6

È teoricamente possibile ma per lo più inutile. È possibile quasi qualsiasi combinazione di lingue di origine e di destinazione, ma nella maggior parte dei casi nessuno vorrebbe mai guardare o utilizzare il risultato.

Un buon numero di compilatori si rivolge a C, semplicemente perché i compilatori C sono disponibili per quasi tutte le piattaforme esistenti (e ci sono generatori di compilatori automatici che ti permetteranno di progettare un processore e generare automaticamente un compilatore C che prende di mira il tuo nuovo processore). Esistono anche, ovviamente, un discreto numero di implementazioni destinate ai linguaggi utilizzati da varie macchine virtuali come .NET, JVM, C-- e LLVM.

Il punto chiave, tuttavia, è che è davvero utile solo se si tratta che il target è fondamentalmente un linguaggio assembly che viene utilizzato solo come passaggio nel processo di compilazione. In particolare, in genere non si desidera che un normale programmatore legga o lavori con quel risultato; di solito non sarà molto leggibile.


5

FWIW, c'è un traduttore da Java a D. Si chiama TioPort ed è stato usato in un tentativo abbastanza serio di portare SWT su D. Il problema principale in cui si è imbattuto è stato che sarebbe stato necessario eseguire il porting di enormi porzioni della libreria standard Java .


4

Sebbene non si tratti della traduzione del codice in sé, il concetto di banchi di lavoro linguistici mostra come implementare qualcosa di simile a un traduttore corretto al 100% tra tutte le lingue.

Nel nostro approccio attuale, il codice sorgente è memorizzato in un formato testuale. Durante la compilazione, questi file di testo leggibili dall'uomo vengono analizzati in una rappresentazione ad albero di sintassi astratta, che a sua volta viene utilizzata per generare bytecode o codice macchina. Questa rappresentazione astratta è tuttavia temporanea e interna al compilatore.

Nell'approccio del workbench del linguaggio, una rappresentazione ad albero di sintassi astratta simile è l'artefatto permanente e memorizzato. Sia il codice macchina che il codice testuale "sorgente" sono generati sulla base di questa rappresentazione astratta. Una delle conseguenze di un tale metodo è che la rappresentazione astratta del programma è in realtà indipendente dal linguaggio e può essere utilizzata per generare codice testuale in qualsiasi linguaggio implementato. Ciò significa che una persona può lavorare su diversi aspetti del sistema liberamente usando la lingua che ritengono più appropriata, oppure ogni membro del team può lavorare sul progetto condiviso nella lingua con cui ha più familiarità.

Per quanto ne so, la tecnologia è ancora lungi dall'essere utilizzabile nello sviluppo tradizionale, tuttavia ci sono diversi gruppi che ci lavorano indipendentemente. Difficile dire se qualcuno di loro manterrà le sue promesse, ma sarebbe interessante vederlo accadere.


Potresti nominare alcuni di questi gruppi?
Qwertie,

4

Ci sono alcuni traduttori automatici. Se il tuo obiettivo è produrre codice compilabile, piuttosto che un codice leggibile, è abbastanza possibile e occasionalmente utile, ma non molto spesso. È noto che il primo compilatore C ++ non era in realtà un compilatore, ma ha tradotto C ++ in sorgente C (davvero complicata) che è stata quindi compilata dal compilatore C. Molti compilatori possono generare codice assembly su richiesta, ma invece di sputare il testo assembly e poi tradurlo in codice macchina, normalmente possono generare direttamente il codice macchina.

Data una specifica completa del linguaggio A, in linea di principio non è così difficile scrivere un programma che esprima le sue direttive in qualche lingua B. Ma di solito chi va in difficoltà sceglierà qualcosa di veramente basso per "lingua B": codice macchina , o in questi giorni bytecode: Jython è un'implementazione di python che genera codice byte java, che viene interpretato dalla VM Java. Non c'è bisogno di preoccuparsi di scrivere e compilare gerarchie di classi Java!


3

Questo è fatto tutto il tempo.

Ogni compilatore traduce il "linguaggio primario", come C ++, nel linguaggio assembly nativo della macchina o nel bytecode indipendente dall'architettura nel caso dei linguaggi interpretati.

Immagino che non sia di questo che stai parlando. Probabilmente vuoi un traduttore che converta C ++ in qualcosa come Java o Python. Qual è il punto di ciò, però? Nella migliore delle ipotesi, il risultato finale avrà esattamente la stessa efficienza della fonte originale. (Praticamente, sarà molto peggio.)

Se vuoi semplicemente tradurre il codice in modo da poterlo leggere come una lingua che capisci, un traduttore del genere avrebbe l'opposto dell'effetto desiderato. Ti verrà lasciato un sacco di codice criptico, non intuitivo e illeggibile.

Questo perché solo le cose più banali si traducono direttamente da una lingua all'altra. Spesso, ciò che è semplice in una lingua richiede enormi librerie per un'altra - o potrebbe essere del tutto impossibile. Perciò:

  1. Se il programma è banale, potresti ottenere un risultato decente. Ma allora, se è così semplice, che senso ha farlo passare attraverso un traduttore?
  2. Se il programma non è banale, il codice sarà di bassa qualità.

Alla fine, l'unico modo per scrivere un buon codice è effettivamente scriverlo. I computer semplicemente non possono - almeno non ancora - abbinare gli esseri umani in materia di leggibilità, buone pratiche ed eleganti soluzioni.

In breve, non ne vale la pena.


la tua analogia si applicherebbe anche alla compilazione normale e sappiamo empiricamente di no! I computer "generano" (non scrivono) un codice di buona qualità. Ciò che spesso fanno male è leggibilità / manutenibilità. Se qualcuno aveva bisogno di un tale processo, il che a volte mi crede che le persone lo facciano, nessuno dei due problemi è un ostacolo allo spettacolo. Se lo sono, beh, ovviamente, la traduzione non è mai stata importante in origine.
JM Becker,

1

Non ci sono traduttori di lingue per linguaggi di programmazione perché i linguaggi di programmazione sono incredibilmente complessi. Mentre è ipoteticamente possibile, ci sono molte sfide.

La prima sfida è semplicemente nelle pratiche accettabili della lingua. La conversione tra due linguaggi orientati agli oggetti come Java e C ++ è incredibilmente complessa e sono entrambi basati su C. Il programma di traduzione dovrebbe avere una perfetta conoscenza delle librerie standard per entrambe le lingue ed essere in grado di conoscere le differenze di comportamento. Dovresti creare un dizionario enorme e anche in questo caso, le differenze negli stili di programmazione da programmatore a programmatore significherebbero che dovrebbe indovinare come eseguire alcune modifiche.

Dopo aver ridotto la traduzione della sintassi, devi capire come convertire un costrutto nella prima lingua in un costrutto nella seconda lingua. Questo va bene se stai andando un oggetto in C ++ a un oggetto in Java (relativamente facile che sia) ma cosa fai con le tue strutture C ++? O le funzioni al di fuori delle classi C ++? Decidere come gestirlo può essere difficile in quanto può comportare un altro problema, vale a dire la creazione di un oggetto BLOB. Il blob è un antipasto che è abbastanza comune.

Questo non è un elenco completo dei problemi, ma quelli sono solo due e sono grandi. Uno dei miei professori ha affermato che qualcuno ha convinto il suo datore di lavoro di poterne fare uno dal codice macchina alla C negli anni '80, ma allora non ha funzionato. Dubito che ce ne sarà mai uno che funzioni pienamente.


Penso che non sia necessario conoscere le librerie esistenti, può semplicemente tradurre le librerie mentre procede (supponendo che abbiano fonti disponibili).
serg

1
Ciò aumenta effettivamente la complessità del secondo problema. E questo presuppone che tu abbia accesso al codice sorgente per tradurlo. Ad ogni modo, è ancora piuttosto impossibile.
indyK1ng

Il punto +1 sulle librerie è totalmente valido e ci sono SEMPRE le librerie.
Dan Rosenstark,

1

Lo scopo della compilazione è ottenere qualcosa di utile per il computer. cioè qualcosa che può funzionare. Perché compilare in qualcosa che potrebbe anche essere di livello superiore a quello in cui l'hai scritto?

Mi piace meglio la strategia di .NET. Compila tutto in un linguaggio comune. Ciò offre il vantaggio delle lingue in grado di comunicare senza la necessità di creare compilatori (N ^ 2) -N cross-language.

Ad esempio, se avessi 10 linguaggi di programmazione, dovrai solo scrivere 10 compilatori con il modello .NET e tutti potrebbero comunicare tra loro. Se hai creato tutti i possibili compilatori in più lingue, dovrai scrivere 90 compilatori. Questo è un sacco di lavoro extra per pochi benefici.

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.