Compilador Diseño - Sintaxis Anã¡lisis



Sintaxis anã¡lisis o anã¡lisis es la segunda fase de un compilador. En este capã­tulo, vamos a aprender los conceptos bã¡sicos utilizados en la construcciã³n de un analizador.

Hemos visto que un analizador lã©xico puede identificar los tokens con la ayuda de expresiones regulares y reglas de patrones. Pero un analizador lã©xico no puede comprobar la sintaxis de una frase debido a las limitaciones de las expresiones regulares. Las expresiones regulares no puede comprobar equilibrio fichas, como entre parã©ntesis. Por lo tanto, esta fase utiliza gramã¡tica libre de contexto (CFG), que estã¡ reconocida por empuje de autã³matas.

CFG, por otro lado, es un superconjunto de Gramã¡tica Regular, como se ilustra a continuaciã³n:

Relación de la CFG y gramática regular

Esto implica que cada Gramã¡tica Regular es tambiã©n libres de contexto, pero hay algunos problemas, que estã¡n mã¡s allã¡ del alcance de Gramã¡tica Regular. CFG es una herramienta ãºtil para describir la sintaxis de los lenguajes de programaciã³n.

Gramã¡tica Context-Free

En esta secciã³n, vamos a ver en primer lugar la definiciã³n de gramã¡tica libre de contexto e introducir tã©rminos utilizados en el anã¡lisis.

UNA gramã¡tica libre de contexto tiene cuatro componentes:

  • Un conjunto de no-terminales (V). No terminales son variables sintã¡cticas que denotan conjuntos de cadenas. La no-terminales definir conjuntos de cadenas que ayudan a definir el lenguaje generado por la gramã¡tica.

  • Un conjunto de sã­mbolos, conocido como sã­mbolos terminales (Σ). Los terminales son los sã­mbolos bã¡sicos de las cadenas que se forman.

  • Un conjunto de producciones (P). Las producciones de una gramã¡tica especifica la forma en la que los terminales y no terminales se pueden combinar para formar cadenas. Cada producciã³n consiste en un no-terminal llamado el lado izquierdo de la producciã³n, una flecha, y una secuencia de las fichas y/o en los terminales, llamado el lado derecho de la producciã³n.

  • Uno de los terminales es designado como el sã­mbolo de arranque (S); desde donde comienza la producciã³n.

Las cadenas se deriva del sã­mbolo de arranque varias veces por sustituciã³n de un no-terminal (en un principio, el sã­mbolo de arranque) por el lado derecho de una producciã³n, para que no sean de terminal server.

Ejemplo

Tenemos el problema de palindromo idioma, que no se puede describir por medio de expresiones regulares. Es decir, L = { w | w = wR } no es un idioma habitual. Pero no se puede describir por medio de CFG, tal como se ilustra a continuaciã³n:

G = ( V, Σ, P, S )

Donde:

V = { Q, Z, N }
Σ = { 0, 1 }
P = { Q → Z | Q → N | Q → ℇ | Z → 0Q0 | N → 1Q1 }
S = { Q }

Esta gramã¡tica describe palindromo idioma, tales como: 1001, 11100111, 1010101, 00100, 11111, etc.

Analizadores Sintaxis

Un analizador de sintaxis tiene la entrada de un analizador lã©xico en forma de token arroyos. El analizador analiza el cã³digo fuente (token) contra las normas de producciã³n para detectar los errores en el cã³digo. El resultado de esta fase es analizar un ã¡rbol.

Sintaxis Analizador

Esta manera, el analizador realiza dos tareas, es decir, analizar el cã³digo y busca los errores y generar un anã¡lisis ã¡rbol como la salida de la etapa.

Los analizadores se espera para analizar todo el cã³digo aunque algunos errores en el programa. Error en la recuperaciã³n los Analizadores utilizan estrategias que vamos a aprender mã¡s adelante en este capã­tulo.

Derivaciã³n

