Supposons que X est la langue d'entrée, Z est la langue de sortie, puis f est le compilateur, qui est écrit dans la langue Y.
f = X -> Z
Puisque f n'est qu'un programme, je pense que Y peut être n'importe quelle langue, non? Nous pouvons donc avoir des compilateurs f1, f2, chacun écrit en Y1, Y2.
f1 = f Y1
f2 = f Y2
g = Z -> M
h = g . f # We get a compiler X -> M
Prenez le compilateur cpython par exemple, X est Python, Z est le code VM Python, Y est C.
cpython = Python -> PythonVMCode C
interpreter = PythonVMCode -> Nothing
interpreter2 = PythonVMCode -> MachineCode
Les sources Python sont compilées dans le code Python VM, les fichiers .pyc, puis interprétées par l'interpréteur. On dirait qu'il est possible qu'il existe un compilateur qui peut directement faire Python -> MachineCode, bien que beaucoup difficile à implémenter:
hardpython = interpreter2 . cpython
Nous pouvons également écrire un autre compilateur faire le travail Python -> PythonVMCode, dans une autre langue, dit Python lui-même.
mypython = Python -> PythonVMCode Python
mypython2 = Python -> PythonVMCode Ruby
Maintenant, voici l'exemple compliqué PyPy. Je suis juste un débutant de PyPy, corrigez-moi si je me trompe:
Doc PyPy http://doc.pypy.org/en/latest/architecture.html#pypy-the-translation-framework
Notre objectif est de fournir une solution possible au problème des implémenteurs de langage: avoir à écrire l * o * p interprètes pour l langages dynamiques et p plateformes avec o des décisions de conception cruciales.
On peut penser que l est X, p est Y. Il existe un programme qui traduit tous les programmes RPython en C:
rpython_compiler = RPython -> C Python
pypy = Python -> Nothing RPython
translate = compile the program pypy written in RPython using rpython_compiler
py2rpy = Python -> RPython Python
py2c = Python -> C Python
py2c = rpython_compiler . py2rpy
Les programmes RPython sont comme les instructions VM, rpython_compiler est la VM.
q1. pypy est l'interpréteur, un programme RPython qui peut interpréter le code Python, il n'y a pas de langage de sortie, donc nous ne pouvons pas le considérer comme un compilateur, non?
Ajoutée:
- Je viens de découvrir que même si après la traduction, pypy est toujours un interprète, mais cette fois écrit en C.
- Si nous regardons profondément dans le pypy interprète, je crois qu'il doit exister une sorte de compilateur, qui compile les sources Python en AST, puis exécute
comme ça:
compiler_inside_pypy = Python -> AST_or_so
q2. Le compilateur py2rpy peut-il exister, transformant tous les programmes Python en RPython? Dans quelle langue il est écrit n'a pas d'importance. Si oui, nous obtenons un autre compilateur py2c. Quelle est la différence entre pypy et py2rpy dans la nature? Py2rpy est-il beaucoup plus difficile à écrire que pypy?
q3. Existe-t-il des règles générales ou une théorie à ce sujet?
Plus de compilateurs:
gcc_c = C -> asm? C # not sure, gimple or rtl?
g++ = C++ -> asm? C
clang = C -> LLVM_IR C++
jython = Python -> JVMCode java
ironpython = Python -> CLI C#
q4. Étant donné f = X -> Z, un programme P écrit en X. Lorsque nous voulons accélérer P, que pouvons-nous faire? Voies possibles:
réécrire P dans un algorithme plus efficace
réécrire f pour générer un meilleur Z
si Z est interprété, écrivez un meilleur interprète Z (PyPy est ici?)
accélérer les programmes écrits en Z récursivement
obtenir une meilleure machine
ps. Cette question ne concerne pas les aspects techniques de la façon d'écrire un compilateur, mais la faisabilité et la complexité de l'écriture d'un certain type de compilateur.