web-dev-qa-db-fra.com

Quels types de modèles pourrais-je appliquer au code pour faciliter la traduction dans un autre langage de programmation?

Je me propose de faire un projet parallèle qui a pour objectif de traduire du code d'un langage de programmation à un autre. Les langues avec lesquelles je commence sont PHP et Python (Python à PHP devrait être plus facile à démarrer)), mais Idéalement, je pourrais ajouter d'autres langues avec une facilité (relative). Le plan est le suivant:

  • Ceci est orienté vers le développement web. Le code original et cible sera placé au-dessus des frameworks (que je devrai également écrire). Ces cadres adopteront un modèle de conception MVC et suivront des conventions de codage strictes. Cela devrait faciliter la traduction.

  • Je regarde également IOC et l'injection de dépendances, car ils pourraient rendre le processus de traduction plus facile et moins sujet aux erreurs.

  • Je vais utiliser le module - parser de Python , qui me permet de jouer avec l'arbre de la syntaxe abstraite. Apparemment, le plus proche que je peux obtenir avec PHP est token_get_all () , ce qui est un début.

  • À partir de là, je peux construire l'AST, les tables de symboles et le flux de contrôle.

Ensuite, je crois que je peux commencer à sortir du code. Je n'ai pas besoin d'une traduction parfaite . Je devrai encore revoir le code généré et résoudre les problèmes. Idéalement, le traducteur devrait signaler les traductions problématiques.

Avant de vous demander "Qu'est-ce que c'est que ça?" La réponse est ... Ce sera une expérience d'apprentissage intéressante. Si vous avez des idées sur la façon de rendre cela moins intimidant, faites-le moi savoir.


ÉDITER:

Je suis plus intéressé à savoir quels types de modèles je pourrais appliquer sur le code pour le rendre plus facile à traduire (ie: IoC, SOA?) Le code que comment faire la traduction.

95
NullUserException

J'ai été construction d'outils (DMS Software Reengineering Toolkit) pour faire de la manipulation de programmes à usage général (avec la traduction de langue étant un cas spécial) depuis 1995, soutenu par une solide équipe d'informaticiens. DMS fournit une analyse générique, AST bâtiment, tables de symboles, contrôle et analyse du flux de données, application des règles de traduction, régénération du texte source avec commentaires, etc., tous paramétrés par des définitions explicites des langages informatiques.

La quantité de machines dont vous avez besoin pour bien faire est vaste (surtout si vous voulez pouvoir le faire pour plusieurs langues de manière générale), puis vous avez besoin d'analyseurs fiables pour les langages avec des définitions peu fiables (PHP en est un parfait exemple).

Il n'y a rien de mal à ce que vous pensiez à construire un traducteur de langue à langue ou à l'essayer, mais je pense que vous trouverez que la tâche est beaucoup plus importante pour les vraies langues que vous ne le pensez. Nous avons investi environ 100 années-homme dans seulement DMS, et encore 6 à 12 mois dans chaque définition de langage "fiable" (y compris celle que nous avons péniblement construite pour PHP), beaucoup plus pour les langages méchants tels que C++. Ce sera "un enfer d'une expérience d'apprentissage"; ça a été pour nous. (Vous pourriez trouver la section Documents techniques sur le site Web ci-dessus intéressante pour démarrer cet apprentissage).

Les gens tentent souvent de construire une sorte de machinerie généralisée en commençant par une technologie qu'ils connaissent, qui fait une partie du travail. (Les AST Python sont un excellent exemple). La bonne nouvelle, c'est qu'une partie du travail est terminée. La mauvaise nouvelle est que les machines ont des millions d'hypothèses intégrées, dont la plupart ne seront découvertes que lorsque vous essaierez de vous battre pour faire autre chose. À ce moment-là, vous découvrez que la machinerie est câblée pour faire ce qu'elle fait à l'origine, et résistera vraiment, vraiment à votre tentative de lui faire faire autre chose. (Je soupçonne d'essayer d'obtenir le Python AST to model PHP va être très amusant).

