Existe-t-il des programmes qui peuvent «traduire» le code source entre deux langues quelconques?

28

Existe-t-il des programmes qui peuvent «traduire» le code source entre deux langues quelconques (en supposant que le traducteur a accès aux bibliothèques requises)?

Si oui, comment fonctionnent-elles (techniques utilisées, connaissances requises, etc.)? Comment seraient-ils réalisables?

S'ils ne le sont pas, quelles sont les restrictions qui empêchent leur développement? Est-ce un problème complet d'IA (la traduction en langage naturel est répertoriée comme une seule)?

EDIT La conversion n'est attendue que lorsque la langue a la même puissance d'expression, elle peut résoudre le même type de problèmes et le code à convertir peut être exprimé dans la langue de destination. (Par exemple, la conversion d'un script shell en MATLAB n'est pas attendue).

Tobi Alafin
la source
14
Qu'entendez-vous par «deux langues quelconques»? Il existe certainement des programmes qui peuvent traduire d'une langue à une autre. Ils sont appelés "compilateurs". C'est littéralement la définition d'un compilateur: un programme qui traduit des programmes d'une langue à une autre. Mais "deux langues"? Je ne pense pas que ce soit possible. Le traducteur doit connaître à la fois la langue source et la langue cible, et elle est généralement spécifique à une paire de langues particulière.
Jörg W Mittag
Le programme est fourni les langues source et cible. Je pense à écrire un programme en C ++, à le traduire en Java, python, Perl, Ruby, Go, etc. Il peut y avoir quelques restrictions (je ne m'attends pas à ce qu'il convertisse votre script shell en MATLAB par exemple).
Tobi Alafin
4
Oui, ils s'appellent des compilateurs, ils fonctionnent comme des compilateurs et ils peuvent être construits comme des compilateurs.
user253751
1
Si par "deux langues quelconques" vous entendez littéralement que le programme (fini) devrait être capable de lire et de comprendre un nombre infini de langues d'entrée, la réponse est trivialement non . Cependant, prenez un ensemble fini de langues d'entrée et vous pouvez trouver un compilateur pour toutes ces langues ..
Bakuriu

Réponses:

57

TLDR; c'est possible mais pas pratique.

(en supposant que le traducteur ait accès aux bibliothèques requises)?

Cela finit par être la partie la plus délicate et explique pourquoi des choses comme celle-ci ne finissent pas par être utilisées dans la pratique.

  1. Tous les compilateurs sont des traducteurs. Traduire d'une langue à une autre est certainement possible, et c'est littéralement tout ce qu'un compilateur fait. Le langage qu'un compilateur crache en sortie est généralement du code machine ou de l'assembly, mais ce n'est qu'un autre langage, et il existe des compilateurs (parfois appelés transpilers ou transcompilers) qui traduisent entre deux langages . Par exemple, il existe une gamme de langages de compilation en Javascript comme PureScript, Elm, ClojureScript, etc.

  2. La traduction entre deux langues Turing Complete est toujours possible. Ignorer des choses comme les appels de bibliothèque et FFI et d'autres éléments pratiques désagréables qui gênent, c'est-à-dire. Si une langue est Turing Complete, vous avez:

    • Une traduction qui convertit une machine de Turing en code dans cette langue
    • Une traduction de cette langue dans une machine de Turing

    Donc, pour traduire de la langue A vers la langue B, vous convertissez le code A en une machine de Turing, puis convertissez cette machine en code B.

    Bien sûr, dans la pratique, les éléments pratiques gênent, et cela nécessite également que vous ayez les traductions à votre disposition. Ils existent pour pratiquement toutes les langues, mais cela ne signifie pas que quelqu'un a pris le temps de les écrire.

  3. Faire cette traduction efficacement est difficile . Différentes langues donnent la priorité à différentes choses. Par exemple, si vous traduisez de C en Python, vous allez probablement devoir finir par simuler la mémoire de C en tant que dictionnaire Python, afin de pouvoir faire de l'arithmétique de pointeur. Il y aura des frais généraux associés à cela, car vous n'accédez plus aux instructions de la mémoire bare metal.

    Différentes langues ont des priorités de performances différentes, donc quelque chose qu'une langue optimise (ou plutôt, une implémentation d'une langue optimise) peut être impossible à faire rapidement dans une autre langue. La traduction d'un langage fonctionnel avec des appels de queue appropriés ralentira si vous le traduisez dans une langue sans appels de queue appropriés.

  4. Faire cette traduction ne rend pas le code lisible . Il est facile d'obtenir un morceau de code dans le langage B qui se comporte de la même manière que le code du langage A. Il est difficile de le faire ressembler à du code qu'un humain aurait écrit en B, pour un certain nombre de raisons. A et B peuvent avoir des outils d'abstraction différents, et l'ordinateur n'a aucune idée de ce qui rend le code lisible. Cela sera particulièrement vrai si vous utilisez la traduction de Turing Machine que j'ai décrite précédemment.

    Cela soulève la question: quel est l'intérêt d'une telle traduction? Si tout ce que vous obtenez à la fin est un bloc de code lent et illisible, pourquoi ne pas simplement le compiler en code machine et utiliser une sorte de communication FFI ou inter-processus pour relier les morceaux?

    Il y a quelques exceptions à cela. Parfois, vous avez besoin de choses dans une certaine langue (comme JavaScript). Parfois, la langue est similaire et une traduction sensée est facile. Parfois, un langage n'est pas destiné à être exécuté, mais à avoir son code extrait dans un autre langage (tel que Coq).

    Mais en général, ce n'est pas une chose très pratique.