Una derivaciã³n es bã¡sicamente una secuencia de reglas de producciã³n, con el fin de obtener la cadena de entrada. Durante el anã¡lisis, tomamos dos decisiones para algunos el oracional formulario de entrada:

  • Decidir el no terminal que se va a sustituir.
  • Decidir sobre la producciã³n, por lo cual, el no-terminal serã¡ reemplazado.

Para decidir que no terminal que se va a reemplazar por producciã³n, no puede tener dos opciones.

Mã¡s a la izquierda de derivaciã³n

Si el formulario el oracional de una entrada es capturado y se cambia de izquierda a derecha, se llama mã¡s a la izquierda de derivaciã³n. El oracional La forma derivada por el de la izquierda se llama derivaciã³n de la izquierda forma el oracional.

Mã¡s a la derecha de derivaciã³n

Si podemos explorar y cambiar la entrada con las normas de producciã³n, de derecha a izquierda, es lo que se conoce como derivaciã³n mã¡s a la derecha. El oracional La forma derivada de la derivaciã³n mã¡s a la derecha se denomina derecho-el oracional.

Ejemplo

Normas de producciã³n:

E → E + E
E → E * E
E → id 

Cadena de entrada: id + id * id.

Mã¡s a la izquierda es derivaciã³n:

E → E * E
E → E + E * E
E → id + E * E
E → id + id * E
E → id + id * id

Tenga en cuenta que el lado izquierdo de la no-terminal siempre se procesa primero.

El derecho de la derivaciã³n es:

E → E + E
E → E + E * E
E → E + E * id
E → E + id * id
E → id + id * id

Parse Tree

Un anã¡lisis ã¡rbol es una representaciã³n grã¡fica de una derivaciã³n. Es conveniente para ver cã³mo las cadenas se deriva del sã­mbolo de inicio. El sã­mbolo de arranque de la derivaciã³n se convierte en la raã­z de la parse tree. Veamos esto con un ejemplo de este tema.

Seguimos a la izquierda de la derivaciã³n de a + b * c

Mã¡s a la izquierda es derivaciã³n:

E → E * E
E → E + E * E
E → id + E * E
E → id + id * E
E → id + id * id

Paso 1:

E → E * E Construcción Parse Árbol

Paso 2:

E → E + E * E Construcción Parse Árbol

Paso 3:

E → id + E * E Construcción Parse Árbol

Paso 4:

E → id + id * E Construcción Parse Árbol

Paso 5:

E → id + id * id. Construcción Parse Árbol

En un anã¡lisis ã¡rbol:

  • Todos los nodos hoja son terminales.
  • Todos los interiores son los nodos no terminales.
  • En fin travesã­a da original cadena de entrada.

ãrbol representa un anã¡lisis asociatividad y precedencia de los operadores. El mã¡s profundo sub-ã¡rbol es atravesado en primer lugar, por lo tanto el operador en ese sub-ã¡rbol obtiene prioridad sobre el operador que se encuentra en los nodos principales.

Ambigã¼edad

Una gramã¡tica G se dice que es ambigua si tiene mã¡s de un ã¡rbol analizar (a la izquierda o a la derecha) por lo menos una cadena.

Ejemplo

E → E + E
E → E – E
E → id

Para la cadena id + id - id, la gramã¡tica genera dos analizar los ã¡rboles:

Construcción Parse Árbol

El lenguaje generado por una gramã¡tica es ambigua dice que es inherentemente ambiguo. Ambigã¼edad de gramã¡tica no es bueno para un compilador construcciã³n. Ningãºn mã©todo puede detectar y eliminar la ambigã¼edad automã¡ticamente, pero se puede extraer por cualquier re-escritura toda la gramã¡tica sin ambigã¼edad, o por establecer y asociatividad y restricciones de precedencia.

Asociatividad

Si un operando tiene operadores de ambos lados, el lado en el que el operador aprovecha esta operando es decidido por la asociatividad de los operadores. Si la operaciã³n es asociativos por la izquierda, a continuaciã³n, el operando se tomarã¡n por la izquierda operador, o si la operaciã³n es asociativa, el operando derecho tendrã¡ el operando.