La raison pour laquelle j'ai commencé à construire DMS à l'origine était de construire des fondations qui contenaient très peu d'hypothèses de ce type. Jusqu'à présent, pas de trous noirs. (La partie la plus difficile de mon travail au cours des 15 dernières années est d'essayer d'empêcher ces hypothèses de s'infiltrer).

Beaucoup de gens font également l'erreur de supposer que s'ils peuvent analyser (et peut-être obtenir un AST), ils sont en bonne voie de faire quelque chose de compliqué. L'une des dures leçons est que vous avez besoin de tables de symboles et d'une analyse de flux pour effectuer une bonne analyse ou transformation de programme. Les AST sont nécessaires mais pas suffisants. C'est la raison pour laquelle le livre de compilation d'Aho & Ullman ne s'arrête pas au chapitre 2. (L'OP a ce droit en ce qu'il prévoit de construire des machines supplémentaires au-delà de l'AST). Pour plus d'informations sur ce sujet, voir Life After Parsing .

La remarque sur "Je n'ai pas besoin d'une traduction parfaite" est gênante. Ce que les traducteurs faibles font est de convertir les 80% "faciles" du code, laissant les 20% difficiles à faire à la main. Si l'application que vous avez l'intention de convertir est assez petite et que vous n'avez l'intention de la convertir qu'une seule fois, ces 20% sont OK. Si vous souhaitez convertir de nombreuses applications (ou même la même avec des modifications mineures au fil du temps), ce n'est pas bien. Si vous tentez de convertir 100K SLOC, 20% correspond à 20 000 lignes de code originales difficiles à traduire, à comprendre et à modifier dans le contexte de 80 000 autres lignes de programme traduit que vous ne comprenez pas déjà. Cela demande énormément d'efforts. Au niveau du million de lignes, cela est tout simplement impossible dans la pratique. (Étonnamment, il y a des gens qui se méfient des outils automatisés et insistent pour traduire manuellement des millions de systèmes de ligne; c'est encore plus difficile et ils le découvrent généralement douloureusement avec de longs délais , des coûts élevés et souvent une panne pure et simple.)

Ce que vous devez viser pour traduire des systèmes à grande échelle, ce sont des taux de conversion en pourcentage élevés des années 90, ou il est probable que vous ne puissiez pas terminer la partie manuelle de l'activité de traduction.

