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 langages avec lesquels je commence sont PHP et Python (Python à PHP devrait être plus facile pour commencer), mais idéalement, je serais capable d'ajouter d'autres langages avec (relative) facilité. Le plan est:
Ceci est orienté vers le développement Web. Le code original et cible sera assis sur des frameworks (que je devrai également écrire). Ces frameworks adopteront un modèle de conception MVC et suivront des conventions de codage strictes. Cela devrait rendre la traduction un peu plus facile.
J'examine également l'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 analyseur de Python , qui me permet de jouer avec l'arbre de syntaxe abstraite. Apparemment, le plus proche que je puisse 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 contrôler le flux.
Ensuite, je crois que je peux commencer à produire du code. Je n'ai pas besoin d'une traduction parfaite . Je vais encore devoir revoir le code généré et résoudre les problèmes. Idéalement, le traducteur devrait signaler les traductions problématiques.
Avant de 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, veuillez me le faire savoir.
ÉDITER:
Je suis plus intéressé à savoir quels types de modèles je pourrais appliquer sur le code pour faciliter la traduction (ie: IoC, SOA?) Le code que comment faire la traduction.
la source
Réponses:
Je construis des outils (DMS Software Reengineering Toolkit) pour faire des manipulations de programmes à usage général (la traduction de langue étant un cas particulier) depuis 1995, soutenu par une solide équipe d'informaticiens. DMS fournit l'analyse générique, la construction AST, les tables de symboles, l'analyse de contrôle et de flux de données, l'application de règles de traduction, la régénération du texte source avec des commentaires, etc., le tout paramétré par des définitions explicites de langages informatiques.
La quantité de machines que vous devez faire ce bien est vaste (surtout si vous voulez être en mesure de le faire pour plusieurs langues d'une manière générale), et vous avez besoin parseurs fiables pour les langues avec des définitions peu fiables (PHP est parfait exemple ).
Il n'y a rien de mal à penser à créer un traducteur de langue à langue ou à l'essayer, mais je pense que vous trouverez que c'est une tâche beaucoup plus importante pour les vraies langues que ce à quoi vous vous attendez. Nous avons investi quelque 100 années-homme uniquement dans le 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 des langages désagréables tels que C ++. Ce sera une «expérience d'apprentissage d'enfer»; cela a été pour nous. (Vous pourriez trouver la section des documents techniques sur le site Web ci-dessus intéressante pour démarrer cet apprentissage).
Les gens essaient souvent de construire une sorte de machinerie généralisée en commençant par une technologie avec laquelle ils sont familiers, qui fait une partie du travail. (Les AST Python sont un excellent exemple). La bonne nouvelle, c'est qu'une partie du travail est faite. La mauvaise nouvelle est que la machinerie a des millions d'hypothèses intégrées, dont la plupart ne seront pas découvertes tant que vous n'essayerez pas de faire autre chose. À ce stade, vous découvrez que la machine est câblée pour faire ce qu'elle fait à l'origine et qu'elle résistera vraiment, vraiment à votre tentative de lui faire faire autre chose. (Je pense qu'essayer de faire en sorte que Python AST modélise PHP va être très amusant).
La raison pour laquelle j'ai commencé à construire DMS à l'origine était de construire des fondations qui avaient très peu d'hypothèses intégrées. Certaines d'entre elles nous donnent des maux de tête. 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 de telles 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 sur la bonne voie pour faire quelque chose de compliqué. L'une des leçons difficiles 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 du compilateur d'Aho & Ullman ne s'arrête pas au chapitre 2. (L'OP a ce droit dans la mesure où il prévoit de construire des machines supplémentaires au-delà de l'AST). Pour plus d'informations sur ce sujet, consultez Life After Parsing .
La remarque "Je n'ai pas besoin d'une traduction parfaite" est gênante. Ce que font les traducteurs faibles, c'est 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 avez seulement l'intention de la convertir une fois correctement, alors ce 20% est 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 essayez de convertir 100K SLOC, 20% correspondent à 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, c'est tout simplement impossible dans la pratique.plus difficile et ils découvrent normalement douloureusement avec de longs délais, des coûts élevés et souvent un échec pur et simple.)
Ce que vous devez viser pour traduire des systèmes à grande échelle, ce sont des taux de conversion é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 efficace et robuste, 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 dans notre expérience), les aspects économiques ne le justifient 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 alors, je suis assez partial). Et il est encore très difficile de construire un bon traducteur; cela nous prend environ 1,5 à 2 années-homme 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.
la source
Ma réponse abordera la tâche spécifique d'analyse de Python afin de le traduire dans une autre langue, et non les aspects de niveau supérieur que Ira a bien abordés dans sa réponse.
Bref: n'utilisez pas le module parser, il existe un moyen plus simple.
Le
ast
module, disponible depuis Python 2.6, est beaucoup plus adapté à vos besoins, car il vous donne un AST prêt à l'emploi avec lequel travailler. J'ai écrit un article à ce sujet l'année dernière, mais en bref, utilisez laparse
méthode deast
pour analyser le code source Python dans un AST. Leparser
module vous donnera un arbre d'analyse, pas un AST. Méfiez-vous de la différence .Maintenant, comme 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, parvenir à une solution complète prendra plus de temps, principalement parce que la sémantique des langages est différente. Un sous-ensemble simple 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 en PHP (à ma connaissance, ce qui est certes médiocre lorsque PHP est impliqué).
Pour vous donner un dernier conseil, considérez l'
2to3
outil créé par les développeurs Python pour traduire le code Python 2 en code Python 3. En ce qui concerne le 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, aucune machine d'émulation n'y est nécessaire.la source
2to3
est juste AST à AST. Il ne prend pas en charge tout ce qui dépasse les capacités duast
module. Notez que toutes les traductions vont de la syntaxe prise en charge par le processus python hôte à la syntaxe prise en charge par le processus python hôte. Il n'y a pas de traducteur qui ajoute, disons, des annotations de fonction, car 2.6 ne le prend pas en charge.2to3
peut être vu comme un exemple d'utilisation de l'AST généré à partir deast
.É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. Le plus difficile est que, bien que n'importe quel langage complet turing puisse faire ce qu'un autre langage complet turing fait, les types de données intégrés peuvent changer de façon phénoménale ce qu'un langage fait.
Par exemple:
prend beaucoup de code C ++ à dupliquer (ok, vous pouvez le faire assez court avec des constructions en boucle, mais quand même).
C'est un peu un aparté, je suppose.
Avez-vous déjà écrit un tokenizer / analyseur basé sur une grammaire de langue? Vous voudrez probablement apprendre comment faire cela si vous ne l'avez pas fait, car c'est la partie principale de ce projet. Ce que je ferais, c'est proposer une syntaxe complète de base de Turing - quelque chose d'assez similaire au bytecode Python . Ensuite, vous créez un lexer / analyseur qui prend une grammaire de langue (peut-être en utilisant BNF ), et basé sur 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 allez probablement créer du code horriblement inefficace, en particulier dans des langages plus puissants * comme Python.
Mais si vous le faites de cette façon, vous serez probablement en mesure de trouver des moyens d'optimiser la sortie au fur et à mesure. Résumer:
* par puissant, je veux dire que cela prend 4 lignes:
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.
la source
Il y a quelques réponses qui vous disent de ne pas vous embêter. Eh bien, à quel point est-ce utile? Tu veux apprendre? Tu peux apprendre. C'est une compilation. Il se trouve que votre langage cible n'est pas du 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 du genre et parcourez l'exemple de code. Ensuite, vous pouvez écrire un analyseur lexical à l'aide d'une séquence d'expressions régulières et de jetons de flux vers 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 aux objets, à l'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 dans le même langage, mais avec une syntaxe différente. Le plus dur 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 du langage (comme uniquement les instructions d'impression, les mathématiques simples et l'affectation de variables), puis de supprimer progressivement les limitations. C'est essentiellement ce que les «gros» gars du terrain ont tous fait.
Oh, et comme vous n'avez pas de types statiques en Python, il peut être préférable d'écrire et de s'appuyer sur des fonctions PHP comme "python_add" qui ajoute des nombres, des chaînes ou des objets selon la façon dont Python le fait.
De toute évidence, cela peut devenir beaucoup plus important si vous le laissez.
la source
Je vais seconder le point de vue de @EliBendersky concernant l'utilisation d'ast.parse au lieu de parser (que je ne connaissais pas auparavant). Je vous recommande également vivement de consulter son blog. J'ai utilisé ast.parse pour faire le traducteur Python-> JavaScript (@ https://bitbucket.org/amirouche/pythonium ). J'ai inventé la conception de Pythonium en examinant quelque peu d' autres implémentations et en les essayant moi-même. J'ai forké Pythonium de https://github.com/PythonJS/PythonJS que j'ai également commencé, c'est en fait une réécriture complète. La conception générale est inspirée du papier PyPy et http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf .
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 à la nétiquette):
Implémentation de la sémantique Python dans Plain Old JavaScript en utilisant l'héritage prototype: AFAIK, il est impossible d'implémenter l'héritage multiple Python en utilisant le système d'objet prototype JS. J'ai essayé de le faire en utilisant d'autres astuces plus tard (cf. getattribute). 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 unique + mixins et je ne suis pas sûr qu'ils gèrent l'héritage de diamant. Un peu similaire à Skulpt mais sans Google Clojure.
J'ai essayé avec Google clojure, tout comme Skulpt (compilateur) au lieu de lire le code Skulpt #fail. Quoi qu'il en soit à cause du système d'objet basé sur un prototype JS encore impossible. Créer une reliure a été très très difficile, il faut écrire du JavaScript et beaucoup de code passe-partout (cf. https://github.com/skulpt/skulpt/issues/50 où je suis le fantôme). À cette époque, il n'y avait pas de moyen clair d'intégrer la liaison dans le système de construction. Je pense que Skulpt est une bibliothèque et il suffit d'inclure vos fichiers .py dans le html à exécuter, aucune phase de compilation n'est requise par le développeur.
J'ai essayé pyjaco (compilateur) mais créer des liaisons (appeler du code Javascript à partir de 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 est le plus proche de Pythonium. pyjaco est écrit en Python (ast.parse aussi) mais beaucoup est écrit en JavaScript et utilise l'héritage de prototype.
Je n'ai jamais réussi à exécuter Pyjamas #fail et je n'ai jamais essayé de relire le code #fail. Mais dans mon esprit, pyjamas faisait de la traduction API-> API (ou framework vers framework) et non de la traduction Python vers JavaScript. Le framework JavaScript consomme des données qui se trouvent déjà dans la page ou des données du serveur. Le code Python n'est que de la "plomberie". Après cela, j'ai découvert que pyjamas était en fait un véritable traducteur python-> js.
Pourtant, je pense qu'il est possible de faire de la traduction API-> API (ou framework-> framework) et c'est essentiellement ce que je fais dans Pythonium mais à un niveau inférieur. Pyjama utilise probablement le même algorithme que Pythonium ...
Puis j'ai découvert 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 depuis PyPy. Les gens disent que c'était une catastrophe. Je n'ai lu nulle part pourquoi. Mais je pense que la raison est que le langage intermédiaire qu'ils utilisent pour implémenter l'interpréteur, RPython, est un sous-ensemble de Python conçu pour être traduit en C (et peut-être asm). Ira Baxter dit que vous faites toujours des hypothèses lorsque vous construisez quelque chose et que vous l'ajustez probablement 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 pourraient ne pas être pertinentes dans un autre contexte, pires qu'elles peuvent entraîner des frais généraux, sinon la traduction directe sera probablement toujours meilleure.
Avoir l'interpréteur écrit en Python semblait être 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 en JavaScript que de l'interpréter.
J'ai commencé PythonJS avec l'idée de créer un sous-ensemble de Python que je pourrais facilement traduire en JavaScript. Au début, je n'ai même pas pris la peine de mettre en œuvre le système OO en raison de l'expérience passée. Le sous-ensemble de Python que j'ai réussi à traduire en JavaScript est:
Cela semble beaucoup mais en fait très restreint 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 surcharge, il ne peut pas être amélioré en termes de performances en l'éditant davantage. Si vous pouvez améliorer le code généré, vous pouvez également le faire à partir du fichier source Python. De plus, le compilateur ne s'appuyait sur aucune astuce JS que vous pouvez trouver dans .js écrit par http://superherojs.com/ , donc c'est 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 de base de Python-> JavaScript, j'ai choisi un autre chemin pour traduire Python complet en JavaScript. La manière de glib de faire du code basé sur une classe orientée objet, sauf le langage cible, est JS, vous avez donc accès à des tableaux, des 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 par dans le traducteur Pythonium. Obtenir un héritage unique n'est pas difficile, voici les parties difficiles qui rendent Pythonium entièrement compatible avec Python:
spam.egg
en Python est toujours traduit engetattribute(spam, "egg")
Je n'ai pas profilé cela en particulier, mais je pense que là où cela perd beaucoup de temps et je ne suis pas sûr de pouvoir l'améliorer avec asm.js ou autre chose.Cette partie est prise en compte dans https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master Il est écrit en Python compatible avec Python Veloce.
Le traducteur conforme actuel https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master ne génère pas de code JavaScript directement et, surtout, n'effectue pas de transformation ast-> ast . J'ai essayé la chose ast-> ast et même si plus agréable que cst n'est pas agréable de travailler même avec ast.NodeTransformer et surtout je n'ai pas besoin de faire ast-> ast.
Faire de python ast à python ast dans mon cas au moins serait peut-être une amélioration des performances puisque j'inspecte parfois le contenu d'un bloc avant de générer le code qui lui est associé, par exemple:
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:
Les buildins Python sont écrits en code Python (!), IIRC il y a quelques restrictions liées aux types de bootstraping, 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 du code JS généré à partir de la compatibilité pythonium peut être comprise, mais les cartes sources seront grandement utiles.
Les précieux conseils que je peux vous donner à la lumière de cette expérience sont de bons vieux pets:
Avec le mode Python Veloce uniquement, je suis très content! Mais en cours de route, j'ai découvert que ce que je cherchais vraiment é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 au 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 6 mois à temps plein. Je pense que nous savons tous ce que 100 années-homme dans un contexte d'entreprise peuvent signifier et ne pas signifier 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" autrement dit que rien n'est impossible sauf s'il s'avère impossible dans ce cas une preuve mathématique ...
Si cela n'est pas impossible, cela laisse place à l'imagination:
et
ou
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. Métaclasses trop difficiles. etc ... Je pense que la seule révolution qui apporte PyPy sur le papier Scheme-> C (qui a 25 ans) est une génération automatique de JIT (basée sur des indices écrits dans l'interpréteur 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 des analyseurs C ++ (gratuits). Le mal est dans le détail? Je le sais. Dire que c'est impossible à lui seul n'est pas utile, c'est encore pire que «pas utile», c'est décourageant, et certaines personnes veulent en décourager les autres. J'ai entendu parler de cette question via /programming/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 que vous atteignez peut-être l'objectif global.
Je ne vois aucun modèle qui ne puisse pas être traduit d'une langue à une autre au moins d'une manière moins que parfaite. Étant donné que la traduction d'une langue à une autre est possible, vous feriez mieux de viser cette première. Depuis, je pense que selon http://en.wikipedia.org/wiki/Graph_isomorphism_problem , la traduction entre deux langages informatiques est un isomorphisme arborescent ou DAG. Même si nous savons déjà qu'ils sont tous les deux terminés, alors ...
Framework-> Framework que je visualise mieux comme API-> La traduction d'API pourrait encore être quelque chose que vous pourriez garder à l'esprit comme moyen d'améliorer le code généré. Par exemple: Prolog comme syntaxe très spécifique mais vous pouvez quand même faire Prolog comme le calcul en décrivant le même graphe en Python ... Si je devais implémenter un traducteur Prolog en Python, je n'implémenterais pas l'unification en Python mais dans une bibliothèque C et je viendrais avec une "syntaxe Python" qui est très lisible pour un pythoniste. Au final, la syntaxe n'est que "peinture" pour laquelle on donne un sens (c'est pour cela que 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 getattributehook (vous pouvez vous en passer) mais les fonctionnalités VM requises telles que l'optimisation de la récursivité de la queue peuvent être difficiles à 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:
De cela émergera:
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 puisque vous pouvez fournir une implémentation en C d'un 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, vous pourrez probablement exécuter le mode conforme ... De plus, 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 en sous-ensemble de Python que veloce.py peut consommer, ce qui signifie que vous pouvez traduire PHP en Javascript. Juste en disant ...
Vous pouvez également jeter un œil à ces bibliothèques:
Cet article de blog (et commentaires) pourrait également vous intéresser: https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/
la source
Vous pouvez jeter un œil au compilateur Vala , qui traduit Vala (un langage de type C #) en C.
la source