Ejemplo

Las operaciones tales como la adiciã³n, sustracciã³n, multiplicaciã³n, divisiã³n y asociativo. Si la expresiã³n contiene:

id op id op id

ã‰sta serã¡ evaluada como:

(id op id) op id

Por ejemplo, (id + id) + id

Operaciones de exponenciaciã³n como son derecho asociativo, es decir, el orden de evaluaciã³n en la misma expresiã³n serã¡:

id op (id op id)

Por ejemplo, id ^ (id ^ id)

Prioridad

Si dos operadores diferentes comparten un operando, la precedencia de los operadores decide que tendrã¡ el operando. Es decir, 2+3*4 puede tener dos anã¡lisis diferentes ã¡rboles, uno correspondiente a (2+3) * 4 y otro correspondiente a 2+(3 * 4). De preferencia entre los operadores, este problema se puede retirar fã¡cilmente. Como en el ejemplo anterior, desde el punto de vista matemã¡tico * (multiplicaciã³n) tiene precedencia sobre + (suma), de forma que la expresiã³n 2+3 * 4 siempre serã¡ interpretada en el sentido de:

2 + (3 * 4)

Estos mã©todos disminuyen el riesgo de ambigã¼edad en el lenguaje o su gramã¡tica.

Recursiã³n izquierda

Una gramã¡tica se convierte izquierda-recursive si tiene cualquier no terminal 'A' cuya derivaciã³n contiene 'A' sã­ mismo como el sã­mbolo de la izquierda. De izquierda gramã¡tica recursiva es considerada una situaciã³n problemã¡tica para los analizadores. De arriba a abajo los analizadores iniciar el anã¡lisis desde el principio, y que en sã­ mismo no es terminal. Por lo tanto, cuando el analizador encuentra el mismo no-terminal en su derivaciã³n, se vuelve difã­cil de juzgar cuando para detener el anã¡lisis de la izquierda no terminales y que entra en un bucle infinito.

Ejemplo:

(1) A => Aα | β
(2) S => Aα | β 
    A => Sd 

(1) es un ejemplo de recursividad inmediatamente a la izquierda, donde A es un sã­mbolo no terminal y α representa una cadena de terminales.

(2) es un ejemplo de recursividad indirecta a la izquierda.

izquierda recursividad

Un analizador de arriba abajo, en primer lugar analizar el A, que a su vez producirã¡ una cadena compuesta por el mismo y el analizador puede entrar en un bucle indefinidamente.

Extracciã³n de recursiã³n izquierda

Una forma de eliminar la recursividad izquierda para usar el siguiente mã©todo:

La producciã³n

A => Aα | β

Se convierte en producciones

A => βA’
A => αA’ | ε

Esto no tiene impacto en el las cadenas derivadas de la gramã¡tica, sino que elimina inmediatamente a la izquierda recursividad.

Segundo mã©todo consiste en utilizar el siguiente algoritmo, que deben eliminar todas directas e indirectas recursividad izquierda.

START
Arrange non-terminals in some order like A1, A2, A3,…, An
   for each i from 1 to n
      {
      for each j from 1 to i-1
         {
         replace each production of form Ai⟹Ajðœ¸
         with Ai ⟹ δ1𜸠 | δ2𜸠| δ3𜸠|…| 𜸠
         where Aj ⟹ δ1 | δ2|…| δn  are current Aj productions
         }
      }
   eliminate immediate left-recursion
END

Ejemplo

La producciã³n

S => Aα | β 
A => Sd

Despuã©s de aplicar el algoritmo antes descrito, debe convertirse en

S => Aα | β 
A => Aαd | βd

Y, a continuaciã³n, retirar inmediatamente a la izquierda recursividad con la primera tã©cnica.

A => βdA’
A => αdA’ | ε

Ahora bien, ninguna de la producciã³n directa o indirecta izquierda recursividad.

