2010-11-30 20 views
6

Cuando pienso en "compilar", pienso en convertir el código de C++ en un binario. O tal vez C# en el código de byte CLR. Pero el "análisis sintáctico" podría ser algo así como analizar Python, o un lenguaje de plantilla web, donde no necesita producir ningún binario, pero puede ejecutar el código inmediatamente, declaración por instrucción o salida de HTML directamente.¿"analizar" un subconjunto de "compilación"?

¿Básicamente estarías haciendo la misma tarea en ambos casos? Ignorando la sintaxis del lenguaje, compilar C++ sería tan difícil como analizar un archivo de plantilla de sitio web (Django, Smarty, lo que sea) o Python?

Lo que estoy tratando de aludir a, es si estudio "compilar" o leer un libro sobre "compilación" ¿necesariamente voy a recoger las habilidades para analizar los lenguajes no compilados?

+0

compilar requiere un análisis, pero el análisis no requiere compilación. Hay una relación, pero no una relación is-a. – DwB

+0

Añadiendo otra pieza al rompecabezas, en asp.net podemos implementar los archivos de código fuente directamente sin compilación debido a [¡Compilación dinámica!] (Http://msdn.microsoft.com/en-us/library/ms366723.aspx) –

Respuesta

24

Respuesta corta: análisis sintáctico es no un subconjunto de la compilación.

Respuesta larga: generalmente, hay 3 pasos para la conversión de fuente a otro formato:

  1. Lexing, que convierte de alguna forma de entrada a una corriente token.
  2. Análisis, que convierte la secuencia de token en un árbol de sintaxis abstracta (AST).
  3. Compilación, que convierte el AST en un conjunto de instrucciones ejecutables (código nativo, código de bytes, etc.).

(Para idiomas muy simples, puede que ni siquiera necesite un analizador, es posible que pueda compilar la secuencia de token directamente, o su analizador podría generar código nativo directamente.)

así que empieza con una cadena de texto en este aspecto:

let x = 0 
while x < 10 
    print x 
    x := x + 1 

Un analizador léxico se va a convertir en una corriente razón, probablemente algo como esto:

[LET; String("x"); EQ; Int(0); NEWLINE; WHILE; String("x"); 
LT; VAL(10); ... ] 

El analizador convertirá el transmita en una estructura de datos más significativa, su árbol de sintaxis abstracto:

// AST definition 
type expr = 
    | Block of expr list 
    | Assign of string * expr 
    | While of expr * expr 
    | Call of string * expr list 
    | Add of expr * expr 
    | Var of string 
    | Int of int 

// AST instance created from token stream 
Block 
    [ 
     Assign("x", Int(10)); 
     While 
     (
      LessThan(Var("x"), Int(10)), 
      Block 
       [ 
        Call("print", [Var("x")]); 
        Assign("x", Add(Var("x"), Int(1))); 
       ] 
     ); 
    ] 

Una vez tiene un AST, puede hacer lo que quiera con él:

  • Convierta el AST en código nativo (compilación).
  • o puede interpretar el AST sobre la marcha, lo que puede hacer con un lenguaje de programación dinámico o un motor de plantillas.
  • o puede repetir el AST para crear un resaltador de sintaxis.
  • o puede recorrer el AST y enviar el código equivalente en otro idioma.
  • o puede buscar todas las instancias de Var("x") y reemplazarlas por Var("y") similar a una herramienta de refactorización de código).

Por lo tanto, si bien normalmente analiza la entrada antes de compilar, eso no es lo mismo que decir que el análisis es un subconjunto de la compilación.

+0

Wow. No esperaba una respuesta tan detallada. ¡Gracias! No sabía esto :) – mpen

5

No, el análisis y la compilación pueden ser completamente independientes.

  • Es posible que un analizador no esté emitiendo ningún código. Podría estar analizando algún objeto de datos (JSON, XML, lo que sea)
  • Un compilador puede no tener un código fuente para comenzar, podría presentarse con un árbol de sintaxis abstracta, ya analizado, y solo tiene que emitir el código correspondiente

mayoría de los compiladores incluyen un paso de análisis, pero no creo que sea necesariamente un "subconjunto" de la compilación, análisis y ciertamente no tiene por qué tener nada que ver con la compilación.

+1

Si está compilando el código fuente, entonces creo que el análisis es necesario. – jjnguy

+1

@jjnguy: Estoy de acuerdo. Sin embargo, yo diría que un compilador no siempre tiene el código fuente como su entrada. Un compilador JIT es un ejemplo. –

1

La compilación es en realidad más difícil que el análisis ya que es solo uno de los pasos preliminares en la compilación.

Después del análisis sintáctico, se genera una tabla de símbolos a partir de la cual se genera el código binario real.

Al interpretar idiomas como Javascript, las instrucciones se pueden ejecutar a medida que se analiza cada declaración.

http://en.wikipedia.org/wiki/Parsing

2

... "¿aprenderé habilidades para analizar los lenguajes no compilados?" Sí, lo harás, pero puedes estudiar el análisis por sí mismo.

Lo que encontrará, sin embargo, es mucha compilación (resolución de nombres, tipo de inferencia, coincidencia de patrones, compilación de instrucciones [pcode en lugar de código de máquina], ejecución de alto rendimiento, optimización para casos especiales) es útil en procesando lenguajes no compilados. Así que si tiene la intención de hacer algo más que literalmente parse, querrá estudiar la tecnología de compilación de todos modos.

Cuestiones relacionadas