compiladores (24/08/2014 13:56)- 4.1 - tema 4. gramáticas y análisis sintáctico parser lección...

52
Compiladores (06/26/22 11:01) - 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Upload: beltran-negron

Post on 10-Feb-2015

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.1 -

Tema 4. Gramáticas y Análisis SintácticoPARSER

Lección 11,12,13

Gramáticas Libres del Contexto

Page 2: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.2 -

Definición de Gramática

• Una gramática G es una tupla (T,N,I,P) donde:– T conjunto de símbolos terminales.

– N conjunto de símbolos no terminales.

– Isímbolo inicial.

– P conjunto de producciones.• Una producción es de la forma

(T|N)+ (T|N)*

• L={x T*| I x} es el lenguaje generado por la gramática G.

• es un paso de derivación si P

• representa la aplicación iterada de pasos de derivación.

• Notación:– Letras mayúsculas representan símbolos no

terminales.

– Letras minúsculas representan símbolos terminales.

*

*

Page 3: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.3 -

Ejemplo de Gramática

• La gramática G=(N,T,I,P) donde,– N={I,A,B}

– T={x,(,),+,-,*,/}

– P={II+I

II-I

IA

AA*A

AA/A

A(I)

Ax

}

• Secuencias generadas por G:– x, x*x

– x*x+x

– x*(x/x)

– x-x+x*x/x

Page 4: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.4 -

Pasos de Generación

• Secuencia: x*x+x

I I+I A+I A*A+I A*A+A

x*A+A x*x+A x*x+x

• Arbol sintáctico: I

I + I

A A

A * A x

x x

Page 5: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.5 -

Clasificación de las Gramáticas

• Regulares– Producciones:

• N• N

– Analizador: autómata finito determinista.

– Complejidad del análisis: lineal

• Libres del Contexto– Producciones:

• N

– Analizador: autómata con pila.

– Complejidad del análisis: lineal

• Dependientes del Contexto– Producciones:

• , donde (T|N)* y ||– Complejidad del análisis: exponencial

• Generales– Complejidad del análisis: no se puede con

memoria finita.

Page 6: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.6 -

Gramáticas de los Lenguajes de Programación

• Un lenguaje de programación se puede generar con una gramática dependiente del contexto.– Las declaraciones provocan la necesidad de

analizar el contexto.

– No utilizaremos estas gramáticas por la complejidad temporal de su analizador.

• Solución:– Utilizar una gramática libre del contexto

que tiene una complejidad lineal y dejar las características del lenguaje dependientes del contexto para el análisis semántico.

Page 7: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.7 -

Notación BNF Extendida

• Regla BNF:no terminal ::= expresión BNF

• Terminal:– Forma única: secuencia de caracteres que

lo forma.• Ej. if, +, then, for

– Forma variable: nombre que lo identifica.• Ej. identificador, numero, string, carácter, literal

• No Terminal: nombre entre < y >– Ej. <programa>, <lista de argumentos>,

<expresión>, <instrucción>• Secuencia vacía: • Operadores:

– Unión: | – Secuencia:

