2009-10-04 9 views
14

He estado programando durante años (principalmente Python), pero no entiendo lo que sucede entre bastidores cuando compilo o ejecuto mi código.Aprendiendo cómo funcionan los lenguajes de programación

En la línea de un question pregunté antes sobre los sistemas operativos, estoy buscando una introducción suave a la ingeniería del lenguaje de programación. Quiero ser capaz de definir y comprender los conceptos básicos de términos como compilador, intérprete, código nativo, código administrado, máquina virtual, etc. ¿Cuál sería una forma divertida e interactiva de aprender sobre esto?

+2

Pregunta de recursos definitiva del compilador en SO: http: // stackoverflow.com/questions/1669/learning-to-write-a-compiler Aquí hay algunos recursos sugeridos que adoptan un enfoque muy sencillo: si puede programar, está listo para aprender métodos de compilación. No tengas miedo. Me gusta el tutorial de Crenshaw. – dmckee

+0

^Esa es una excelente lista de recursos. Gracias. –

Respuesta

12

de ejecución en un

Un programa de pocas palabras (código) se introduce en el compilador (o intérprete).

Los caracteres se usan para formar tokens (+, identificadores, números) y su valor se almacena en algo llamado tabla de símbolos.

Estos tokens se combinan para formar sentencias: (int a = 6 + b * c;). Principalmente en la forma de un árbol de sintaxis:

     = 
        /\ 
       / \ 
        a  + 
        /\ 
        / \ 
        6  * 
         /\ 
         b c 

Dentro de un intérprete, el árbol se ejecuta directamente.

Con un compilador, el árbol finalmente se traduce a código intermedio o código de ensamblador.

Ahora tiene uno o más "archivos de objeto". Estos contienen el código de ensamblador sin los saltos precisos (porque aún no se conocen estos valores, especialmente si los objetivos están en otros archivos de objetos). Los archivos objeto están vinculados junto con un enlazador que completa los espacios en blanco para los saltos (referencias ans). El resultado del enlazador es una biblioteca (que también se puede vincular) o un archivo ejecutable.

Si inicia el archivo ejecutable, los datos del programa se copiarán en la memoria y existe algún otro mapeo de enlace para hacer coincidir los punteros con las ubicaciones de memoria correctas. Y luego se da el control a la primera instrucción.

3

This site has a great series de conferencias sobre la Estructura e Interpretación de Programas de Computadora, que es exactamente el tipo de cosas que quiere aprender. El libro de texto que lo acompaña también es útil, aunque no lo he leído personalmente. Creo que ver las conferencias es bastante bueno, te lleva el 60% del camino hasta allí.

0

Usted puede encontrar muchas conferencias .Por ejemplo en iTunes U

2

Whoa, esta es una pregunta enorme con un montón de libros escritos sobre todo esto. Realmente dudo que obtengas una respuesta decente en SO sobre esto. Necesitas ir a tu librería local o recoger algunas clases de ciencia comp.

para darle una rápida introducción:

  • Compilador: un programa que convierte el código escrito en instrucciones que se entienden de forma nativa por el procesador.
  • Intérprete: Un programa que lee el código escrito y, sobre la marcha, traduce y da las instrucciones correspondientes nativas del procesador.
  • Código administrado: Código que se ejecuta en una máquina virtual, p. para dar compatibilidad multiplataforma (Java).
  • Máquina virtual: Un programa que emula el comportamiento, o más bien la API, de un entorno de computadora en toda regla. Entre otras cosas, esto ofrece algunas ventajas de seguridad y compatibilidad multiplataforma.
4

compiladores, intérpretes y máquinas virtuales son solo ejemplos de detalles de implementación. Lo que podría buscar es la teoría de los lenguajes de programación, la gramática generativa, los traductores de idiomas, y posiblemente necesite alguna arquitectura de computadora para relacionar la teoría con las implementaciones.

Personalmente, aprendí de Sebesta's book. Da una introducción muy amplia al tema sin entrar en detalles minuciosos. También tiene un buen capítulo sobre la historia de los lenguajes de programación (~ 20 idiomas ~ 3 documentos por idioma). Tiene una buena explicación sobre las gramáticas y la teoría de los idiomas en general. Además, ofrece una buena introducción a los paradigmas de esquema, prólogo y programación (lógico, funcional, imperativo ^, orientado a objetos).

^Se concentra mucho más en el paradigma imperativo que los dos primeros.

Código
1

Cuando aprendí sobre programación, en algún lugar en la segunda mitad del siglo pasado, aprendí que todo se debe convertir a código de máquina. Los lenguajes de script simplemente decidirían qué código llamar según el código del script. El código compilado se compilaría primero en p-code, que significa código precompilado, que debe vincularse a otro código precompilado para crear una aplicación completa. Me gustó Turbo Pascal en aquel entonces, simplemente porque Turbo Pascal compiló directamente el código machione y no usó el código intermedio intermedio. Es decir, hasta Turbo Pascal 4.0, que creó * .tpu unidades compiladas. La mayoría de los otros compiladores compilarían en su lugar el formato .obj.