Une autre considération clé est la taille du code à traduire. Il faut beaucoup d'énergie pour construire un traducteur robuste et fonctionnel, même avec de bons outils. Bien qu'il semble sexy et cool de construire un traducteur au lieu de simplement faire une conversion manuelle, pour les petites bases de code (par exemple, jusqu'à environ 100K SLOC selon notre expérience), l'économie ne le justifie tout simplement pas. Personne n'aime cette réponse, mais si vous devez vraiment traduire seulement 10K SLOC de code, vous feriez probablement mieux de simplement mordre la balle et de le faire. Et oui, c'est douloureux.

Je considère que nos outils sont extrêmement bons (mais ensuite, je suis assez biaisé). Et il est encore très difficile de construire un bon traducteur; cela nous prend environ 1,5 à 2 années-hommes et nous savons comment utiliser nos outils. La différence est qu'avec autant de machines, nous réussissons beaucoup plus souvent que nous échouons.

119
Ira Baxter

Ma réponse portera sur la tâche spécifique d'analyser Python afin de le traduire dans une autre langue, et non sur les aspects de niveau supérieur que Ira a bien abordés dans sa réponse.

En bref: n'utilisez pas le module analyseur, il existe un moyen plus simple.

Le module ast, disponible depuis Python 2.6 est beaucoup plus adapté à vos besoins, car il vous donne un AST prêt à l'emploi. J'ai écrit un article à ce sujet l'année dernière, mais en bref, utilisez la méthode parse de ast pour analyser Python code source dans un AST. Le module parser vous donnera un arbre d'analyse, pas un AST. Méfiez-vous de la différence .

Maintenant, puisque les AST de Python sont assez détaillés, étant donné un AST le travail frontal n'est pas terriblement difficile. Je suppose que vous pouvez avoir un prototype simple pour certaines parties de la fonctionnalité prêt assez rapidement. Cependant, arriver à une solution complète prendra plus de temps, principalement parce que la sémantique des langues est différente. Un simple sous-ensemble du langage (fonctions, types de base, etc.) peut être facilement traduit, mais une fois que vous entrez dans les couches les plus complexes, vous aurez besoin de machines lourdes pour émuler le noyau d'un langage dans un autre. Par exemple, considérons les générateurs de Python et les listes de compréhension qui n'existent pas dans PHP (à ma connaissance, qui est certes médiocre lorsque PHP est impliqué).

Pour vous donner un dernier conseil, considérez l'outil 2to3 Créé par les développeurs Python pour traduire le code Python 2 en code Python 3. Côté front-end, il contient la plupart des éléments dont vous avez besoin pour traduire Python en quelque chose. Cependant, comme les cœurs de Python 2 et 3 sont similaires, aucun mécanisme d'émulation n'y est requis.

13
Eli Bendersky

Écrire un traducteur n'est pas impossible, d'autant plus que le stagiaire de Joel l'a fait pendant un été.

Si vous voulez faire une langue, c'est facile. Si vous voulez en faire plus, c'est un peu plus difficile, mais pas trop. La partie la plus difficile est que, bien que tout langage complet de turing puisse faire ce qu'un autre langage complet de turing fait, les types de données intégrés peuvent changer ce que fait un langage de façon phénoménale.

Par exemple:

Word = 'This is not a Word'
print Word[::-2]

prend un beaucoup de code C++ à dupliquer (ok, bien vous pouvez le faire assez court avec quelques constructions en boucle, mais quand même).

C'est un peu un aparté, je suppose.

Avez-vous déjà écrit un tokenizer/parser basé sur une grammaire linguistique? Vous voudrez probablement apprendre à le faire si vous ne l'avez pas fait, car c'est la partie principale de ce projet. Ce que je ferais, c'est trouver une syntaxe complète de Turing de base - quelque chose d'assez similaire à Python bytecode . Ensuite, vous créez un lexer/analyseur qui prend une grammaire linguistique ( peut-être en utilisant BNF ), et en fonction de la grammaire, compile la langue dans votre langue intermédiaire. Ensuite, ce que vous voudrez faire est de faire l'inverse - créer un analyseur de votre langue dans les langues cibles en fonction de la grammaire.

Le problème le plus évident que je vois est qu'au début, vous créerez probablement un code horriblement inefficace, en particulier dans les langages plus puissants * comme Python.

Mais si vous le faites de cette façon, vous pourrez probablement trouver des moyens d'optimiser la sortie au fur et à mesure. Résumer:

  • lire la grammaire fournie
  • compiler le programme en syntaxe intermédiaire (mais aussi complète de Turing)
  • compiler le programme intermédiaire dans la langue finale (basé sur la grammaire fournie)
  • ...?
  • Profit!(?)

* par puissant je veux dire que cela prend 4 lignes:

myinput = raw_input("Enter something: ")
print myinput.replace('a', 'A')
print sum(ord(c) for c in myinput)
print myinput[::-1]

Montrez-moi un autre langage qui peut faire quelque chose comme ça en 4 lignes, et je vais vous montrer un langage aussi puissant que Python.

5
Wayne Werner

Il y a quelques réponses qui vous disent de ne pas vous embêter. Eh bien, est-ce utile? Tu veux apprendre? Tu peux apprendre. Ceci est une compilation. Il se trouve que votre langue cible n'est pas un code machine, mais un autre langage de haut niveau. Cela se fait tout le temps.

Il existe un moyen relativement simple de commencer. Tout d'abord, allez chercher http://sourceforge.net/projects/Lime-php/ (si vous voulez travailler en PHP) ou quelque chose comme ça et passez par l'exemple de code. Ensuite, vous pouvez écrire un analyseur lexical à l'aide d'une séquence d'expressions régulières et envoyer des jetons à l'analyseur que vous générez. Vos actions sémantiques peuvent soit générer du code directement dans un autre langage, soit créer une structure de données (pensez à des objets, homme) que vous pouvez masser et parcourir pour générer du code de sortie.

Vous avez de la chance avec PHP et Python car à bien des égards, ils sont le même langage les uns que les autres, mais avec une syntaxe différente. La partie difficile est de surmonter les différences sémantiques entre les formes grammaticales et les structures de données. Par exemple, Python a des listes et des dictionnaires, tandis que PHP n'a que des tableaux d'assoc).

L'approche "apprenant" consiste à créer quelque chose qui fonctionne bien pour un sous-ensemble restreint de la langue (comme uniquement les instructions d'impression, les mathématiques simples et l'affectation des variables), puis à supprimer progressivement les limitations. C'est essentiellement ce que les "gros" gars du domaine ont fait.