– Opcional: [ | – Repetición: {}= | | | |...

Page 8: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.8 -

Ejemplo

• Gramática simplificada de la declaración de una variable en C.

<dec>::=<tipo> <var> {, <var>};<tipo>::=[signed|unsigned] (int|char)<var>::={*} identificador {‘[‘ número ‘]’}

• Símbolos terminales: signed, unsigned, int, char, identificador, número, ‘[‘, ‘]’, ‘,’

• Símbolos no terminales: <dec>, <tipo>, <var>

• Símbolo inicial: <dec>• Secuencias válidas:

int a,**b[3][4];unsigned char *p;signed char str[100];

Page 9: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.9 -

Estructura Sintáctica de un Lenguaje y su Gramática

• Gramática de expresiones aritméticas de números y variables. Operaciones: +,-, *, /, - (cambio de signo), paréntesis.

<expresión>::=[-]<operando>

{(+|-|*|/) [-]<operando>}

<operando>::=‘(‘<expresión>‘)’ |

identificador | número• Secuencias valida: a+10*30/(-bd+2)• Arbol sintáctico generado para a+b*c

<expresión>

<operando> + <operando> * <operando>

identificador identificador identificador

• Este árbol sintáctico no representa el orden en que se han de realizar + y *.

Page 10: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.10 -

Prioridad de las Operaciones y el Arbol Sintáctico

• Nueva gramática:

<expresión>::=<término>{(+|-) <término>}<término>::=<factor>{(*|/) <factor>}<factor>::=[-](‘(‘ <expresión> ‘)’ |

identificador | número)• Arbol sintáctico generado para a+b*c

<expresión>

<término> + <término>

<factor> <factor> * <factor>

identificado identificador identificador

• En este árbol cada operador se agrupa con sus operandos y las operaciones más prioritarias están más abajo.

Page 11: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.11 -

Asociatividad y el Arbol Sintáctico

• Operación asociativa:

abc = abc) = (ab)c Ej. +, *

• Operación asociativa por la izquierda:

abc = (ab)c Ej. -, /

<operación>::=<operando>{<operando>}

<operación>

<operando> <operando> <operando>• Operación asociativa por la derecha:

abc = abc) Ej. = (asignación)

<operación>::=<operando>[<operación>]

<operación>

<operando> <operación>

<operando> <operando>

Page 12: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.12 -

Ambigüedad Gramatical

• Una gramática es ambigua si puede generar una secuencia de símbolos con dos árboles sintácticos diferentes.

• Ejemplo: <a> ::= <a> (+ | *) <a> | número

Secuencia: 1*2+3

Arboles sintácticos generados:

<a> <a>

<a> * <a> <a> + <a>

número <a> + <a> <a> * <a> número

número número número número

• Una gramática no se puede utilizar para la realización de un compilador por que no especifica la estructura sintáctica del lenguaje.

Page 13: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.13 -

Diagramas Sintácticos

No Terminal

Terminal

No TerminalDiagrama sintáctico de un

símbolo no terminal

Símbolo no terminal

Símbolo Terminal

Ejemplo: <sumas>::= número {+ número}

sumas

número

+número

Page 14: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.14 -

Ejemplo

• Diagramas sintácticos para expresiones aritméticas.

expresión

factor

término

término+

-

factor-

número

identificador

términofactor

factor*

