php - que - programar en wordpress desde cero
¿Qué tipos de patrones podría aplicar al código para facilitar la traducción a otro lenguaje de programación? (6)
Me dispongo a hacer un proyecto paralelo que tiene el objetivo de traducir el código de un lenguaje de programación a otro. Los idiomas con los que estoy empezando son PHP y Python (desde Python hasta PHP debería ser más fácil comenzar), pero idealmente podría agregar otros idiomas con (relativa) facilidad. El plan es:
Esto está orientado al desarrollo web. El código original y el objetivo se situarán en la parte superior de los marcos (que también tendré que escribir). Estos marcos abarcarán un patrón de diseño MVC y seguirán estrictas convenciones de codificación. Esto debería facilitar la traducción.
También estoy mirando IOC y la inyección de dependencia, ya que pueden hacer que el proceso de traducción sea más fácil y menos propenso a errores.
Haré uso del módulo analizador de Python, lo que me permite jugar con el Árbol de sintaxis abstracta. Aparentemente, lo más cercano que puedo obtener con PHP es token_get_all() , que es un comienzo.
A partir de ese momento, puedo construir el AST, las tablas de símbolos y el flujo de control.
Entonces creo que puedo comenzar a producir código. No necesito una traducción perfecta . Todavía tendré que revisar el código generado y solucionar problemas. Lo ideal sería que el traductor marque las traducciones problemáticas.
Antes de preguntar "¿Qué diablos es el objetivo de esto?" La respuesta es ... Será una experiencia de aprendizaje interesante. Si tiene alguna idea sobre cómo hacer esto menos intimidante, por favor hágamelo saber.
EDITAR:
Estoy más interesado en saber qué tipos de patrones podría aplicar al código para que sea más fácil traducir (es decir, IoC, SOA?) El código que cómo hacer la traducción.
Consideraré el punto de vista de @EliBendersky con respecto al uso de ast.parse en lugar de analizador sintáctico (que antes no conocía). También te recomiendo encarecidamente que revises su blog. Utilicé ast.parse para hacer el traductor de Python-> JavaScript (@ https://bitbucket.org/amirouche/pythonium ). He ideado el diseño de Pythonium al revisar un poco otras implementaciones y probarlas por mi cuenta. Bifurqué Pythonium de https://github.com/PythonJS/PythonJS que también comencé, en realidad es una reescritura completa. El diseño general está inspirado en PyPy y http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf paper.
Todo lo que probé, desde el principio hasta la mejor solución, incluso si parece que el marketing de Pythonium realmente no lo es (no dude en decirme si algo no parece correcto para la netiqueta):
Implementar la semántica de Python en Plain JavaScript antiguo usando herencia de prototipo: AFAIK es imposible implementar la herencia múltiple de Python usando el sistema de objetos prototipo JS. Intenté hacerlo usando otros trucos más tarde (compárese con getattribute). Por lo que sé, no existe una implementación de la herencia múltiple de Python en JavaScript, lo mejor que existe es Single inhertance + mixins y no estoy seguro de que manejen la herencia de diamantes. Algo similar a Skulpt pero sin google clojure.
Intenté con Google clojure, al igual que Skulpt (compilador) en lugar de leer Skulpt code #fail. De todos modos, debido al sistema de objetos basado en el prototipo JS sigue siendo imposible. La creación de enlaces fue muy difícil, necesitas escribir JavaScript y un montón de código repetitivo (ver https://github.com/skulpt/skulpt/issues/50 donde yo soy el fantasma). En ese momento no había una forma clara de integrar el enlace en el sistema de compilación. Creo que Skulpt es una biblioteca y solo tienes que incluir tus archivos .py en el html para ser ejecutados, no es necesario que el desarrollador realice ninguna fase de compilación.
Probé pyjaco (compilador) pero crear enlaces (llamar código JavaScript desde el código Python) fue muy difícil, había demasiado código repetitivo para crear todo el tiempo. Ahora creo que Pyjaco es el que está más cerca de Pythonium. pyjaco está escrito en Python (ast.parse también) pero mucho está escrito en JavaScript y usa herencia de prototipos.
En realidad nunca logré ejecutar #fail # de Pijamas y nunca intenté leer el código #fail nuevamente. Pero en mi opinión, el pijama estaba haciendo translación API-> API (o framework a framework) y no traducción de Python a JavaScript. El marco de JavaScript consume datos que ya están en la página o datos del servidor. El código de Python es solo "fontanería". Después de eso, descubrí que el pijama era en realidad un verdadero traductor de python-> js.
Aún así, creo que es posible hacer una traducción API-> API (o framework-> framework) y eso es básicamente lo que hago en Pythonium pero a un nivel más bajo. Probablemente los pijamas usen el mismo algoritmo que Pythonium ...
Luego descubrí brython completamente escrito en Javascript como Skulpt, sin necesidad de compilación y mucha pelusa ... pero escrito en JavaScript.
Desde la línea inicial escrita en el curso de este proyecto, sabía sobre PyPy, incluso el backend de JavaScript para PyPy. Sí, puedes, si lo encuentras, generar directamente un intérprete de Python en JavaScript desde PyPy. La gente dice que fue un desastre. No leí por qué. Pero creo que la razón es que el lenguaje intermedio que utilizan para implementar el intérprete, RPython, es un subconjunto de Python adaptado para ser traducido a C (y tal vez a asm). Ira Baxter dice que siempre hace suposiciones cuando construye algo y, probablemente, lo afine para que sea el mejor en lo que se supone que debe hacer en el caso de la traducción PyPy: Python-> C. Esas suposiciones pueden no ser relevantes en otro contexto, empeorar la sobrecarga, de lo contrario la traducción directa siempre será mejor.
Tener el intérprete escrito en Python sonaba como una (muy) buena idea. Pero estaba más interesado en un compilador por motivos de rendimiento, también es más fácil compilar Python en JavaScript que interpretarlo.
Empecé PythonJS con la idea de armar un subconjunto de Python que pudiera traducir fácilmente a JavaScript. Al principio, ni siquiera me molesté en implementar el sistema OO debido a la experiencia pasada. El subconjunto de Python que logré traducir a JavaScript es:
- función con parámetros completos semánticos tanto en definición como en llamada. Esta es la parte de la que estoy más orgulloso.
- while / if / elif / else
- Los tipos de Python se convirtieron a tipos de JavaScript (no hay tipos de Python de ningún tipo)
- para podría iterar sobre matrices de Javascript solamente (para una matriz)
- Acceso transparente a JavaScript: si escribe Array en el código de Python, se traducirá a Array en javascript. Este es el mayor logro en términos de usabilidad sobre sus competidores.
- Puede pasar la función definida en el origen de Python a las funciones de JavaScript. Se tendrán en cuenta los argumentos predeterminados.
- Agrega una función especial llamada nueva que se traduce a JavaScript nueva, por ejemplo: new (Python) (1, 2, spam, "huevo") se traduce a "nueva Python (1, 2, spam," huevo ").
- "var" son manejados automáticamente por el traductor. (Muy buen hallazgo de Brett (colaborador de PythonJS).
- palabra clave global
- cierres
- lambdas
- lista de comprensiones
- las importaciones son compatibles a través de requirejs
- herencia de clase única + mixin vía classyjs
Esto parece mucho, pero realmente muy estrecho en comparación con la semántica completa de Python. Es realmente JavaScript con una sintaxis de Python.
El JS generado es perfecto, es decir. no hay gastos generales, no se puede mejorar en términos de rendimiento editando más. Si puede mejorar el código generado, también puede hacerlo desde el archivo fuente de Python. Además, el compilador no confió en ningún trucos JS que pueda encontrar en .js escrito por http://superherojs.com/ , por lo que es muy legible.
El descendiente directo de esta parte de PythonJS es el modo Pythonium Veloce. La implementación completa se puede encontrar en https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/veloce/veloce.py?at=master 793 SLOC + alrededor de 100 SLOC de código compartido con el otro traductor.
Una versión adaptada de pystones.py se puede traducir en modo Veloce cf. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pystone/?at=master
Después de haber configurado la traducción básica de Python-> JavaScript, elegí otra ruta para traducir Python completo a JavaScript. La forma de hacer glib haciendo código basado en clases orientadas a objetos, excepto el idioma de destino, es JS, por lo que tienes acceso a matrices, objetos similares a mapas y muchos otros trucos, y toda esa parte se escribió en Python. IIRC no hay código JavaScript escrito en el traductor de Pythonium. Obtener herencia individual no es difícil aquí son las partes difíciles lo que hace Pythonium totalmente compatible con Python:
-
spam.egg
en Python siempre se traduce engetattribute(spam, "egg")
Nogetattribute(spam, "egg")
esto en particular, pero creo que donde pierde mucho tiempo y no estoy seguro de poder mejorarlo con asm.js O algo más. - orden de resolución de métodos: incluso con el algoritmo escrito en Python, traducirlo a código compatible con Python Veloce fue un gran esfuerzo.
- getattributre : el algoritmo de resolución de getattribute real es un poco complicado y aún no admite descriptores de datos
- basado en la clase metaclass: sé dónde enchufar el código, pero aún así ...
- last bu no menos: some_callable (...) siempre se transalta a "call (some_callable)". AFAIK el traductor no utiliza la inferencia en absoluto, por lo que cada vez que hace una llamada necesita verificar qué tipo de objeto es llamarlo de la manera en que debe ser llamado.
Esta parte está incluida en https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master Está escrita en Python y es compatible con Python Veloce.
El traductor real compatible https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master no genera código JavaScript directamente y lo más importante no lo hace ast-> ast transformación . Probé lo más astuto y ast incluso si es más agradable trabajar con cst.NodeTransformer y, lo que es más importante, no necesito hacer ast-> ast.
Hacer python ast a python ast en mi caso al menos podría ser una mejora en el rendimiento ya que en algún momento inspecciono el contenido de un bloque antes de generar el código asociado con él, por ejemplo:
- var / global: para poder var algo, debo saber lo que necesito y no var. En lugar de generar un seguimiento de bloque qué variable se crean en un bloque dado e insertarlo encima del bloque de funciones generado, solo busco la asignación variable de variable cuando ingreso al bloque antes de visitar realmente el nodo secundario para generar el código asociado.
- rendimiento, los generadores tienen, hasta el momento, una sintaxis especial en JS, así que necesito saber qué función de Python es un generador cuando quiero escribir el "var my_generator = function"
Así que realmente no visito cada nodo una vez para cada fase de la traducción.
El proceso general se puede describir como:
Python source code -> Python ast -> Python source code compatible with Veloce mode -> Python ast -> JavaScript source code
Los builtins de Python están escritos en código de Python (!), IIRC existen algunas restricciones relacionadas con los tipos de arranque, pero usted tiene acceso a todo lo que puede traducir Pythonium en modo compatible. Eche un vistazo a https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/builtins/?at=master
Se puede entender el código JS de lectura generado a partir de pythonium, pero los mapas fuente serán de gran ayuda.
Los valiosos consejos que puedo darte a la luz de esta experiencia son pedos viejos y amables:
- Revise extensamente el tema tanto en la literatura como en proyectos existentes de fuente cerrada o gratuitos. Cuando revisé los diferentes proyectos existentes, debería haberle dado más tiempo y motivación.
- ¡hacer preguntas! Si supiera de antemano que backend PyPy era inútil debido a la sobrecarga debido a la falta de correspondencia semántica de C / Javascript. Tal vez tenía la idea de Pythonium antes de hace 6 meses, tal vez hace 3 años.
- sabe lo que quiere hacer, tiene un objetivo. Para este proyecto tenía diferentes objetivos: practicar un poco un javascript, aprender más de Python y poder escribir el código de Python que se ejecutaría en el navegador (más y más abajo).
- fracaso es experiencia
- un pequeño paso es un paso
- empieza pequeño
- Sueño grande
- hacer demos
- iterar
Con el modo Python Veloce solamente, ¡estoy muy feliz! Pero a lo largo del camino descubrí que lo que realmente estaba buscando era liberarme a mí y a los demás de Javascript, pero lo más importante era que podía crear de forma cómoda. Esto me llevó a Scheme, DSL, Modelos y eventualmente modelos específicos de dominio (véase http://dsmforum.org/ ).
Acerca de qué respuesta de Ira Baxter:
Las estimaciones no son útiles en absoluto. Me llevó más o menos 6 meses de tiempo libre para PythonJS y Pythonium. Entonces puedo esperar más de tiempo completo 6 meses. Creo que todos sabemos lo que 100 años-hombre en un contexto empresarial puede significar y no significar en absoluto ...
Cuando alguien dice que algo es difícil o más a menudo imposible, respondo que "solo lleva tiempo encontrar una solución para un problema que es imposible", de lo contrario, nada es imposible, excepto si se demuestra que es imposible en este caso una prueba matemática ...
Si no se prueba que es imposible, deja espacio para la imaginación:
- encontrar una prueba que demuestre que es imposible
y
- Si es imposible, puede haber un problema "inferior" que puede tener una solución.
o
- si no es imposible, encontrar una solución
No es solo un pensamiento optimista. Cuando comencé Python-> Javascript todo el mundo decía que era imposible. PyPy imposible. Metaclases demasiado duras. etc ... Creo que la única revolución que trae PyPy sobre el documento Scheme-> C (que tiene 25 años) es cierta generación JIT automática (sugerencias basadas en el intérprete RPython, creo).
La mayoría de las personas que dicen que una cosa es "difícil" o "imposible" no brindan los motivos. C ++ es difícil de analizar? Lo sé, todavía son analizadores (gratuitos) de C ++. ¿El mal está en los detalles? Yo sé eso. Decir que es imposible solo no es útil, es incluso peor que "no es útil", es desalentador y algunas personas quieren desalentar a los demás. Escuché sobre esta pregunta a través de https://.com/questions/22621164/how-to-automatically-generate-a-parser-code-to-code-translator-from-a-corpus .
¿Cuál sería la perfección para ti ? Así es como defines el próximo objetivo y tal vez alcances el objetivo general.
Estoy más interesado en saber qué tipos de patrones podría aplicar al código para que sea más fácil traducir (es decir, IoC, SOA?) El código que cómo hacer la traducción.
No veo patrones que no se puedan traducir de un idioma a otro, al menos de manera menos que perfecta. Dado que la traducción del idioma al idioma es posible, será mejor que apuntes primero. Desde entonces, creo que de acuerdo con http://en.wikipedia.org/wiki/Graph_isomorphism_problem , la traducción entre dos idiomas de computadora es un árbol o isomorfismo DAG. Incluso si ya sabemos que ambos están completos, entonces ...
Framework-> Framework, que mejor visualizo como API-> La traducción de API aún puede ser algo que se debe tener en cuenta como una forma de mejorar el código generado. Por ejemplo: Prolog como sintaxis muy específica, pero aún puedes hacer Prolog como cálculo describiendo el mismo gráfico en Python ... Si tuviera que implementar un traductor Prolog to Python, no implementaría la unificación en Python, sino en una biblioteca C y vendría con una "sintaxis de Python" que es muy legible para un Pythonist. Al final, la sintaxis es solo "pintura", por lo que damos un significado (es por eso que comencé el esquema). El mal está en el detalle del lenguaje y no estoy hablando de la sintaxis. Los conceptos que se utilizan en el lenguaje getattribute hook (puede vivir sin él) pero requieren funciones de VM como la optimización de recursión de cola pueden ser difíciles de tratar. No le importa si el programa inicial no utiliza la recursividad de cola e incluso si no hay recursión de cola en el idioma de destino, puede emularlo usando greenlets / evento de bucle.
Para idiomas de origen y destino, busque:
- Ideas grandes y específicas
- Ideas compartidas pequeñas y comunes
De esto surgirá:
- Cosas que son fáciles de traducir
- Cosas que son difíciles de traducir
Probablemente también podrá saber qué se traducirá a un código rápido y lento.
También está la cuestión del stdlib o de cualquier biblioteca, pero no hay una respuesta clara, depende de tus objetivos.
Código idiomático o código generado legible también tienen soluciones ...
Dirigirse a una plataforma como PHP es mucho más fácil que orientar los navegadores, ya que puede proporcionar una implementación en C de ruta lenta o crítica.
Dado que el primer proyecto es traducir Python a PHP, al menos para el subconjunto PHP3 que conozco, la personalización de veloce.py es su mejor opción. Si puede implementar veloce.py para PHP, entonces probablemente podrá ejecutar el modo compatible ... Además, si puede traducir PHP al subconjunto de PHP puede generar con php_veloce.py significa que puede traducir PHP al subconjunto de Python que veloce.py puede consumir, lo que significa que puede traducir PHP a Javascript. Solo digo...
También puedes echarle un vistazo a esas bibliotecas:
También podría interesarle esta publicación de blog (y comentarios): https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/
- Este Google Tech Talk de Ira Baxter es interesante https://www.youtube.com/watch?v=C-_dw9iEzhA
Escribir un traductor no es imposible, especialmente teniendo en cuenta que el interno de Joel lo hizo durante un verano.
Si quieres hacer un idioma, es fácil. Si quieres hacer más, es un poco más difícil, pero no demasiado. La parte más difícil es que, si bien cualquier idioma completo puede hacer lo que hace otro idioma completo, los tipos de datos integrados pueden cambiar lo que hace un lenguaje fenomenalmente.
Por ejemplo:
word = ''This is not a word''
print word[::-2]
requiere una gran cantidad de código C ++ para duplicar (bueno, puedes hacerlo bastante corto con algunas construcciones de bucle, pero aún así).
Eso es un poco de un lado, supongo.
¿Alguna vez ha escrito un tokenizador / analizador basado en una gramática de lenguaje? Probablemente querrás aprender cómo hacerlo si no lo has hecho, porque esa es la parte principal de este proyecto. Lo que haría sería crear una sintaxis completa de Turing, algo bastante similar al bytecode Python. Luego, crea un lexer / analizador que toma una gramática del lenguaje (tal vez usando BNF ), y basado en la gramática, compila el lenguaje en su lenguaje intermedio. Entonces, lo que querrá hacer es hacer lo contrario: cree un analizador de su idioma en los idiomas de destino según la gramática.
El problema más obvio que veo es que al principio probablemente creará un código terriblemente ineficiente, especialmente en lenguajes * más potentes como Python.
Pero si lo haces de esta manera, entonces probablemente puedas descubrir maneras de optimizar la salida a medida que avanzas. Para resumir:
- leer la gramática proporcionada
- compilar programa en sintaxis intermedia (pero también Turing completa)
- compilar un programa intermedio en el idioma final (basado en la gramática proporcionada)
- ...?
- ¡Lucro!(?)
* por poderoso quiero decir que esto toma 4 líneas:
myinput = raw_input("Enter something: ")
print myinput.replace(''a'', ''A'')
print sum(ord(c) for c in myinput)
print myinput[::-1]
Muéstrame otro idioma que pueda hacer algo así en 4 líneas, y te mostraré un lenguaje que es tan poderoso como Python.
Hay un par de respuestas que te dicen que no te molestes. Bueno, ¿qué tan útil es eso? ¿Tu quieres aprender? Puedes aprender. Esto es compilación. Sucede que su idioma de destino no es un código de máquina, sino otro idioma de alto nivel. Esto está hecho todo el tiempo.
Hay una manera relativamente fácil de comenzar. Primero, ve a http://sourceforge.net/projects/lime-php/ (si quieres trabajar en PHP) o algo así y sigue el código de ejemplo. A continuación, puede escribir un analizador léxico utilizando una secuencia de expresiones regulares y tokens de alimentación para el analizador que genere. Sus acciones semánticas pueden generar código directamente en otro idioma o crear una estructura de datos (objetos de pensamiento, hombre) que puede administrar y recorrer para generar código de salida.
Tienes suerte con PHP y Python porque en muchos aspectos son del mismo idioma pero con una sintaxis diferente. La parte difícil es superar las diferencias semánticas entre las formas gramaticales y las estructuras de datos. Por ejemplo, Python tiene listas y diccionarios, mientras que PHP solo tiene matrices de asociaciones.
El enfoque de "aprendiz" consiste en construir algo que funcione bien para un subconjunto restringido del lenguaje (como solo declaraciones impresas, matemática simple y asignación de variables), y luego eliminar progresivamente las limitaciones. Eso es básicamente lo que hicieron los "grandes" muchachos en el campo.
Ah, y como no tienes tipos estáticos en Python, es mejor escribir y confiar en funciones de PHP como "python_add" que agrega números, cadenas u objetos de acuerdo con la forma en que lo hace Python.
Obviamente, esto puede ser mucho más grande si lo dejas.
He estado desarrollando herramientas (DMS Software Reengineering Toolkit) para hacer manipulación de programas de propósito general (siendo la traducción de idiomas un caso especial) desde 1995, respaldada por un sólido equipo de científicos informáticos. DMS proporciona análisis genéricos, creación de AST, tablas de símbolos, control y análisis de flujo de datos, aplicación de reglas de traducción, regeneración del texto fuente con comentarios, etc., todos ellos parametrizados mediante definiciones explícitas de lenguajes de programación.
La cantidad de maquinaria que necesita para hacer esto bien es enorme (especialmente si desea poder hacer esto para múltiples idiomas de manera general), y luego necesita analizadores confiables para idiomas con definiciones poco confiables (PHP es el ejemplo perfecto de esto )
No hay nada de malo en que piense en crear un traductor de idioma a idioma o en intentarlo, pero creo que encontrará una tarea mucho más grande para los lenguajes reales de lo que esperaba. Tenemos unos 100 años-hombre invertidos en solo DMS, y otros 6-12 meses en cada definición de lenguaje "confiable" (incluido el que penosamente diseñamos para PHP), mucho más para lenguajes desagradables como C ++. Será una "experiencia infernal de aprendizaje"; ha sido para nosotros (Puede encontrar la sección de Documentos técnicos en el sitio web anterior interesante para comenzar ese aprendizaje).
La gente a menudo intenta construir algún tipo de maquinaria generalizada comenzando con una pieza de tecnología con la que están familiarizados, que hace una parte del trabajo. (Los AST de Python son un gran ejemplo). La buena noticia es que esa parte del trabajo ya está hecha. La mala noticia es que la maquinaria tiene un trillón de suposiciones incorporadas, la mayoría de las cuales no descubrirás hasta que trates de luchar para hacer otra cosa. En ese momento, descubres que la maquinaria está conectada para hacer lo que originalmente hace, y realmente resistirán tu intento de hacer que haga otra cosa. (Sospecho que tratar de obtener Python AST para modelar PHP va a ser muy divertido).
La razón por la que comencé a construir DMS originalmente fue para construir cimientos que tenían muy pocas suposiciones incorporadas. Tiene algunas que nos dan dolores de cabeza. Hasta ahora, no hay agujeros negros. (La parte más difícil de mi trabajo en los últimos 15 años es tratar de evitar que esas suposiciones se vuelvan locas).
Muchas personas también cometen el error de suponer que si pueden analizar (y tal vez obtener un AST), están en camino de hacer algo complicado. Una de las lecciones difíciles es que necesita tablas de símbolos y análisis de flujo para realizar un buen análisis o transformación del programa. Los AST son necesarios pero no suficientes. Esta es la razón por la cual el libro de compilación de Aho y Ullman no se detiene en el capítulo 2. (El OP tiene este derecho porque planea construir maquinaria adicional más allá del AST). Para más información sobre este tema, vea Life After Parsing .
El comentario sobre "No necesito una traducción perfecta" es problemático. Lo que hacen los traductores débiles es convertir el 80% "fácil" del código, dejando el 20% difícil de hacer a mano. Si la aplicación que pretende convertir es bastante pequeña, y solo tiene la intención de convertirla una vez, entonces ese 20% está bien. Si desea convertir muchas aplicaciones (o incluso la misma con cambios menores a lo largo del tiempo), esto no es bueno. Si intenta convertir 100K SLOC, entonces 20% son 20,000 líneas originales de código que son difíciles de traducir, comprender y modificar en el contexto de otras 80,000 líneas de programas traducidos que usted ya no comprende. Eso requiere una gran cantidad de esfuerzo. En el nivel de millones de líneas, esto es simplemente imposible en la práctica. (Sorprendentemente, hay personas que desconfían de las herramientas automatizadas e insisten en traducir millones de sistemas de líneas a mano, eso es aún más difícil y normalmente lo descubren con mucho retraso, altos costos y, a menudo, rotundos fallos).
Lo que tienes que disparar para traducir sistemas a gran escala es el alto porcentaje de conversiones porcentuales de los noventa, o es probable que no puedas completar la parte manual de la actividad de traducción.
Otra consideración clave es el tamaño del código a traducir. Se necesita mucha energía para construir un traductor robusto y funcional, incluso con buenas herramientas. Si bien parece atractivo y genial construir un traductor en lugar de simplemente hacer una conversión manual, para bases de código pequeño (por ejemplo, hasta 100K SLOC en nuestra experiencia) la economía simplemente no lo justifica. A nadie le gusta esta respuesta, pero si realmente tiene que traducir 10K SLOC de código, probablemente será mejor que solo muerda la bala y lo haga. Y sí, eso es doloroso.
Considero que nuestras herramientas son extremadamente buenas (pero entonces, soy bastante parcial). Y todavía es muy difícil construir un buen traductor; nos toma alrededor de 1.5-2 años-hombre y sabemos cómo usar nuestras herramientas. La diferencia es que con tanta maquinaria, succeed mucho más a menudo de lo que fallamos.
Mi respuesta abordará la tarea específica de analizar Python para traducirlo a otro idioma, y no los aspectos de nivel superior que Ira dirigió bien en su respuesta.
En resumen: no use el módulo analizador, hay una manera más fácil.
El módulo ast
, disponible desde Python 2.6, es mucho más adecuado para sus necesidades, ya que le proporciona un AST listo para trabajar. He escrito un artículo sobre este último año, pero en resumen, use el método parse
de ast
para analizar el código fuente de Python en un AST. El módulo parser
le dará un árbol de análisis sintáctico, no un AST. Tenga cuidado con la diferencia .
Ahora, dado que los AST de Python son bastante detallados, dado un AST, el trabajo de front-end no es terriblemente difícil. Supongo que puedes tener un prototipo simple para algunas partes de la funcionalidad listo bastante rápido. Sin embargo, llegar a una solución completa llevará más tiempo, principalmente porque la semántica de los idiomas es diferente. Un subconjunto simple del lenguaje (funciones, tipos básicos, etc.) se puede traducir fácilmente, pero una vez que ingresas en las capas más complejas, necesitarás maquinaria pesada para emular el núcleo de un idioma en otro. Por ejemplo, considere los generadores de Python y enumere las comprensiones que no existen en PHP (según mi mejor conocimiento, que es ciertamente pobre cuando se trata de PHP).
Para darle un consejo final, considere la herramienta 2to3
creada por los desarrolladores de Python para traducir el código de Python 2 al código de Python 3. Front-end-wise, tiene la mayoría de los elementos necesarios para traducir Python a algo . Sin embargo, dado que los núcleos de Python 2 y 3 son similares, no se requiere maquinaria de emulación allí.
You could take a look at the Vala compiler , which translates Vala (a C#-like language) into C.