Cuando se creó Java, algo relativamente nuevo comenzó a hacerse popular. Básicamente, un compilador de Java simplemente compila código en algún archivo de script binario. Esta secuencia de comandos podría interpretarse, aunque ese mecanismo pronto también cambió.

Hoy en día, los intérpretes están casi extintos. La mayoría de los lenguajes guionizados se compilarán primero en código máquina, el código de la máquina se almacena en algún caché y, por lo tanto, se puede ejecutar muy rápido, sin que el sistema tenga que volver a interpretar ninguna instrucción repetitiva. Esto funciona bien para textos y scripts binarios. PHP sería un ejemplo de un script basado en texto. Java y .NET son scripts binarios, ya que generalmente compila el código en este formato de script binario. (Lo llamarán diferente, pero creo que las secuencias de comandos binarias suenan mejor.)

En general, el truco consiste en convertir el código en código de máquina, utilizando cualquier medio posible. Ha habido muchas formas de hacerlo y es un poco complejo dejarlo todo en claro.

También recuerdo el momento en que podía escribir una aplicación C++ donde las sentencias SQL se ubicarían dentro del código mismo. Esto también era muy práctico, pero requería un preprocesador que primero analizara las declaraciones SQL del código para convertirlo a otras sentencias C++ y reemplazando las sentencias SQL con los comandos C++ más complejos. Entonces todo se compilaría en código p. Entonces necesitarías vincularlo con las bibliotecas SQL adicionales y finalmente tendrías un ejecutable.

4

En términos básicos, escriba source files. Estos son archivos de texto de lujo, que están incluidos en el compiler que da como resultado alguna forma de código ejecutable (lo que se ejecuta depende del tipo de código del que se está hablando).El compilador tiene varias partes:

  • Alguna forma de preprocessing en el archivo que se ocupa de las macros y similares (como el de C).
  • A parser, que toma los archivos fuente, verifica que se ajustan a las reglas sintácticas de su idioma y transforma el archivo en una estructura de datos en memoria que es más fácilmente manipulable por otras partes del programa. Esto se llama árbol Abstract Syntax o AST.
  • Alguna forma de análisis AST, que verifica que el código real que escribió no viola ninguna regla del lenguaje (por ejemplo, recursividad en un idioma que no lo admite), así como muchas otras cosas.
  • Optimization como la optimización de la cola de llamadas, optimización de bucle y muchos otros tipos de optimizaciones.
  • Code generation, que es el proceso real de tomar el AST final y cualquier otro dato generado y convertirlo en un archivo binario de algún tipo que se puede ejecutar o interpretar.

Interpreter:

Un intérprete es un programa que toma en alguna forma de datos binarios que representa un programa no compilado a código directamente ejecutable por la máquina de destino, y ejecuta los comandos dentro. Los ejemplos son python, java y lua.

Native code:

Este es el código que se ha compilado en instrucciones nativas directamente ejecutables por la máquina de destino. Por ejemplo; si ejecuta una arquitectura x86, entonces C++ se compilará en un archivo ejecutable que sea comprensible para el procesador.

Virtual Machine:

Esto es generalmente un programa incorporado para simular la construcción y operación de un procesador. Puede ser tan simple como un programa que lee en bytecode y ejecuta operaciones en el idioma nativo basadas en los comandos que representa el bytecode (aunque llamar a esto una máquina virtual puede ser un tramo), o puede ser tan complejo como simular completamente el comportamiento de un procesador y todos los periféricos asociados.

esas otras respuestas tienen buenos puntos en ellas, pero esta información y enlaces deben comenzar. Cualquier otra pregunta, solo pregunta!

(La mayor parte de este artículo fue escrito con la ayuda de Wikipedia aunque algunos se escribió de memoria)

1

Este series of lectures de Stanford abarca varios lenguajes de programación a los bits y pernos, incluyendo Python (aunque sólo he miraba un par de los C)

2

Si desea saber cómo se va desde el código fuente a algo que realmente se ejecuta en una máquina de destino, debe obtener una copia del famoso Red Dragon Book. Lo he usado para construir analizadores léxicos y analizadores sintácticos. Si bien se remonta a 1986, y estoy seguro de que ha habido avances en el ínterin, por lo que puedo decir, no se ha superado como texto.

Parece que Addison-Wesley ha hecho una reimpresión de su predecesor, el Libro del Dragón Verde, y lo está pasando como algo reciente, así que tenga cuidado de obtener el artículo genuino.

Cuestiones relacionadas