/

)( expresión

Page 15: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.15 -

Paso de BNF a Diagramas Sintácticos

• A cada símbolo no terminal le corresponde una única regla.• Por cada regla se crea un único diagrama sintáctico.

<no terminal>::= expresión BNF

• Aplicar las siguientes reglas de conversión para pasar de la expresión BNF a su diagrama sintáctico.

Diagrama sintácticode la expresión BNF

No terminal

No Terminal

Terminal

<no terminal>

Terminal

Page 16: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.16 -

Paso de BNF a Diagramas Sintácticos

Diag. sint. de

n

Diag. sint. de

Diag. sint. de n

n

Diag. sint. de

Diag. sint. de

Diag. sint. de n

Page 17: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.17 -

Paso de BNF a Diagramas Sintácticos

Diag. sint. de

Diag. sint. de

Page 18: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.18 -

Ejemplo de Paso de BNF a Diagrama Sintáctico

• Gramática de instrucciones PASCAL simplificada:<instrucción>::=

if <condición> then <instrucción>[else <instrucción>]

Diagrama sintáctico deif <condición> then <instrucción> [else <instrucción>]

instrucción

Page 19: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.19 -

Ejemplo de Paso de BNF a Diagrama Sintáctico

instrucción

Diagrama sintáctico deif <condición> then <instrucción> [else <instrucción>]

Diag. if

Diag. then

Diag. <condición>

Diag. <instrucción>

Diag. [else <instrucción>]

Diag. if

Diag. <condición>

if

Diag. then then

condición

Diag. <instrucción> instrucción

Page 20: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.20 -

Ejemplo de Paso de BNF a Diagrama Sintáctico

Diag. [else <instrucción>]

Diag. sint. de else <instrucción>

Diag. else

Diag. <instrucción>

Diag. else <instrucción>

Diag. else else

Diag. <instrucción> instrucción

instrucciónif instruccióncondición then

else instrucción

Page 21: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.21 -

Gramática LL(1) Simple

• Un parser para gramáticas libres de contexto debe utilizar Backtracking

• Reducir las gramáticas utilizables a aquellas que permitan un reconocimiento determinista, en base al primer símbolo terminal de la secuencia.

• Una gramática LL(1) simple es aquella gramática libre de contexto sin reglas y para cada símbolo A N las alternativas para A empiezan con un símbolo terminal distinto.

A a11| a22 ... | ann , ai aj para i j y ai T para 1 i n

Page 22: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.22 -

Ejemplo de Gramáticas LL(1) Simple

• Ejemplo:S aS

S bA

A d

A ccA

• Reconocer:

aabccd

S

a S

a S

b A

c c A

d

Page 23: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.23 -

Conjunto de Primeros de una Secuencia de Terminales y no Terminales

• Primeros: concepto T+ Primero() = { x | x... y x T}

• Gramática LL(1) sin reglas es:

una gramática libre de contexto en la que para todas las reglas de la forma A 1| 2 ... | n , los conjuntos Primero(1), Primero(2),..., Primero(n) son disjuntos.

Primero(i) Primero(j) = i j

• Ejemplo:S ABePrimero(S) = {a,b,c,d}

S C

A dB Primero(A) = {a,c,d}

A aS

A c

B AS Primero(B) = {a,b,c,d}

B b

C b Primero(C) = {b}

*

Page 24: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.24 -

Gramáticas LL(1) con reglas

• Primeros: concepto (T|N)+ Primero() = { | ... y T}

• Siguientes: concepto N Siguiente() = { | S

Primero() y

S es el símbolo inicial y

T}

• Gramática LL(1) con reglas es una gramática libre de contexto en la que para cada par de reglas de la forma A y A se cumple que:

Primero(Siguiente(A)) Primero(Siguiente(A)) =

• O lo que es lo mismo, para todas las reglas de la forma A 1| 2 ... | n :

Primero(i) Primero(j) = i j

y si i , entonces

Primero(j) Siguiente() = j1..n

*

*

*

Page 25: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.25 -

Cálculo del Conjunto de Símbolos Anulables

• Un símbolo N es anulable si y solo si

• Cálculo del conjunto de Símbolos Anulables:

Anulables0={N| A }

Repetir

Anulablesn+1=Anulablesn

{BN| A12 ...m y

im iAnulablesn}

Hasta que Anulablesn==Anulablesn+1

*

Page 26: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.26 -

Ejemplo: Cálculo del Conjunto de Símbolos Anulables

• Gramática:IDIa

IvI

Af

B+I

CAB

DCA

• Aplicación del AlgoritmoAnulables0={A,B}

Anulables1={A,B,C}

Anulables2={A,B,C,D}

Page 27: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.27 -

Cálculo del Conjunto de Primerosde los no Terminales

ASi AAnulables entonces P0(A)={

sino P0(A)=

Repetir producción A de G

Pn+1(A)= Pn(A) PrimerosDe

Hasta que APn(A)== Pn+1(A)

PrimerosDe(}

PrimerosDe(a)={a} ,aT

PrimerosDe(A)= AN

si Pn(A) entonces

(Pn(A)-{})PrimerosDe()

sino Pn(A)

Page 28: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.28 -

Ejemplo de Cálculo de Primeros

• Gramática:ITFC

B+TB|-TB|Fx

C*FC|/FC|

Anulables={B,C}

• Cálculo del conjunto de primerosP(I) P(T) P(B) P(F) P(C)

{}{}

{} {x} {}2 {x} {} {x}

{}3 {x} {x} {} {x}

{}4 {x} {x} {} {x}

{}

Page 29: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.29 -

Cálculo del Conjunto de Siguientes

ASi A es el inicial entonces S0(A)={

sino S0(A)=

Repetir producción A B de G

Sn+1(B)= Sn(B) PrimerosDe

si PrimerosDe) entonces

Sn(A)

sino Hasta que ASn(A)== Sn+1(A)

Page 30: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.30 -

Ejemplo de Cálculo de Siguientes

• Gramática:ITFC

B+TB|-TB|Fx

C*FC|/FC|

• PrimerosP(I) P(T) P(B) P(F) P(C)

{x} {x} {} {x}{}

• Cálculo del conjunto de siguientesS(I) S(T) S(B) S(F) S(C)

{} {}{} {} {} {}{} {} {} {}{}{} {} {} {}

Page 31: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.31 -

Cálculo de Primeros y Siguientes en BNF

• Primeros:

P(n)=P()

P(n)=P()P()P(n)

P([])=P()P()

P({})=P()P()

P() en <A>::= ... es S(<A>)

• Siguientes

S( A ) PX : A

( )

• Problema:Estas definiciones generan recursividadesinfinitas que tras su estudio se pueden eliminar

Page 32: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.32 -

Analizador Sintáctico Dirigido por Tabla

Simbolo Terminal t;

Parser(n) {

if (predicción[t,n]==E) error();

p=Producciones[predicción[t,n]];

while (p!=NULL) {

if (p->symÎT)

if (t==p->sym) t=leer_símbolo();

else error();

else Parser(p->sym);

p=p->siguiente;

}

}

• Producciones[P]: tabla donde los símbolos de cada producción forman una lista encadenada

• predicción[T,N]: tabla que dado un símbolo no terminal y el terminal leído especifica que producción hay que aplicar.

sym siguiente

Page 33: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.33 -

Ejemplo: Analizador Sintáctico Dirigido por Tabla

• GramáticaITFC

B+TB|-TB|Fx

C*FC|/FC|

• Tabla de Producciones

1

2

3

4

5

T B

6

7

8

9

F C

+ T

- T

x

* F

/ F

B

B

C

C

Page 34: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.34 -

Ejemplo: Analizador Sintáctico Dirigido por Tabla

• Cálculo de la tabla de predicción– predicción[t,n]=E si no hay ninguna

producción de n cuyos primeros contengan t.

– predicción[t,n]=al número de producción de n tal que t pertenezca a sus primeros

• Tabla de predicción

+ - * / x

F

C

E E E E 1 E

E E E E 2 E

3

E

9

4 E E E 5

E E E 6 E

9 7 8 E 9

Terminales

No

term

inal

es

Page 35: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.35 -

Construcción de un Parser a Partir de los Diagramas Sintácticos (I)

• Programa principal

Símbolo SLA; /* Símbolo leído */

main() {

SLA=leer_símbolo();

Inicial();

if (SLA!=) Error();

}

Page 36: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.36 -

Construcción de un Parser a Partir de los Diagramas Sintácticos (II)

{

Parser[

Parser[

...

Parser[n

}

Diagrama sintácticodel No terminal

No terminal

Diag. sint. de

Diag. sint. de

Diag. sint. de n

noterminal ( ) {

Parser[Diagrama sintáctico]

};

Page 37: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.37 -

Construcción de un Parser a Partir de los Diagramas Sintácticos (III)

switch (SLA) {

case ( Primero()) : Parser[] break;

case (Primero()) : Parser[] break;

...

case (Primero(n)) : Parser[n] break;

default: error();

}

Diag. sint. de

Diag. sint. de

Diag. sint. de n

Page 38: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.38 -

Construcción de un Parser a Partir de los Diagramas Sintácticos (VI)

if (SLA == Terminal) leer_símbolo();

else error()

Diag. sint. de

No Terminal

Terminal

while (SLAPrimero() )

Parser[

Noterminal( );

Page 39: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.39 -

Construcción de un Parser a Partir de la Descripción BNF (I)

• Programa principal

Simbolo SLA; /* Simbolo leido */

main() {

SLA=leer_símbolo();

Inicial();

if (SLA!=) Error();

}

• <no terminal>::= expresión BNF

no_terminal ( ) {

Parser[expresión BNF]

};

Page 40: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.40 -

Construcción de un Parser a Partir de la Descripción BNF (II)

• Parser[n]

{

Parser[

Parser[

...

Parser[n

}

• Parser[n]

switch (SLA) {

case ( Primero()) : Parser[] break;

case (Primero()) : Parser[] break;

...

case (Primero(n)) : Parser[n] break;

default: error();

}

Page 41: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.41 -

Construcción de un Parser a partir de la descripción BNF (III)

• Parser[{}]

while (SLAPrimero() )

Parser[

• Parser[<no terminal>]

Noterminal( );

• Parser[ Terminal]

if (SLA== Terminal) leer_símbolo();

else error();

Page 42: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.42 -

Tratamiento de los Errores en Análisis Descendente

• Tratamiento de errores:– Detectar sólo el primero

– Detectar el máximo (razonable)• Sincronizar después del error

• Prever errores típicos y cambiar la gramática a otra que los acepte dando warnings.

• Corregir el error: Decidir cual ha sido el error y reconstruir el programa fuente eliminando dicho error

• Consideraciones:– No se pueden solucionar correctamente

todos los casos.

– Hay que considerar la psicología del programador.

– Como mínimo tratar correctamente los errores más comunes.

– Minimizar:• Error no detectados

• Falsas alarmas

Page 43: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.43 -

Sincronización Después de Error

• Después de un error se leen símbolos hasta encontrar uno que pertenezca al conjunto de sincronización– Saltar símbolos hasta encontrar uno

correcto y continuar (se supone que era código adicional erróneo)

– Saltar símbolos hasta encontrar uno correcto como siguiente del símbolo no terminal que se está analizando y retornar para continuar con ese símbolo siguiente (se supone que falta un trozo y se continua en un nivel superior)

• El conjunto de sincronización se puede formar a partir del cálculo de los símbolos que pueden seguir a un momento dado del análisis sintáctico.– Acumular los símbolos de estructuras

mayores en el conjunto de sincronización.

Page 44: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.44 -

Corrección de Errores

• Después de un error añadir o quitar símbolos hasta poder continuar el análisis sintáctico.– Añadir: ir hacia delante dentro de la

gramática.

– Quitar: ir hacia atrás dentro de la gramática.

• En el caso que varias correcciones sean válidas se seleccionará la de menor peso.

• Ponderación de la secuencia:– A cada inserción de un símbolo se le asocia

un peso según lo fácil que sea dejarselo.

– A cada eliminación de un símbolo se le asocia un peso según lo fácil que sea ponerlo de más.

Page 45: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.45 -

Tema 4. Análisis Sintáctico Ascendente (Bottom-Up)

Lecciones 17,18

Page 46: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.46 -

Análisis Sintáctico Ascendente (Bottom-Up)

• Un analizador sintáctico ascendente construye el árbol sintáctico de abajo a arriba, por lo tanto– parte de los símbolos terminales que agrupan

o reducen en símbolos no terminales

• Ejemplo– Gramática

II+I | I-IA

AA*A | A/A(I) |num

– Expresión 1+2*3– Derivación: I => I+I => num+I => num+A =>

num+A*A => num+num*A => num+num*num

– La reducción de símbolos supone ir de derecha a izquierda en los pasos de derivación

1 + 2 * 3

num+num*num

A

I

Page 47: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.47 -

Gramáticas LR(k)

• El conjunto de las gramáticas LR(k) es el conjunto de las gramáticas libres del contexto no ambiguas– El conjunto de las gramáticas LR(k)

contiene las gramáticas LL(k).

– k es el número de símbolos que hay que considerar hacia delante antes de que el analizador sintáctico realice una acción.

– Solo se consideran las gramáticas LR(0) y LR(1) ya que para k>1 el análisis tiende ha ser demasiado costoso.

• Familias de gramáticas

demasiado costoso LR(k)

LR(1)

LALR(1)

SLR(1) LL(1)

demasiado simple LR(0)

equivalentespor transformación

Page 48: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.48 -

Bases del Análisis Sintáctico con Gramáticas LR(k) (I)

• Derivación de más a la derecha (rightmost derivation) de una secuencia de símbolos X esI => 1 => 2 => 1 =>...=> m = X

donde para todo i [1..m-1]

Bt => t, i= Bt, BP, t T*

• Como ha de actuar el analizador de una gramática LR(k)– es una secuencia de símbolos terminales

y no terminales donde se han realizado todas las reducciones posibles.

– es la nueva reducción que podemos realizar y la sustituimos por el símbolo no terminal B que la genera

– t es el resto de símbolos de la secuencia que faltan por procesar.

– La decisión de que reducción se ha de realizar se toma en base a y a los k primeros símbolos de t si la gramática es LR(k).

Page 49: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.49 -

Bases del Análisis Sintáctico con Gramáticas LR(k) (II)

• Knuth demostró que se pueden reconocer los prefijos válidos mediante un autómata finito.– hay que considerar que el número de

prefijos puede ser infinito.

– Una vez reconocido el prefijo y leídos los k primeros símbolos de t hay una única reducción válida a aplicar.

• Como es un parser LR– Es una máquina con

• como entrada la secuencia a analizar

• una pila

• un mecanismo de control finito formado por:

– estados de lectura• Lee un símbolo, lo pone en la pila y salta a

un nuevo estado

– estados reductores • sustituyen la secuencia que encuentra en

la pila por B.

– un estado inicial

no es necesario

Page 50: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.50 -

Gramática LR(0)

• GramáticaSE#

ET | E+T | E - T

Ti | (E)

0

1 6

8

7

9

10 1142

3

5

Estado reductor

Estado de lectura

E

#

+T

+T

-

)E

(

(

i

T

T

(

(i

i

i-

Ti

T(E)

EE+T

ET

EE-T

SE#

Page 51: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.51 -

Trazado

• Secuencia: i-(i+i)#

Paso Pila Entrada Prefijo Grupo

0 0 i-(i+i)#

1 0 i3 -(i+i)# i i

2 0 T2 -(i+i)# T T

3 0 E1 -(i+i)# E

4 0 E1 -7 (i+i)# E-

5 0 E1 -7 (4 i+i)# E-(

6 0 E1 -7 (4 i3 +i)# E-(i i

7 0 E1 -7 (4 T2 +i)# E-(T T

8 0 E1 -7 (4 E10 +i)# E-(E

9 0 E1 -7 (4 E10 +6 i)# E-(E+

10 0 E1 -7 (4 E10 +6 i3 )# E-(E+i i

11 0 E1 -7 (4 E10 +6 T8 )# E-(E+T E+T

12 0 E1 -7 (4 E10 )# E-(E E+T

13 0 E1 -7 (4 E10 )11 # E-(E) (E)

14 0 E1 -7 T9 # E-T E-T

15 0 E1 # E

16 0 E1 #5 E#

17 0 Aceptado

Page 52: Compiladores (24/08/2014 13:56)- 4.1 - Tema 4. Gramáticas y Análisis Sintáctico PARSER Lección 11,12,13 Gramáticas Libres del Contexto

Compiladores (04/10/23 17:12) - 4.52 -

Gramáticas no LR(0)

• Gramática LR(0)SE#

ET | E+T | E - T

Ti | (E)

• Gramática No LR(0)S E#

E E - T

E T

T F ^ T

T F

F (E)

F i

• Gramáticas SLR(1), LR(1), LALR(1):– Se decide cual es el estado siguiente de una

reducción a partir del estado de la pila y el símbolo leído hacia delante

– Los tres tipos de gramáticas se diferencian en el tratamiento del símbolo leído hacia delante.

Para aplicar una de estas dos reducciones hay que leer el siguiente símbolo