Factoring izquierda

Si hay mã¡s de una gramã¡tica normas de producciã³n tiene un prefijo comãºn cadena, entonces el top-down analizador no puede hacer una elecciã³n de de la producciã³n debe tener para analizar la cadena de la mano.

Ejemplo

Si un top-down analizador encuentra una producciã³n como

A ⟹ αβ | α𜸠| …

A continuaciã³n, no puede determinar quã© producciã³n a seguir para analizar la cadena de ambas producciones estã¡n empezando desde el mismo terminal (o no-terminal). Para eliminar esta confusiã³n, se utiliza una tã©cnica llamada izquierda factoring.

Factoring Izquierda transforma la gramã¡tica para que sea ãºtil para los analizadores de arriba a abajo. En esta tã©cnica, se hace una producciã³n para cada uno de los prefijos y el resto de la derivaciã³n de nuevas producciones.

Ejemplo

Las producciones se puede escribir como

A => αA’
A’=> β | 𜸠| … 

Ahora el analizador sã³lo tiene una producciã³n por prefijo, lo que facilita a la hora de tomar las decisiones.

En primer lugar y el seguimiento conjuntos

Una parte importante del analizador construcciã³n tabla es para crear la primera y el seguimiento. Estos juegos pueden proporcionar la posiciã³n real de cualquier terminal de la derivaciã³n. Esto se hace para crear el anã¡lisis tabla donde la decisiã³n de reemplazar T[A, t] = α con parte de la producciã³n.

Primer Juego

Este juego es creado para saber quã© sã­mbolo terminal se deriva de la primera posiciã³n por un no-terminal. Por ejemplo,

α → t β

Se deriva que es α t (terminal) en la primera posiciã³n. Por lo tanto, t ∈ PRIMERO(α).

Algoritmo para calcular primero

Fã­jese en la definiciã³n de PRIMERA(α) establecido:

  • Si α es una terminal, luego en la primera(α) = { α }.
  • Si α es un no-terminal y α → ℇ es una producciã³n, entonces PRIMERO(α) = { ℇ }.
  • Si α es un no-terminal y α → ðœ¸1 ðœ¸2 ðœ¸3 … ðœ¸n cualquier PRIMERA(ðœ¸)contiene a su vez, t. t es de primera(α).

En primer lugar se puede considerar como:

Primera Fórmula

Sigue

Del mismo modo, podemos calcular quã© sã­mbolo terminal sigue inmediatamente un no-terminal α en normas de producciã³n. No tenemos en cuenta lo que el no-terminal puede producir pero en lugar de eso, vemos lo que serã­a el siguiente sã­mbolo terminal que sigue la producciã³n de un no-terminal.

Algoritmo para calcular sigue:

  • Si α es un sã­mbolo de inicio y, a continuaciã³n, siga() = $

  • Si α es un no-terminal y tiene una producciã³n α → AB, luego la primera(B) es en el seguimiento(A), salvo ℇ.

  • Si α es un no-terminal y tiene una producciã³n α → AB, donde B ℇ, a continuaciã³n, siga(A) estã¡ en el seguimiento(α).

Seguimiento conjunto puede considerarse como: SEGUIMIENTO(α) = { t | S *αt*}

Analizadores de Sintaxis Limitaciones

Analizadores Sintaxis recibir sus aportes, en forma de fichas, de analizadores lã©xicos. Analizadores lã©xicos son responsables de la validez de un token suministrado por el analizador sintaxis. Sintaxis analizadores tienen los siguientes inconvenientes:

  • No se puede determinar si una seã±al es vã¡lida,
  • No puede determinar si un token es declarado antes de que se utilice,
  • No puede determinar si un token se inicia antes de que se utilice,
  • No se puede determinar si una operaciã³n realizada en un tipo de token es vã¡lida o no.

Estas tareas son realizadas por el analizador semã¡ntico, que estudiaremos en anã¡lisis semã¡ntico.

Advertisements