jmite
la source
5
Un exemple pour le point 4 est asm.js . Aujourd'hui, il est possible de rendre sorta lisible, en utilisant Javascript Source carte et l'élément inspecteur, mais personne ne voudra le faire ...
Ismael Miguel
1
Modelica est un autre exemple de langage conçu pour être compilé dans une autre langue (dans ce cas C).
Rétablir Monica
Webassembly traduisant de C ++ en javascript.
Surt
Il existe de nombreux exemples de transpilateurs de X à Y, mais c'est différent d'un compilateur universel de n'importe quoi à n'importe quoi. Il y a évidemment des cas où le transpiling a du sens.
jmite
IMO manque une exception importante: la compilation en C. La raison en est que de nombreux systèmes peu communs ont un compilateur C existant, qui peut généralement émettre un code machine tout à fait raisonnable. Par conséquent, en compilant un langage en C, vous n'avez pas besoin d'avoir de backends pour ces architectures rares.
MSalters
2

Il existe de tels programmes. Par exemple, des traducteurs Lisp vers Fortran, qui étaient largement utilisés à l'époque. Les compilateurs Sole Lisp ne compilent pas directement Lisp mais génèrent du code C à la place qui est ensuite compilé par un compilateur C normal. Un autre exemple serait Vala qui n'est pas compilé directement mais d'abord traduit en C ++ avant la compilation du code C ++. Qt est écrit en MOC, un langage qui est traduit en C ++ afin de le compiler (mais comme MOC n'est que du C ++ avec quelques commandes supplémentaires, on peut discuter s'il doit vraiment être nommé un "nouveau langage") - et avant cela étaient des compilateurs C ++, il y avait des traducteurs C ++ vers C. Et certains projets ont été écrits en Pascal et ensuite traduits en C. De plus, clang et Java ont tendance à être une sorte de chose car ils traduisent le code C ++ et Java en un langage intermédiaire qui peut ensuite être traité plus loin.

Ce que vous ne pouvez pas attendre de la sortie d'un traducteur de langue, c'est que le résultat est logique pour un lecteur humain: la tâche du programme est d'écrire du code qui se traduit par un programme faisant la même chose que le code d'origine (ce qui, selon mon expérience, pourrait ou pourrait ne fonctionne pas, selon les fonctionnalités de la langue et les bibliothèques externes que vous utilisiez). Mais comme il ne connaît pas le but de cette tâche pour le reste du sens du programme, il pourrait être perdu dans une large mesure.

Gunter Königsmann
la source
0

Pas une réponse directe, mais il y a un outil appelé ILSpy , qui a été écrit pour le .Net Framework, et vous permet de décompiler un assembly .Net en C # ou VB.Net.

Si vous n'êtes pas familier avec la nature de .Net, vous pouvez écrire du code .Net dans de nombreuses langues, mais principalement en C # ou VB.Net. Lorsque le compilateur compile l'application, il traduit le code en un code "Intermediate Language" (ou IL pour faire court). Ce code est ensuite compilé en binaires .Net.

Étant donné que les applications .Net sont des binaires compilés à partir du code IL, ILSpy peut prendre l'application .Net, la retourner en code IL et, par la suite, aller plus loin et la revenir en C # ou VB.Net.

En utilisant cet outil, tout ce que vous avez à faire est de compiler une application, puis vous pouvez parcourir les fichiers compilés en code IL, C # ou VB.Net. Pour être clair, peu importe la langue dans laquelle le code a été initialement écrit. Tant que le binaire est un assembly .Net, il peut effectuer une rétro-ingénierie des fichiers compilés et produire le contenu dans l'une de ces trois langues.

Je sais que ce n'est pas exactement un compilateur, mais c'est un outil qui offre un résultat final similaire à ce que vous recherchez et, en fait, je l'ai utilisé pour "traduire" les projets VB.Net en quelque chose d'un peu plus familier - C #.

RLH
la source
0

Pour votre cas d'utilisation (basé sur des commentaires), il semble que SWIG pourrait être utile.

SWIG est un outil de développement logiciel qui connecte des programmes écrits en C et C ++ avec une variété de langages de programmation de haut niveau. SWIG est utilisé avec différents types de langages cibles, y compris les langages de script courants tels que Javascript, Perl, PHP, Python, Tcl et Ruby. La liste des langages pris en charge comprend également des langages sans script tels que C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go, Java, y compris Android, Lua, Modula-3, OCAML, Octave, Scilab et R Plusieurs implémentations de Scheme interprétées et compilées (Guile, MzScheme / Racket, Chicken) sont également prises en charge.

Nathan Ringo
la source
0

Je me souviens du vénérable f2c , qui fait la traduction de source à source de Fortran 77 en C.

Il a été (est parfois ...) utilisé principalement pour traduire du code numérique d'il y a des décennies sans avoir à intégrer un compilateur fortran à votre chaîne d'outils.

Alexandre C.
la source
0

Le morceau de théorie qui vous dit que de tels programmes existent, en principe, s'appelle des numérotations admissibles . Nous pouvons prouver qu'il existe des compilateurs calculables entre deux de ces numérotations, et chaque formalisme (ou langage de programmation) complet de Turing est, en substance, un.

Raphael
la source