Oh, et comme vous n'avez pas de types statiques en Python, il vaut peut-être mieux écrire et compter sur PHP des fonctions comme "python_add" qui ajoute des nombres, des chaînes ou des objets selon la manière Python le fait.

Évidemment, cela peut devenir beaucoup plus gros si vous le laissez.

3
Ian

Je vais appuyer le point de vue @EliBendersky concernant l'utilisation d'ast.parse au lieu de l'analyseur (que je ne connaissais pas auparavant). Je vous recommande également chaleureusement de revoir son blog. J'ai utilisé ast.parse pour faire le traducteur Python-> JavaScript (@ https://bitbucket.org/amirouche/pythonium ). J'ai trouvé la conception de Pythonium en quelque peu en examinant d'autres implémentations et en les essayant moi-même. J'ai bifurqué Pythonium de https://github.com/PythonJS/PythonJS que j'ai également commencé, c'est en fait une réécriture complète. La conception globale est inspirée de PyPy et http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf papier.

Tout ce que j'ai essayé, du début à la meilleure solution, même si cela ressemble à du marketing Pythonium, ce n'est vraiment pas le cas (n'hésitez pas à me dire si quelque chose ne semble pas correct pour la netiquette):

  • Implémenter Python sémantique en JavaScript ancien simple en utilisant l'héritage du prototype: AFAIK il est impossible d'implémenter Python l'héritage multiple en utilisant le système d'objet prototype JS. J'ai essayé de le faire en utilisant d'autres astuces plus tard (cf. getattribute). Pour autant que je sache, il n'y a pas d'implémentation de l'héritage multiple Python en JavaScript, le meilleur qui existe est l'héritage simple + mixins et je ne suis pas sûr qu'ils gèrent l'héritage diamant. Un peu similaire à Skulpt mais sans google clojure.

  • J'ai essayé avec Google clojure, tout comme Skulpt (compilateur) au lieu de lire réellement le code Skulpt #fail. Quoi qu'il en soit, le système d'objets basé sur le prototype JS est toujours impossible. La création de la liaison était très très difficile, vous devez écrire JavaScript et beaucoup de code passe-partout (cf. https://github.com/skulpt/skulpt/issues/5 où je suis le fantôme). À cette époque, il n'existait aucun moyen clair d'intégrer la liaison dans le système de génération. Je pense que Skulpt est une bibliothèque et il suffit d'inclure vos fichiers .py dans le html pour être exécuté, aucune phase de compilation requise par le développeur.

  • Pyjaco essayé (compilateur) mais créer des liaisons (appeler du code Javascript à partir du code Python) était très difficile, il y avait trop de code standard à créer à chaque fois. Maintenant, je pense que pyjaco est celui qui se rapproche le plus de Pythonium. pyjaco est écrit en Python (ast.parse aussi) mais beaucoup est écrit en JavaScript et utilise l'héritage du prototype.

Je n'ai jamais réussi à exécuter un pyjama #fail et je n'ai jamais essayé de relire le code #fail. Mais dans mon esprit, le pyjama faisait de la traduction API-> API (ou framework à framework) et non de la traduction de Python vers JavaScript. Le framework JavaScript consomme des données qui sont déjà dans la page ou des données du serveur. Python le code n'est que "plomberie". Après cela, j'ai découvert que le pyjama était en fait un vrai traducteur python-> js.

Pourtant, je pense qu'il est possible de faire une traduction API-> API (ou framework-> framework) et c'est fondamentalement ce que je fais en Pythonium mais à un niveau inférieur. Les pyjamas utilisent probablement le même algorithme que Pythonium ...

Puis j'ai découvert du brython entièrement écrit en Javascript comme Skulpt, pas besoin de compilation et beaucoup de fluff ... mais écrit en JavaScript.

Depuis la ligne initiale écrite au cours de ce projet, je connaissais PyPy, même le backend JavaScript pour PyPy. Oui, vous pouvez, si vous le trouvez, générer directement un interpréteur Python en JavaScript à partir de PyPy. Les gens disent que c'était une catastrophe. Je ne lis pas où pourquoi. Mais je pense que la raison en est que le langage intermédiaire qu'ils utilisent pour implémenter l'interpréteur, RPython, est un sous-ensemble de Python adapté pour être traduit en C (et peut-être asm). Ira Baxter dit que vous faites toujours des suppositions lorsque vous construisez quelque chose et probablement vous affinez pour qu'il soit le meilleur dans ce qu'il est censé faire dans le cas de la traduction PyPy: Python-> C. Ces hypothèses peuvent ne pas être pertinentes dans un autre contexte, pire elles peuvent entraîner des frais généraux, sinon la traduction directe sera probablement toujours meilleure.

Faire interpréter l'interprète en Python sonnait comme une (très) bonne idée. Mais j'étais plus intéressé par un compilateur pour des raisons de performances, il est en fait plus facile de compiler Python vers JavaScript que de l'interpréter.

J'ai commencé PythonJS avec l'idée de rassembler un sous-ensemble de Python que je pourrais facilement traduire en JavaScript. Au début, je n'ai même pas pris la peine d'implémenter le système OO à cause de mon expérience passée. Le sous-ensemble de Python que j'ai réussi à traduire en JavaScript est:

  • fonction avec des paramètres sémantiques complets à la fois dans la définition et l'appel. C'est la partie dont je suis le plus fier.
  • while/if/Elif/else
  • Les types Python ont été convertis en types JavaScript (il n'y a pas de types python de toute nature)
  • car pourrait parcourir les tableaux Javascript uniquement (pour un tableau in)
  • Accès transparent à JavaScript: si vous écrivez Array dans le code Python, il sera traduit en Array en javascript. Il s'agit de la plus grande réalisation en termes de convivialité par rapport à ses concurrents.
  • Vous pouvez passer la fonction définie dans Python source aux fonctions javascript. Les arguments par défaut seront pris en compte.
  • Il a une fonction spéciale appelée new qui est traduite en JavaScript nouveau par exemple: new (Python) (1, 2, spam, "Egg") est traduit en "new Python (1, 2, spam," Egg ").
  • "var" est automatiquement géré par le traducteur. (très belle découverte de Brett (contributeur PythonJS).
  • mot-clé global
  • fermetures
  • lambdas
  • liste des compréhensions
  • les importations sont prises en charge via requirejs
  • héritage de classe unique + mixin via classyjs

Cela semble beaucoup mais en fait très étroit par rapport à la sémantique complète de Python. C'est vraiment du JavaScript avec une syntaxe Python.

Le JS généré est parfait ie. il n'y a pas de frais généraux, il ne peut pas être amélioré en termes de performances en le modifiant davantage. Si vous pouvez améliorer le code généré, vous pouvez également le faire à partir du fichier source Python. En outre, le compilateur ne s'est appuyé sur aucune astuce JS que vous pouvez trouver dans .js écrit par http://superherojs.com/ , il est donc très lisible.

Le descendant direct de cette partie de PythonJS est le mode Pythonium Veloce. L'implémentation complète peut être trouvée @ https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/veloce/veloce.py?at=master 793 SLOC + environ 100 SLOC de code partagé avec l'autre traducteur.

Une version adaptée de pystones.py peut être traduite en mode Veloce cf. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pystone/?at=master

Après avoir configuré la traduction Python-> JavaScript de base, j'ai choisi un autre chemin pour traduire Python complet en JavaScript. La manière dont Glib fait du code basé sur une classe orientée objet, à l'exception du langage cible, est JS, vous avez donc accès aux tableaux, aux objets de type carte et à de nombreuses autres astuces, et toute cette partie a été écrite en Python. IIRC il n'y a pas de code javascript écrit dans le traducteur Pythonium. Obtenir l'héritage unique n'est pas difficile ici sont les parties difficiles qui rendent Pythonium entièrement compatible avec Python:

  • spam.Egg Dans Python est toujours traduit en getattribute(spam, "Egg") Je n'ai pas profilé cela en particulier mais je pense que là où ça perd beaucoup de temps et je ne suis pas sûr peut l'améliorer avec asm.js ou toute autre chose.
  • ordre de résolution de la méthode: même avec l'algorithme écrit en Python, le traduire en Python du code compatible Veloce était un gros effort.
  • getattributre : l'algorithme de résolution de getattribute est un peu délicat et ne prend toujours pas en charge les descripteurs de données
  • classe de métaclasse basée: je sais où brancher le code, mais quand même ...
  • dernier point mais non des moindres: some_callable (...) est toujours transformé en "call (some_callable)". AFAIK le traducteur n'utilise pas du tout l'inférence, donc chaque fois que vous faites un appel, vous devez vérifier de quel type d'objet il s'agit pour l'appeler comme il est censé être appelé.

Cette partie est prise en compte dans https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master Elle est écrite en Python compatible avec Python Veloce.

Le traducteur conforme réel https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master ne génère pas de code JavaScript directement et surtout ne le fait pas '' t faire ast-> ast transformation. J'ai essayé la chose ast-> ast et ast même si plus agréable que cst n'est pas agréable de travailler même avec ast.NodeTransformer et plus important encore, je n'ai pas besoin de faire ast-> ast.

Faire python ast à python ast dans mon cas au moins serait peut-être une amélioration des performances car j'inspecte parfois le contenu d'un bloc avant de générer le code qui lui est associé, par exemple:

  • var/global: pour pouvoir var quelque chose, je dois savoir ce dont j'ai besoin et ne pas var. Au lieu de générer un bloc de suivi des variables qui sont créées dans un bloc donné et de les insérer au-dessus du bloc fonctionnel généré, je cherche simplement une attribution de variable révélatrice lorsque j'entre dans le bloc avant de visiter le nœud enfant pour générer le code associé.
  • rendement, les générateurs ont, pour le moment, une syntaxe spéciale dans JS, j'ai donc besoin de savoir quelle fonction Python est un générateur quand je veux écrire la "var my_generator = function"

Je ne visite donc pas vraiment chaque nœud une fois pour chaque phase de la traduction.

Le processus global peut être décrit comme:

Python source code -> Python ast -> Python source code compatible with Veloce mode -> Python ast -> JavaScript source code

Les commandes internes de Python sont écrites dans le code Python (!), IIRC il y a quelques restrictions liées aux types d'amorçage, mais vous avez accès à tout ce qui peut traduire Pythonium en mode conforme. Jetez un œil à https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/builtins/?at=master

La lecture de code JS généré à partir de pythonium est compréhensible, mais les cartes sources seront très utiles.

Les précieux conseils que je peux vous donner à la lumière de cette expérience sont de bons vieux farts:

  • revoir en profondeur le sujet à la fois dans la littérature et les projets existants en source libre ou gratuite. Quand j'ai passé en revue les différents projets existants, j'aurais dû lui donner beaucoup plus de temps et de motivation.
  • poser des questions! Si je savais à l'avance que le backend PyPy était inutile à cause de la surcharge due au décalage sémantique C/Javascript. J'aurais peut-être eu l'idée de Pythonium bien avant il y a 6 mois peut-être 3 ans.
  • savoir ce que vous voulez faire, avoir un objectif. Pour ce projet, j'avais différents objectifs: pratiquer un peu le javascript, en savoir plus sur Python et être capable d'écrire Python code qui s'exécuterait dans le navigateur (plus et que ci-dessous).
  • l'échec est l'expérience
  • un petit pas est un pas
  • commencer petit
  • rêve grand
  • faire des démos
  • répéter

Avec Python mode Veloce uniquement, je suis très content! Mais en cours de route, j'ai découvert que ce que je cherchais vraiment, c'était de me libérer, moi et les autres, de Javascript, mais surtout de pouvoir créer de manière confortable. Cela m'a conduit à Scheme, DSL, Models et éventuellement des modèles spécifiques à un domaine (cf. http://dsmforum.org/ ).

À propos de la réponse d'Ira Baxter:

Les estimations ne sont pas du tout utiles. J'ai pris plus ou moins 6 mois de temps libre pour PythonJS et Pythonium. Je peux donc m'attendre à plus de temps plein 6 mois. Je pense que nous savons tous ce que 100 années-hommes dans un contexte d'entreprise peuvent signifier et pas du tout ...

Quand quelqu'un dit que quelque chose est difficile ou plus souvent impossible, je réponds que "cela ne prend que du temps pour trouver une solution à un problème qui est impossible" sinon dit que rien n'est impossible sauf si cela s'avère impossible dans ce cas une preuve mathématique ...

Si ce n'est pas prouvé impossible, cela laisse place à l'imagination:

  • trouver une preuve prouvant qu'il est impossible

et

  • S'il est impossible, il peut y avoir un problème "inférieur" qui peut avoir une solution.

ou

  • si ce n'est pas impossible, trouver une solution

Ce n'est pas seulement une pensée optimiste. Quand j'ai commencé Python-> Javascript, tout le monde disait que c'était impossible. PyPy impossible. Les métaclasses sont trop dures. etc ... Je pense que la seule révolution qui apporte PyPy sur du papier Scheme-> C (qui a 25 ans) est une génération JIT automatique (des conseils basés sur l'écrivain RPython je pense).

La plupart des gens qui disent qu'une chose est "difficile" ou "impossible" n'en donnent pas les raisons. C++ est difficile à analyser? Je sais que, ils sont toujours (gratuit) analyseur C++. Le mal est dans le détail? Je le sais. Dire que c'est impossible seul n'est pas utile, c'est encore pire que "pas utile", c'est décourageant, et certaines personnes veulent décourager les autres. J'ai entendu parler de cette question via https://stackoverflow.com/questions/22621164/how-to-automatically-generate-a-parser-code-to-code-translator-from-a-corpus .

Quelle serait la perfection pour vous ? C'est ainsi que vous définissez le prochain objectif et atteignez peut-être l'objectif global.

Je suis plus intéressé à savoir quels types de modèles je pourrais appliquer sur le code pour le rendre plus facile à traduire (ie: IoC, SOA?) Le code que comment faire la traduction.

Je ne vois aucun modèle qui ne peut pas être traduit d'une langue à une autre langue au moins d'une manière moins que parfaite. Étant donné que la traduction de langue à langue est possible, vous feriez mieux de viser cela en premier. Depuis, je pense que selon http://en.wikipedia.org/wiki/Graph_isomorphism_problem , la traduction entre deux langages informatiques est un arbre ou un isomorphisme DAG. Même si nous savons déjà qu'ils sont tous deux complets, alors ...

Framework-> Framework que je visualise mieux en tant qu'API-> La traduction d'API pourrait toujours être quelque chose que vous pourriez garder à l'esprit comme un moyen d'améliorer le code généré. Par exemple: Prolog comme syntaxe très spécifique mais vous pouvez toujours faire Prolog comme un calcul en décrivant le même graphe en Python ... Si je devais implémenter un traducteur Prolog vers Python je n'implémenterais pas l'unification dans Python mais dans une bibliothèque C et proposer une "syntaxe Python" très lisible pour un pythoniste. Au final, la syntaxe n'est que "peinture" pour laquelle on donne un sens (c'est pourquoi j'ai commencé le schéma). Le mal est dans le détail du langage et je ne parle pas de la syntaxe. Les concepts utilisés dans le langage getattribute hook (vous pouvez vous en passer) mais nécessitaient VM des fonctionnalités comme l'optimisation de la récursivité de la queue peut être difficile à gérer. Vous ne vous souciez pas si le programme initial n'utilise pas la récursivité de queue et même s'il n'y a pas de récursivité de queue dans la langue cible, vous pouvez l'émuler en utilisant des greenlets/boucle d'événement.

Pour les langues cible et source, recherchez:

  • Des idées grandes et spécifiques
  • Idées partagées minuscules et communes

De cela émergera:

  • Des choses faciles à traduire
  • Choses difficiles à traduire

Vous pourrez également probablement savoir ce qui sera traduit en code rapide et lent.

Il y a aussi la question du stdlib ou de n'importe quelle bibliothèque mais il n'y a pas de réponse claire, cela dépend de vos objectifs.

Le code idiomatique ou le code généré lisible ont aussi des solutions ...

Cibler une plate-forme comme PHP est beaucoup plus facile que de cibler les navigateurs, car vous pouvez fournir une implémentation C du chemin lent et/ou critique.

Étant donné que votre premier projet consiste à traduire Python en PHP, au moins pour le sous-ensemble PHP3 que je connais, la personnalisation de veloce.py est votre meilleur pari. Si vous pouvez implémenter veloce.py pour PHP alors vous pourrez probablement exécuter le mode conforme ... Aussi si vous pouvez traduire PHP dans le sous-ensemble de PHP vous pouvez générer avec php_veloce.py cela signifie que vous pouvez traduire PHP dans le sous-ensemble de Python que veloce.py peut consommer, ce qui signifie que vous pouvez traduire PHP à Javascript. Je dis juste ...

Vous pouvez également consulter ces bibliothèques:

Vous pouvez également être intéressé par ce billet de blog (et commentaires): https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/

2
amirouche

Vous pouvez jeter un œil au compilateur Vala , qui traduit Vala (un langage de type C #) en C.

0
ptomato