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).
la source
Réponses:
TLDR; c'est possible mais pas pratique.
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.
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.
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:
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.
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.
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.
la source
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.
la source
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 #.
la source
Pour votre cas d'utilisation (basé sur des commentaires), il semble que SWIG pourrait être utile.
la source
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.
la source
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.
la source