it-swarm.it

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

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 anche 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?

37
serg

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

Considera un PHP in Java. L'unico modo fattibile per farlo senza incorporare parte del binario PHP è reimplementa tutti i moduli e le API di PHP in Java. Ciò comporta l'implementazione di oltre 10.000 funzioni. Rispetto a ciò il lavoro di traduzione della sintassi è facile come una torta. E anche dopo tutto quel lavoro non avresti Java codice, 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.

32
Joeri Sebrechts

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

Bene sai una cosa? Tale formato esiste già: Assemblea. Il compilatore esegue già la conversione "Lingua da X a Assembly" e disassemblatori alla conversione "Da Lingua a 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 è abbastanza possibile prendere un programma in C #, compilarlo in un DLL (cioè MSIL), quindi usare il riflettore per smontarlo in VB, C++/CLI, F # e un intero raggruppare 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 es. VB, libreria F # e così via). Dovrebbero essere inclusi (o convertiti) quando si esegue anche 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.

20
Dean Harding

È 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.
    • Nulla è implicito nella leggibilità del codice tradotto o nella 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.
20
rwong

Perché dovresti voler convertire un programma?

Entrambe le lingue, la sorgente e la lingua di destinazione sono comunque compilate in machinecode (virtuale) *, 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 c'è un traduttore che generi codice leggibile ', e la risposta sarebbe (imho): perché se ci sono due lingue sufficientemente diverse, le modalità di scrittura del "codice leggibile" sono diverse in un modo che non richiederebbe solo di tradurre gli algoritmi, ma prendere algoritmi diversi.

Ad esempio, confrontare una tipica iterazione in C e una in LISP. O i pitoni "un modo migliore" con Ruby idiomatico.

Qui, gli stessi problemi iniziano a manifestarsi nelle lingue reali, come se traducessi "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'è coffeescript ...

10
keppla

È 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 discreto 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 destinato al 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 l'obiettivo è fondamentalmente un linguaggio Assembly che viene utilizzato solo come passaggio nel processo di compilazione. In particolare, generalmente non volete che un normale programmatore legga o lavori con quel risultato; di solito non sarà molto leggibile.

6
Jerry Coffin

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 che ha riscontrato era che sarebbe stato necessario eseguire il porting di enormi porzioni della libreria standard Java.

5
dsimcha

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 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.

4
scrwtp

Ci sono 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 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 Java codice byte, che viene interpretato dal Java = VM. Non c'è bisogno di preoccuparsi di scrivere e compilare Java gerarchie di classi!

4
alexis

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 di linguaggi interpretati.

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

Se vuoi solo che il codice venga tradotto 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 è in realtà scriverlo. I computer semplicemente non possono - almeno non ancora - abbinare gli umani in materia di leggibilità, buone pratiche ed eleganti soluzioni.

In breve, non ne vale la pena.

3
Maxpm

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 antipattern 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.

1
indyK1ng

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 che le lingue sono 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.

1
mike30