procesadores de lenguajes ii

239
Procesadores de Lenguajes Ingeniería Técnica superior de Ingeniería Informá8ca Departamento de Lenguajes y Sistemas informá6cos Javier Vélez Reyes [email protected] Departamento de Lenguajes Y Sistemas Informá6cos UNED Universidad Nacional de Educación a Distancia Grado en Ingeniería Informática

Upload: javier-velez-reyes

Post on 21-Mar-2017

96 views

Category:

Education


16 download

TRANSCRIPT

ProcesadoresdeLenguajesIngenieríaTécnicasuperiordeIngenieríaInformá8ca

DepartamentodeLenguajesySistemasinformá6cos

JavierVé[email protected]

DepartamentodeLenguajesYSistemasInformá6cosUNED

UniversidadNacionaldeEducaciónaDistancia

Grado en Ingeniería Informática

Procesad

oresdeLengua

jes

IngenieríaTécnicasu

perio

rdeIngenieríaIn

form

á8ca

Departam

entodeLenguajesy

Sistem

asinform

á6cos

JavierVé[email protected]á?cosUNED

ParteIPresentación

ProcesadoresdeLenguajesIngenieríaTécnicasuperiordeIngenieríaInformá8ca

DepartamentodeLenguajesySistemasinformá6cos

JavierVé[email protected]

DepartamentodeLenguajesYSistemasInformáAcosUNED

1IntroducciónElprocesodecompilación

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 2

Obje6vosGenerales

Obje8vosGenerales

›  Poner en contexto y justificar la relevancia de la compilación

›  Aprender la diferencia entre compiladores y traductores

›  Entender la diferencia entre compiladores e interpretes

›  Apreciar el contexto en el que trabaja un compilador

›  Apreciar cómo interactúan sus partes

›  Entender la responsabilidad de cada una de ellas

›  Analizar diferentes configuraciones alternativas

›  Conocer el proceso completo de compilación

›  Entender la responsabilidad de cada una de sus fases

›  Obtener una visión general de las técnicas empleadas en cada una

›  Aprender los principales artefactos que dan soporte a la compilación

›  Discutir sobre la portabilidad de compiladores

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 3

Índice

Índice

›  Introducción

›  Traductores y compiladores

›  Compiladores e interpretes

›  Contexto de compilación

›  Proceso de compilación

›  Fases de compilación

›  Etapas de compilación

›  Artefactos de compilación

›  Análisis de compiladores

›  Representación de compiladores

›  Tipos de compiladores

›  Portabilidad de compiladores

›  Práctica

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 4

Introducción

EsfuerzodeabstracciónLa historia de la programación puede describirse como un constante esfuerzo por acercar el lenguaje ejecutable de las arquitecturas hardware a un lenguaje más próximo al humano a través de sucesivos pasos de abstracción

I.ArquitecturasVonNeumann›  Representación del programa como instrucciones en memoria

›  La unidad de control va leyéndolo secuencialmente

›  Cada instrucción tiene un código de operación y unos operandos

›  Operaciones aritmético lógicas, comparativas, de salto, de E/S,…

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX#3MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

111001100001011010101001110000111100001111011100

Código de operación

Operando 1

Operando 2

* En esta descripción se han omitido muchos paradigmas

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 5

Introducción

EsfuerzodeabstracciónLa historia de la programación puede describirse como un constante esfuerzo por acercar el lenguaje ejecutable de las arquitecturas hardware a un lenguaje más próximo al humano a través de sucesivos pasos de abstracción

II.Paradigmaensamblador›  Los códigos de operación se sustituyen por acrónimos

›  Los operandos se sustituyen por registros y referencias a memoria

›  El juego de instrucciones sigue siendo el mismo

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX[1305]MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

MOVEAX#2MOVEBX[1305]MULCXAXBX

Acrónimo de operación

Operando 1 de tipo registro

Operando 2 de tipo literal numérico

Operando 2 referencia a memoria

* En esta descripción se han omitido muchos paradigmas

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 6

Introducción

EsfuerzodeabstracciónLa historia de la programación puede describirse como un constante esfuerzo por acercar el lenguaje ejecutable de las arquitecturas hardware a un lenguaje más próximo al humano a través de sucesivos pasos de abstracción

III.Paradigmaestructuradoimpera8vo›  Flujo de ejecución secuencial

›  Metáfora de variables y operación de asignación

›  Tipificación de los datos

›  Estructuras de control iterativas y condicionales (no de salto)

›  Subrutinas para modularizar los programas

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX#3MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

a

b c

b(x,y);C(x,y);

d e f g

if(x>y)f(x);elseg(y);

while(x=y){d(x,y);e(x,y);}

* En esta descripción se han omitido muchos paradigmas

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 7

Introducción

EsfuerzodeabstracciónLa historia de la programación puede describirse como un constante esfuerzo por acercar el lenguaje ejecutable de las arquitecturas hardware a un lenguaje más próximo al humano a través de sucesivos pasos de abstracción

IV.Paradigmaconcurrente›  Varios flujos de ejecución secuencial asociados a procesos

›  Es necesario cuidar el acceso concurrente a recursos

›  Mecanismos de exclusión mutua y de sincronización por condición

›  Para cada proceso el algoritmo sigue siendo imperativo

›  Existen lenguajes concurrentes funcionales

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX#3MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

xlectorlectorlector

Leer x

lectorlectorescritor

Escribir x

* En esta descripción se han omitido muchos paradigmas

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 8

Introducción

EsfuerzodeabstracciónLa historia de la programación puede describirse como un constante esfuerzo por acercar el lenguaje ejecutable de las arquitecturas hardware a un lenguaje más próximo al humano a través de sucesivos pasos de abstracción

V.Paradigmafuncionaldeclara8vo›  Únicamente declaración de funciones

›  El resultado de una expresión depende sólo de sus sub-expresiones

›  No hay efectos colaterales en la evaluación funcional

›  No existe asignación ni estructuras de control

›  Se da soporte a la definición recursiva de funciones

›  Las funciones se usan como datos (orden superior, currificación,…)

›  Operaciones map / reduce

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX#3MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

funinvertir(l)=[]->[]|(p:resto)->invertir(resto):p

* En esta descripción se han omitido muchos paradigmas

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 9

Introducción

EsfuerzodeabstracciónLa historia de la programación puede describirse como un constante esfuerzo por acercar el lenguaje ejecutable de las arquitecturas hardware a un lenguaje más próximo al humano a través de sucesivos pasos de abstracción

VI.Paradigmadeorientaciónaobjetos›  Las operaciones acompañan a las estructuras de datos

›  Clases con bajo acoplamiento y fuerte cohesión

›  El algoritmo se encuentra distribuido en la colaboración entre objetos

›  Herencia, polimorfismo, ligadura dinámica y genericidad

›  Los objetos se gestionan en el heap

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX#3MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

for(iin[2..n])for(jin[0..n-1])if(c.mayor(a[j],a[j+1]))intercambiar(a[j],a[j+1]) * En esta descripción se han omitido muchos paradigmas

Lista

-ordenar()

Comparador

-mayor(x,y)

ComparadorA

ComparadorB

usa

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 10

Traductoresycompiladores

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX#3MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

¿Quéesuncompilador?Para dar soporte a este proceso de abstracción es necesario idear programas capaces de traducir las expresiones abstractas en secuencias de instrucciones máquina interpretables por un ordenados

DefiniciónUn compilador es un programa que lee un programa escrito en lenguaje fuente, y lo traduce a un lenguaje objeto de bajo nivel. Además generará una lista de los posibles errores que tenga el programa fuente

CompiladorLenguaje fuente

Lenguaje objeto

Compilado

r

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 11

Traductoresycompiladores

111001100001011010101001110000111100001111011100

1945

MOVEAX#2MOVEBX#3MULCXAXBX

1950

Fact=1;Fori:=0to10fact:=fact*i;

1968

Wait(q);i:=fact(x);Signal(q);

1970

funmul(x,y)=x*yfunfact(n,m)=0->1|m(n,fact(n-1,m))

1990

bajo nivel

alto nivel

+ n

ivel

de

abst

racc

ión

ClassPunto{intx,y;intmodulo(){...}}

1995

¿Quéesuntraductor?Cuando lo que se pretende es cambiar la expresión sintáctica de un programa de un lenguaje de alto nivel a otro no hablamos de compilador sino de traductor

DefiniciónUn traductores un programa que lee un programa escrito en lenguaje fuente de alto nivel, y lo traduce a un lenguaje objeto también de alto nivel.

TraductorLenguaje fuente

Lenguaje objeto

fact=1;for(inti=0;i<=10;i++)fact*=i;

Pascal C traductor

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 12

Traductoresycompiladores

Traductoresycompiladores

I.Traductor

II.Compilador

Un compilador es un programa que lee un programa escrito en lenguaje fuente, y lo traduce a un lenguaje objeto de bajo nivel. Además generará una lista de los posibles errores que tenga el programa fuente

Un traductores un programa que lee un programa escrito en lenguaje fuente de alto nivel, y lo traduce a un lenguaje objeto también de alto nivel.

CompiladorLenguaje fuente

Lenguaje objeto

TraductorLenguaje fuente

Lenguaje objeto

}

Foco de atención principal de la asignatura

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 13

Compiladoreseinterpretes

Compiladoreseinterpretes

I.Compilador

Un compilador es un artefacto software capaz de generar un programa ejecutable a partir de un programa escrito en un lenguaje de alto nivel

II.Interprete

Un interprete es un artefacto software capaz de ir interpretando secuencialmente la colección de instrucciones de un programa escrito en un lenguaje de alto nivel para ejecutarlas

›  Se obtiene un fichero ejecutable

›  El proceso de compilación se realiza sólo una vez

›  El proceso de compilación es más lento

›  Mayor consumo de memoria

›  Mayor cantidad de detalles de errores de compilación

›  Mayor velocidad de ejecución del programa ejecutable

›  Los errores en ejecución se minimizan

›  No se obtiene un fichero ejecutable

›  El proceso de interpretación se realiza cada vez

›  El proceso de interpretación es más rápido

›  Menor consumo de memoria

›  Menor cantidad de detalles de errores de compilación

›  Menor velocidad de ejecución del programa ejecutable

›  Los errores en ejecución son mayores

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 14

Contextodecompilación

I.Precompilador

Algunos compiladores incluyen precompiladores capaces de hacer un tratamiento preliminar del fichero fuente para prepararlo para el proceso de la compilación. Esta herramienta suele eliminar comentarios, sustituir constantes simbólicas por sus valores literales, o extender en el código fuente las macros definidas

II.Compilador

El compilador es el programa encargado de realizar el proceso de traducción del programa fuente para expresarlo en términos de una secuencia de instrucciones de código máquina interpretables por un ordenador

}

Foco de atención principal de la asignatura

III.Enlazadoromontador

El producto resultante del compilador no es un fichero directamente ejecutable en la arquitectura. Muchas funciones, invocadas desde el programa fuente, y cuyo código se encuentra programado y compilado en otro fichero deben ser incorporadas al fichero resultante de la compilación para que sea autónomo. De esto se encarga el montador

Elementosdelcontextodelacompilación

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 15

Contextodecompilación

Elementosdelcontextodelacompilación

IV.Enlazadordinámico

Con el ánimo de que los programas finales no sean muy pesados, muchas funciones externas no se incluyen en el ejecutable final sino que son enlazadas dinámica y automáticamente por el sistema operativo, que se encarga de gestionarlas. Como consecuencia los ejecutables son más pequeños pero establecen dependencias con recursos que han de estar presentes en el sistema operativo

V.Depurador

Los errores producidos en tiempo de compilación son reportados por el compilador para su corrección. Sin embargo los ocurridos en tiempo de ejecución pueden ser más difíciles de detectar. Es necesario hacer ejecuciones paso a paso para comprobar el estado que va tomando cada variable del programa. El depurador ayuda a realizar este tipo de trazas

VI.Ensamblador

A veces los compiladores no generan programas directamente ejecutables en código máquina sino ficheros que corresponden a la expresión en ensamblador del código fuente. Esto puede ser tremendamente útil - aunque en la actualidad no frecuente – para permitir al programador optimizar los resultados generados por el compilador

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 16

Contextodecompilación

EjecutableDOS

EjecutableWindows

.C .H

Precompilador

.I .ASM

Compilador Ensamblador

.OBJ .OBJ .OBJ

Enlazador

.LIB

.ASM.EXE .EXE Ensamblador

Enlazadordinámico

.DLL

Proceso

Recurso

CompiladordeC

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 17

Procesodecompilación

FasesdecompilaciónToda compilación es un proceso de transformación paulatina que convierte un programa escrito en un lenguaje fuente de alto nivel en otro programa escrito en un lenguaje objeto de bajo nivel. Ese proceso se articula conceptualmente en una secuencia de fases

›  Análisis léxico

›  Análisis sintáctico

›  Análisis semántico

›  Generación de código intermedio

›  Generación de código final

Analizad

orléxico

Analizad

orsintác8co

Analizad

or

semán

8co

Códigointerm

edio

Códigofina

l

e·l·i·h·w <WHILE,PR> S

WHILEEDOS

E>E

S

WHILEEDOS

E>E

√ LDat1LDbt2GRTt3t1t2BRZt3L1…

0000001100000011010000010100000000010010…

While(a>b)doa:=a+1;

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 18

Procesodecompilación

FasesdecompilaciónToda compilación es un proceso de transformación paulatina que convierte un programa escrito en un lenguaje fuente de alto nivel en otro programa escrito en un lenguaje objeto de bajo nivel. Ese proceso se articula conceptualmente en una secuencia de fases

Analizadorléxico

e·l·i·h·w

<WHILE,PR>

While(a>b)doa:=a+1;

I.AnálisisléxicoEl analizador léxico (scanner) va leyendo caracteres del fichero hasta encontrar una entidad con significado léxico. Estas entidades se llaman tokens y son una estructura de datos que contiene información acerca del mismo (tipo, lexema, número de fila y columna, valor, etc.) La construcción de analizadores léxicos suele hacerse mediante herramientas que hay que configurar indicando el tipo de token que es necesario emitir para cada posible patrón léxico

while:<WHILE,PR>do:<DO,PR>l(l|d)*:<a,ID>...

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 19

Procesodecompilación

FasesdecompilaciónToda compilación es un proceso de transformación paulatina que convierte un programa escrito en un lenguaje fuente de alto nivel en otro programa escrito en un lenguaje objeto de bajo nivel. Ese proceso se articula conceptualmente en una secuencia de fases

Analizadorsintác8co

<WHILE,PR>

II.Análisissintác8coEl analizador sintáctico (parser) va pidiendo tokens al analizador léxico y los va organizando en frases de acuerdo a las reglas de construcción gramatical del lenguaje. Como resultado genera un árbol de análisis sintáctico que representa todo el programa en memoria La construcción de analizadores sintácticos suele hacerse mediante herramientas que hay que configurar indicando la colección de reglas sintácticas que definen las construcciones del lenguaje gramaticalmente correctas

S ::= SIf | Swhlile | ... SWhile ::= while PI E PD do S; E ::= E + E E ::= E * E E ::= E > E E ::= E < E E ::= id ...

SWhile

WHILEEDOS

E>E

<a,ID><>,GT><b,ID>

<DO,PR><a,ID><:=,ASIG>...

<(,PI>

<),PD>

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 20

Procesodecompilación

FasesdecompilaciónToda compilación es un proceso de transformación paulatina que convierte un programa escrito en un lenguaje fuente de alto nivel en otro programa escrito en un lenguaje objeto de bajo nivel. Ese proceso se articula conceptualmente en una secuencia de fases

Analizadorsemán8co

III.Análisissemán8coEl analizador semántico se encarga de gestionar la declaración de constantes, funciones, procedimientos y variables y de comprobar la corrección de tipos a lo largo de todo el programa. Como resultado se obtiene un árbol de análisis sintáctico anotado, con atributos en cada uno de sus nodos La implementación del analizado semántico se realiza insertando acciones semánticas en las partes derechas de las reglas de producción gramatical

S ::= SIf | Swhlile | ... SWhile ::= while PI E PD do S; {: if (E.tipo != booleano) error (); :} ...

SWhile

WHILEEDOS

E>E

SWhile

WHILEEDOS

E>E

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 21

Procesodecompilación

FasesdecompilaciónToda compilación es un proceso de transformación paulatina que convierte un programa escrito en un lenguaje fuente de alto nivel en otro programa escrito en un lenguaje objeto de bajo nivel. Ese proceso se articula conceptualmente en una secuencia de fases

Códigointermedio

IV.GeneracióndecódigointermedioEl generador de código intermedio traduce la representación arborescente del programa en una secuencia ordenada de instrucciones llamadas cuádruplas próximas al lenguaje máquina. Se trata de un lenguaje abstracto y genérico que aún mantiene las referencias simbólicas a los elementos declarados en el programa (variables, parámetros, funciones, etc.) La implementación del generador de código intermedio se realiza insertando acciones en las partes derechas de las reglas de producción que acumulan la traducción parcial del subárbol en cada nodo

exp ::= exp:e1 > exp:e2 {:... e.código = e1.código + e2.código + CMP e1.temp r2.temp e.temp :};

SWhile

WHILEEDOS

E>E

LDat1LDbt2GRTt3t1t2BRZt3L1...

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 22

Procesodecompilación

FasesdecompilaciónToda compilación es un proceso de transformación paulatina que convierte un programa escrito en un lenguaje fuente de alto nivel en otro programa escrito en un lenguaje objeto de bajo nivel. Ese proceso se articula conceptualmente en una secuencia de fases

Op8mizaciónCódigointermedio

V.Op8mizacióndecódigointermedioEn los compiladores comerciales es frecuente optimizar el resultado de la fase anterior para hacer el programa más compacto y más rápido. Suelen aplicarse estrategias de transformaciones heurísticas y elementales que ofrecen buenos resultados

LDat1LDbt2GRTt3t1t2BRZt3L1...

LDat1LDbt2GRTt3t1t2BRZt3L1...

WHILE(A>B)AND(A<2*B-5)DOA:=A+B

L1:IFA>BGOTOL2GOTOL3L2:T1:=2*BT2:=T1–5IFA<T2GOTOL4GOTOL3L4:A:=A+BGOTOL1L3:...

Optimización

Código intermedio

L1:IFA<=BGOTOL2T1:=2*BT2:=T1–5IFA>=T2GOTOL2A:=A+BGOTOL1

L2: …

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 23

Procesodecompilación

FasesdecompilaciónToda compilación es un proceso de transformación paulatina que convierte un programa escrito en un lenguaje fuente de alto nivel en otro programa escrito en un lenguaje objeto de bajo nivel. Ese proceso se articula conceptualmente en una secuencia de fases

VI.CódigofinalUna vez que el código intermedio ha sido generado y optimizado pueden resolverse las referencias simbólicas a posiciones de memoria física y a recursos de la máquina (registros, pila, etc.). Además debe traducirse cada cuarteto a sus equivalentes instrucciones en código máquina La traducción a código final se encarga de hacerla una rutina de traducción ubicada en la acción semántica final ubicada al final de la regla de producción del axioma

Códigofinal

LDat1LDbt2GRTt3t1t2BRZt3L1...

0000001100000011010000010100000000010010…

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 24

Procesodecompilación

Etapasdecompilación

›  Expertos en lenguajes

›  Independencia de arquitectura

›  Dependencia de lenguaje

›  Optimización de lenguajes

Analizad

orléxico

Analizad

orsintác8co

Analizad

or

semán

8co

Códigointerm

edio

Códigofina

l

e·l·i·h·w <WHILE,PR> S

WHILEEDOS

E>E

S

WHILEEDOS

E>E

√ 0000001100000011010000010100000000010010…

While(a>b)doa:=a+1;

Etapa de análisis Etapa de síntesis

›  Expertos en arquitecturas

›  Dependencia de arquitectura

›  Independencia de lenguaje

›  Optimización de ejecución

LDat1LDbt2GRTt3t1t2BRZt3L1…

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 25

Procesodecompilación

Equiposdecompilación

Analizadorléxico

Analizadorsintác8co

Analizadorsemán8co

Códigointermedio

While(a>b)doa:=a+1;

Equi

po d

e Le

ngua

je

Op8mizaciónCódigointermedio

Códigofinal

Analizadorléxico

Analizadorsintác8co

Analizadorsemán8co

Códigointermedio

Op8mizaciónCódigointermedio

Códigofinal

LDat1LDbt2GRTt3t1t2BRZt3L1…

Equi

po d

e

arqu

itect

ura

Pascal C

Intel Solaris

Código intermedio

M

N x

while(a>b)a++;

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 26

Procesodecompilación

ArtefactosdecompilaciónA lo largo de todo el proceso de compilación se una colección de artefactos para dar soporte al mismo. A lo largo del curso los estudiaremos en detalle. Dos son de vital importancia

I.Tabladesímbolos

La tabla de símbolos se utiliza para gestionar todos los elementos declarados por programador (constantes, tipos, variables, funciones y procedimientos)

Analizadorléxico

Analizadorsintác8co

Analizadorsemán8co

Códigointermedio

Op8mizaciónCódigointermedio

Códigofinal

Tablade

símbo

los

Analizador léxico En compiladores antiguos utilizado para reconocer palabras clave

Analizador semántico Registra los elementos declarados por el programador y los consulta para efectuar la comprobación de tipos

Código intermedio Se consulta para conocer el espacio de memoria que debe reservarse para gestionar la activación de subrutinas y p a r a d e t e r m i n a r e l á m b i t o d e declaración de los elementos

Código final Se utiliza para traducir las referencias simbólicas a posiciones de memorial

Fase Descripción

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 27

Procesodecompilación

ArtefactosdecompilaciónA lo largo de todo el proceso de compilación se una colección de artefactos para dar soporte al mismo. A lo largo del curso los estudiaremos en detalle. Dos son de vital importancia

II.Gestordeerrores

Las tres primeras fases pueden generar errores durante el proceso de compilación. El gestor de errores se encarga de emitir mensajes de los mismos para informar al programador

Gestordeerrores

Analizadorléxico

Carácterñnoválido

Whiñe(a>b)doa:=a+1;

Analizadorsintác8coAnalizadorsemán8co

SWhile::=WHILEeDOs

Analizadorléxico

While(a>b)a:=a+1;

Analizadorsintác8co

Analizadorléxico

While(a>b)doa:=a+‘c’;

Seesperabaunenteroenexpresióndesuma

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 28

Análisisdecompiladores

RepresentacióndeuncompiladorComo se ha discutido a lo largo del tema un compilador es una máquina de transformación capaz de traducir un programa escrito en un lenguaje fuente a otro programa escrito en otro lenguaje objeto. A su vez, éste está implementado en un tercer lenguaje llamado lenguaje anfitrión. Por tanto, para representar en abstracto un compilador suele emplearse una representación en forma de T que incluye los 3 lenguajes que lo caracterizan

›  Lenguaje objeto (T)

›  Lenguaje fuente (S)

›  Lenguaje anfitrión (H)

S T

H }

H es un lenguaje máquina frecuentemente igual a T

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 29

Análisisdecompiladores

Tiposdecompiladores

H

I.Ensamblador

ASM Máquina

H

II.Compiladorcruzado

S T

H = T

H

III.Autocompilador

S T

H != T H = S

H

IV.Metacompilador

S T

H

V.Descompilador

T S

S especificaciones

T es un compilador

Se traduce de T a S

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 30

Análisisdecompiladores

Portabilidaddecompiladores

I.Portabilidadfuentedes8no

A B

H

B C

H

= A C

H

II.Portabilidaddehost

A B

H H K

M

= A B

K

La concatenación transitiva de dos compiladores da como resultado un compilador del fuente del primero al objeto del segundo

Si tenemos un compilador con anfitrión H y necesitamos uno con anfitrión K podemos usar un compilador H a K y traducir los anfitriones

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 31

Análisisdecompiladores

Portabilidaddecompiladores

III.Arranqueautomá8coportransferencia

Java ENS

Java Java ENS

ENS

= Java ENS

ENS

Construimos un compilador de java provisional en ensamblador. Construirnos un compilador de java a ensamblador en java. Para compilarlo utilizamos el compilador provisional y obtenemos un compilador de java a ensamblador en ensamblador mejorado. Recurrimos iterativamente sustituyendo en cada pasada el compilador provisional por el nuevo en la iteración anterior

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 32

Construccióndecompiladoresenlaprác6ca

Descripcióndelaprác8ca

S ENS2001

Java

›  Lenguaje fuente : S

›  Lenguaje objeto : ENS2001

›  Lenguaje anfitrión : Java

Entrega de Febrero Entrega de Junio

›  Analizador léxico

›  Analizador sintáctico

50% especificación

Sesión de control (Enero)

›  Analizador léxico

›  Analizador sintáctico

›  Analizador semántico

›  Generación de código intermedio

›  Generación de código final

50% especificación

Sesión de control (Mayo)

Test

Entrega de Septiembre

›  Analizador léxico

›  Analizador sintáctico

›  Analizador semántico

›  Generación de código intermedio

›  Generación de código final

100% especificación

Sesión de control (Junio)

Test

›  JFlex

›  Cup

›  Ant

›  Marco de desarrollo

›  ENS2001

Caracterís8cas Herramientas

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 33

Construccióndecompiladoresenlaprác6ca

Primerospasosconlaprác8ca

›  Instalar JDK

›  Descargar JDK de la página Web

›  Ejecutar el instalable

›  Comprobar la actualización de las variables de entorno path y classpath

›  Descargar un IDE de desarrollo

›  NetBeans

›  Eclipse

›  Descargar el marco de desarrollo proporcionado

›  Descargar del entorno virtual

›  Crear un proyecto a partir del marco de desarrollo

›  Actualizar el IDE para que reconozca todas las libarías

›  Crear tareas ant desde el IDE para ejecutar los scripts de ejecución y prueba de la práctica

I.Instalaciónydescarga

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 34

Construccióndecompiladoresenlaprác6ca

Primerospasosconlaprác8caII.Desarrollosobreelframeworkdesoporte

Las clases compiladas se generan aquí

Las documentación de la arquitectura (sobre todo en 2ºcuatrimestre) Tareas ant para ejecutar y depurar la práctica

§  clear §  jflex §  cup §  build

§  flexTest §  cupTest §  finalTest

Memoria de la práctica según formato establecido

Consúltese el documento “Directrices de implementación”

Especificaciones gramaticales de Cup

Especificaciones léxicas de JFlex Test de prueba para las especificaciones A y B

Librerías necesarias Con8núa…

Esta primera parte del framework contiene la documentación, ficheros de configuración, librerías de ejecución, y directorios de soporte a la compilación

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 35

Construccióndecompiladoresenlaprác6ca

Primerospasosconlaprác8caII.Desarrollosobreelframeworkdesoporte

Consúltese el documento “Directrices de implementación”

Esta segunda parte del framework contiene la infraestructura de clases abiertas que el usuario debe extender o completar

Acceso a los artefactos del compilador

Entorno de ejecución donde se efectúa la generación del código final

Artefactos para la generación de código intermedio

Clase Token para comunicar el analizador léxico con el sintáctico

Clases Symbol y Type para representar los tipos y símbolos

Clases para representar los no terminales del árbol de análisis sintáctico

Programar para la prueba y depuración §  LexicalTestCase §  SyntaxTestCase §  FinalTestCase

Con8núa…

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 36

Construccióndecompiladoresenlaprác6ca

Primerospasosconlaprác8caII.Desarrollosobreelframeworkdesoporte

Consúltese el documento “Directrices de implementación”

Esta tercera parte del framework contiene la infraestructura de clases cerradas que ofrecen al usuario funcionalidades completas para utilizar

Entorno de ejecución donde se efectúa la generación del código final

Artefactos para la generación de código intermedio

Artefactos para el análisis léxicos y el control de errores

Artefactos para el análisis semántico y el control de errores

Artefactos para el análisis sintáctico y el control de errores

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 37

Construccióndecompiladoresenlaprác6ca

Primerospasosconlaprác8ca

›  La ejecución y prueba del marco de trabajo esta dirigida por tareas ant

›  Clear: Borrar el contenido de /clases

›  JFlex: Generar el analizador léxico (como un fichero fuente en src/lexical/scanner.java)

›  Cup: Generar el analizador sintáctico (como un fichero fuente en src/syntax/parser.java)

›  Build: Cup + Jflex + Compile

›  flexTest: Ejecuta la prueba LexicalTestCase (generar tokens hasta final de fichero)

›  cupTest: Ejecuta la prueba SyntaxTestCase (ejecuta el parser)

›  finalTest: Ejecuta la prueba FinalTestCase (ejecuta el parser y traza el estado del compilador)

›  Familia de tablas de símbolos creadas

›  Familia de tablas de tipos creadas

III.Ejecuciónyprueba

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 38

Construccióndecompiladoresenlaprác6ca

Primerospasosconlaprác8ca

›  Especificación del analizador léxico

›  Generación (Jflex + compilar)

›  Prueba (FlexTest)

›  Especificación del analizador sintáctico

›  Generación (Build)

›  Prueba (CupTest)

›  Integración del analizador lexico con el sintáctico

›  Generación (Build)

›  Prueba (CupTest)

III.Fasesdedesarrollodelcompilador

›  Implementación en cup del sistema de tipos

›  Generación (Build)

›  Prueba (FinalTest)

›  Generación de código intermedio

›  Generación (Build)

›  Prueba (FinalTest)

›  Generación de código Final

›  Generación (Build)

›  Prueba (FinalTest)

›  Pruebas finales con fichero de test

1er cuatrimestre 2º cuatrimestre

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 39

Bibliograca

MaterialdeestudioBibliografía básica

Construcción de compiladores: principios y práctica

Kenneth C. Louden International Thomson Editores,

2004 ISBN 970-686-299-4

Javier Vélez Reyes [email protected]

Introducción.Elprocesodecompilación

1 - 40

Bibliograca

MaterialdeestudioBibliografía complementaria

Compiladores: Principios, técnicas y herramientas.

Segunda Edición Aho, Lam, Sethi, Ullman

Addison – Wesley, Pearson Educación, México 2008

Diseño de compiladores. A. Garrido, J. Iñesta, F. Moreno

y J. Pérez. 2002. Edita Universidad de Alicante

Procesad

oresdeLengua

jes

IngenieríaTécnicasu

perio

rdeIngenieríaIn

form

á8ca

Departam

entodeLenguajesy

Sistem

asinform

á6cos

JavierVé[email protected]á?cosUNED

ParteIIEtapadeanálisis

ProcesadoresdeLenguajesIngenieríaTécnicasuperiordeIngenieríaInformá8ca

DepartamentodeLenguajesySistemasinformá6cos

JavierVé[email protected]

DepartamentodeLenguajesYSistemasInformáAcosUNED

2AnálisisléxicoLenguajesregulares

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 2

Obje6vos

Obje8vos

›  Conocer las responsabilidades de un analizador léxico

›  Aprender cómo funciona

›  Entender los diferentes tipos de patrones que reconoce

›  Aprender a especificar formalmente analizadores léxicos

›  A través de gramáticas formales

›  A través de expresiones regulares

›  A través de autómatas finitos

›  Estudiar la implementación de analizadores léxicos

›  Conocer las distintas estrategias de implementación

›  Entender las posibles relaciones con la tabla de símbolos

›  Estudiar la generación de errores léxicos

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 3

Índice

Índice

›  Introducción

›  Token

›  Patrón léxico

›  Lexema

›  Lenguaje regular

›  Especificación de analizadores léxicos

›  Lenguajes regulares

›  Gramáticas lineales

›  Expresiones regulares

›  Autómatas finitos

›  Conversión de formalismos

›  Implementación de analizadores léxicos

›  basada en casos

›  dirigida por tabla

›  guiada por herramientas

›  Estrategias de implementación

›  Gestión de errores

›  Construcción de A. léxicos en en la práctica

›  ¿Qué es JFlex?

›  ¿Cómo funciona JFlex?

›  ¿Cómo se usa JFlex?

›  Gestión de errores en JFlex

›  Desarrollo paso a paso

›  Bibliografía

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 4

Introducción

Analizadorléxico·i·h·w

<WHILE,PR>

While(a>b)doa:=a+1;

Analizadorsintác8co

nextToken()

IntroducciónEl primer paso para procesar un programa es convertir la colección de caracteres del mismo en una colección de componentes léxicos con significado único dentro del lenguaje llamados tokens. De eso se encarga el analizador léxico o escáner

El analizador sintáctico va pidiendo nuevos tokens al analizador léxico y éste los sirve bajo demanda

Foco de atención

¿Cómo se formaliza un analizador léxico?

¿Cómo se implementa un analizador léxico?

›  Formalismos

›  Conversión entre formalismos

›  Estrategias de implementación

›  Buenas prácticas

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 5

Introducción

IntroducciónEl primer paso para procesar un programa es convertir la colección de caracteres del mismo en una colección de componentes léxicos con significado único dentro del lenguaje llamados tokens. De eso se encarga el analizador léxico o escáner

Definicióndetoken

Un token es una unidad léxica indivisible con significado único dentro del lenguaje. Desde el punto de vista tecnológico se trata de una estructura de datos que contiene información sobre

›  ID: Tipo del token

›  Número de línea

›  Número de columna

›  Lexema

›  Valor…

CategoríasdetokenLos tipos de tokens existentes en un lenguaje son una característica intrínseca al mismo. No obstante, pueden encontrarse categorías generales

Categoría Ejemplos

Delimitadores

Palabrasreservadas

Iden8ficadores

Númerosenteros

Númerosflotantes

Simbolosespeciales

Cadenas

(),;:[]

whiletruedoiffor

IndexfisEven

3-45507658

4.5.30.58.4e-5

+-*/.=<><=>=!=++

“Holamundo!”

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 6

Introducción

IntroducciónCada tipo de token representa a un conjunto de tokens (construcciones léxicas diferentes) con unos mismos propósitos dentro del lenguaje. Estos tipos se definen a través de un patrón léxico al que se adscriben los lexemas del tipo

Definicióndepatrónléxico

Un patrón léxico es una expresión abstracta llamada expres ión regu la r que permi te iden t i f i ca r unívocamente un tipo de token y referenciar al conjunto de todos los tokens que se ajustan a él.

DefinicióndelexemaLa cadena de caracteres específica de un token que se ajusta al patrón léxico de su tipo se llama lexema. Existen dos tipos de lexemas

›  Cadena propia: lexema idéntica al patrón

›  Cadena no propia: lexema encaja con patrón

Tipodetoken Patrónléxico

While

Enteros

División

Iden8ficador

while

digito+

/

letra(letra|digito)*

Ejemplosdelexema

while

12123045

/

IndexfisEven

Cadenapropia

SI

NO

SI

NO

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 7

Introducción

IntroducciónDesde la perspectiva léxica un programa es una familia ordenada de tokens de varios tipos. Cada tipo, a través de su patrón léxico, define un micro lenguaje formado por todos aquellos lexemas que encajan con el patrón léxico. Este tipo de lenguajes sencillos se llaman lenguajes regulares

Definicióndelenguajeregular

Un lenguaje regular describe una familia de tokens que se ajustan a un determinado patrón léxico.

programburbuja;usescrt;constn=5;vari,j,temp:integer;a:array[1..n]ofinteger;beginfori:=1tondoreadln(a[i]);forj:=(n-1)downto1dofori:=1tojdoif(a[i])>(a[i+1])thenbegintemp:=a[i];a[i]:=a[i+1];a[i+1]:=temp;end;writeln('Elresultadoes:');fori:=1tondowriteln(a[i]);readln;end.

Lenguajedeiden8ficadoresPascal

burbujactrnijtempareadlnwriteln...

LenguajedepalabrasreservadasdePascal

programusesconstvarintgerofarraybeginforto

dodowntiifthenEnd...

LenguajededelimitadoresdePascal

;=,:[..]()...

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 8

Especificaciónformaldeanalizadoresléxicos

EspecificacióndelenguajesregularesAdemás de la declaración extensiva – sólo viable en los lenguajes finitos – existen 3 diferentes maneras de definir formalmente un lenguaje regular. A lo largo de esta sección estudiaremos cada una de ellas en detalle y veremos cómo se puede pasar de cada una a las otras 2

Lenguajesregulares

Gramá8caslineales

Expresionesregulares

Autómatasfinitos

›  Elementos

›  Gramáticas lineales

›  Expresiones regulares

›  Autómatas finitos

›  Transformaciones

›  De gramáticas a expresiones

›  De gramáticas a autómatas

›  De expresiones a gramáticas

›  De expresiones a autómatas

›  De autómatas a gramáticas

›  De autómatas a expresiones

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 9

Especificaciónformaldeanalizadoresléxicos

Especificaciónmediantegramá8caslinealesUna forma de definir formalmente un lenguaje regular es utilizar una gramática lineal, que describe todas las reglas que se pueden aplicar para la construcción de lexemas que pertenecen al lenguaje regular

Definicióndegramá8calinealUna gramática lineal es un conjunto de 4 elementos G = (T, N, S, P) donde:

›  T es un conjunto de símbolos terminales

›  N es un conjunto de símbolos no terminales

›  S Є N axioma gramatical

›  P un conjunto de reglas de producción de la forma

1.  A ::= B x donde A, B Є N y x Є T

2.  A ::= x B donde A, B Є N y x Є T

3.  A ::= x donde x Є T U { ع}

A veces T se elide, N se deduce de los antecedentes de las reglas de P y se asume que el antecedente de la primera regla es S con lo G sólo a través de P

Tiposdegramá8caslinealesExisten en realidad 2 tipos de gramáticas lineales. En función de la forma del conjunto de reglas de producción podemos distinguir entre:

›  Gramáticas lineales por la izquierda

›  Usan reglas A ::= B x

›  Usan reglas A ::= x

›  Gramáticas lineales por la derecha

›  Usan reglas A ::= x B

›  Usan reglas A ::= x

Dada una gramática G lineal por la izquierda siempre se puede encontrar una gramática G’ lineal por la derecha y recíprocamente

)representa la cadena vacía (ausencia de terminal ع

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 10

Especificaciónformaldeanalizadoresléxicos

Especificaciónmediantegramá8caslinealesUna forma de definir formalmente un lenguaje regular es utilizar una gramática lineal, que describe todas las reglas que se pueden aplicar para la construcción de lexemas que pertenecen al lenguaje regular

Derivacióngrama8calUna gramática debe interpretarse como un conjunto de reglas de reescritura o transformación de elementos no terminales en elementos terminales o no terminales.

›  La primera transformación parte del axioma

›  En cada paso se aplica una única regla

›  Las reglas pueden extender la transformación ( A::= B x / A ::= x B)

›  Las reglas pueden ser recursivas (A ::= A x / A ::= x A)

›  Las reglas pueden ser terminales (A ::= x)

›  El proceso debe ser convergente

LG = {a b*}

Sea G = (T, N A, P) con

T = {a, b}

N = {A, B}

P = {

A ::= a B

A ::= a

B ::= b B

B ::= b

}

Ejemplo

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 11

Especificaciónformaldeanalizadoresléxicos

Especificaciónmediantegramá8caslinealesUna forma de definir formalmente un lenguaje regular es utilizar una gramática lineal, que describe todas las reglas que se pueden aplicar para la construcción de lexemas que pertenecen al lenguaje regular

Derivacióngrama8calEl problema ahora se traduce en, dada una cadena formada por una secuencia de elementos terminales de T, demostrar que dicha cadena pertenece al lenguaje definido por la gramática

LG = {a b*}

Sea G = (T, N A, P) con

T = {a, b}

N = {A, B}

P = {

A ::= a B

A ::= a

B ::= b B

B ::= b

}

A → aB → abB → abbB → abbb

Ejemplo

axioma

Paso de derivación

asidero

Frase F o r m a de frase

Cadena de derivación

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 12

›  L1 = conjunto de todas las palabras sobre {a, b} que empiezan por a

›  L2 = conjunto de todas las palabras sobre {a, b} que empiezan por a y continúan con secuencias ab

›  L3 = Números fraccionarios

›  L4 = Identificadores

Especificaciónformaldeanalizadoresléxicos

Especificaciónmediantegramá8caslinealesUna forma de definir formalmente un lenguaje regular es utilizar una gramática lineal, que describe todas las reglas que se pueden aplicar para la construcción de lexemas que pertenecen al lenguaje regular

EjerciciosDefinir formalmente a través de una gramática lineal los siguientes lenguajes descritos informalmente

GD = (T, N A, P) con

T = {a, b}

N = {A, B}

P = {

A ::= a B

B ::= a B

B ::= b B

B ::= ع

}

GI = (T, N A, P) con

T = {a, b}

N = {A, B}

P = {

A ::= A a

A ::= A b

A ::= a

}

L1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 13

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteexpresionesregularesOtra forma de definir lenguajes regulares es a través del uso de expresiones regulares. Una expresión regular utiliza los términos del alfabeto de terminales operados a través de operaciones con una semántica especifica

Una expresión regular sobre un conjunto T es un conjunto ER = (T, | , · , *) que cumple las siguientes propiedades:

Definicióndeexpresiónregular

›  Ø es una expresión regular que define el lenguaje L = Ø

 ع )es una expresión regular que define el lenguaje L (cadena vacía ) ع( = } ع { ›

›  Cualquier símbolo a Є T es una expresión regular que define el lenguaje L ( a ) = { a }

›  Si x, y son dos expresiones regulares, x·y es una expresión regular que define L ( x·y ) = L ( x ) L ( y )

›  Si x, y son dos expresiones regulares, x | y es una expresión regular que define L (x | y) = L ( x ) U L ( y )

›  Si x es una expresión regular x* es una expresión regular que define L ( x* ) = U L( x )

›  Si x es una expresión regular x+ es una expresión regular que define el lenguaje L ( x* ) = U L( x )

›  No existen más expresiones regulares

i =0

∞ i

∞ i =1

i

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 14

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteexpresionesregularesOtra forma de definir lenguajes regulares es a través del uso de expresiones regulares. Una expresión regular utiliza los términos del alfabeto de terminales operados a través de operaciones con una semántica especifica

Definir los siguientes lenguajes regulares utilizando para ello expresiones regulares

Ejercicios

›  L1 = Lenguaje de identificadores

›  L2 = Lenguaje de números naturales

›  L3 = Lenguaje de números fraccionarios

›  L4 = Lenguaje de números enteros con exponente

›  L5 = Lenguaje de números fraccionarios con exponente

›  L6 = Lenguaje de números pares

›  L7 = Lenguaje de las cuentas de correo

›  L8 = Lenguajes de las URL

L1 = l ( l | d )* l Є {a..z} d Є {0..9}

L3 = d+ . d+ d Є {0..9}

L6 = d+ p d Є {0..9} p Є {0, 2, 4, 6, 8}

L7 = nombre @ host

nombre = L1 (. L1)*

host = L1 (. L1)*

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 15

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

Un autómata finito determinista es un conjunto AFD = (T, Q, f, q, F) donde:

Autómatafinitodeterminista

›  T es un alfabeto de símbolos terminales de entrada

›  Q es un conjunto de estados finito no vacío

›  f: Q x T → Q es una función de transición

›  q Є Q es un estado inicial o estado de arranque

›  F C Q es un subconjunto de estados finales de aceptación

Gráficamente, un autómata finito determinista es una colección de estados unidos por arcos, donde para cada estado existe un arco etiquetado con cada elemento de T. El estado inicial tiene una flecha entrante y los estados finales tienen un doble borde

Interpretacióngráfica

letra

letra, dígito

letra, dígito

dígito

letra Є [a..z] dígito Є [0..9]

1

2

0

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 16

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

Con el ánimo de simplificar el trabajo con los autómatas finitos deterministas, dentro de la teoría de compiladores se utilizan las siguientes extensiones notacionales

Extensióndelosautómatasfinitosdeterministas Interpretacióngráfica

›  Las transiciones ausentes se asumen como errores

›  Se omiten los estados de absorción de errores

›  Se usa la etiqueta otro para representar el resto de alternativas

›  Los estados finales paran el proceso y emiten token

›  Los estados finales con * recuperan el carácter de tránsito

›  Se espera a reconocer el posible toquen de lexema más largo

›  El estado final ya no es final

›  Al llegar un carácter terminador se pasa a uno final

›  Entonces se emite el token

›  Si es necesario se marca con * el estado final

0letra

letra, dígito

A continuación representamos el autómata finito determinista anterior aplicando las extensiones descritas

otro

letra Є [a..z] dígito Є [0..9]

* 2

1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 17

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

Los autómatas arrancan en el estado de inició y comienzan a consumir caracteres de la entrada lo que provoca una transición a un nuevo estado o un error. En cuanto se alcanza un estado de aceptación final, el autómata para y se emite el token reconocido

Comoseusanlosautómatasfinitosdeterministas

→ c → o → u → n → t → e → r → 0 → 1 → +

letra

letra, dígito

otro

letra Є [a..z] dígito Є [0..9]

*

caracteres

Estado 0 Estado 1 Estado 2

transiciones

token

Carácter delimitador (otro)

0

2

1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 18

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

Definir los siguientes lenguajes regulares utilizando para ello autómatas finitos deterministas

Ejercicios

›  L1 = Lenguaje de identificadores

›  L2 = Lenguaje de números naturales

›  L3 = Lenguaje de números fraccionarios

›  L4 = Lenguaje de números naturales con exponente

›  L5 = Lenguaje de números fraccionarios con exponente

›  L6 = When

letra

letra, dígito

otro *

L1

0

2

1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 19

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

Para construir un analizador léxico completo es necesario combinar en un único autómata todos los autómatas correspondientes a los micro-lenguajes que aparecen en el lenguaje. Este proceso se puede hacer mediante una aproximación holística

Construcciónmanualcomposi8vadeautómatas

›  L7 = Números naturales y fraccionarios con exponente

›  L8 = {<, <<,<=, =, ==, +, ++, -, --, *, *=}

›  L9 = {While, When, Do, Downto}

›  L10 = L1 U L7 U L9

›  L11 = U Li con i Є [1..11]

0

< *

=

+

<

*

= otro

= otro

+ otro

– otro

= otro

<<

<=

<

==

=

++

+

– –

*=

*

*

*

*

* 16

15

13

12

10

9

7

6

4

3

2

11

14

L8

Definir los siguientes lenguajes regulares utilizando para ello autómatas finitos deterministas

Ejercicios

0

5

8

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 20

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

Cuando el número de micro-lenguajes es grande y éstos son complejos la aproximación manual se convierte en un proceso prolijo por eso conviene establecer un proceso sistemático. Este proceso se basa en definir formalmente la composición de autómatas sobre las operaciones legítimas de composición de autómatas

Construcciónsistemá8cacomposi8vadeautómatas

L (x) x

L (x) L (y) x y ع

L (x) U L (y)

x ع

L (x)+ x

ع

L (x)* x

ع

00 ع1

ع

Las ع– transiciones deben interpretarse como transiciones que no consumen caracteres }

x

0 n1 n-1 … ≡

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 21

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

Cuando el número de micro-lenguajes es grande y éstos son complejos la aproximación manual se convierte en un proceso prolijo por eso conviene establecer un proceso sistemático. Este proceso se basa en definir formalmente la composición de autómatas sobre las operaciones legítimas de composición de autómatas

Construcciónsistemá8cacomposi8vadeautómatas

L = {<, <<, <=} Ejemplo

0 <

1

4

7 =

otro

5

8<

<

2< ع

ع

ع

0

1

3

5 =

otro

<

Uso de ع–transiciones para construir el autómata

}

La eliminación de las ع–transiciones provoca varias transiciones iguales desde el mismo nodo

}

<

<

<

<

<<

<=

<

<<

<=

3

6

9

2

4

6

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 22

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

La construcción sistemática de autómatas genera autómatas finitos no deterministas. Un autómata finito no determinista es un autómata finito donde cada estado:

Autómatasfinitosnodeterministas

›  Puede tener ع – transiciones

›  Puede tener varias transiciones con la misma etiqueta

Genera indeterminación porque desde ese estado no se sabe si avanzar por otra transición normal consumiendo un carácter o hacerlo por la ع – transición sin consumir ningún carácter

Genera indeterminación porque desde ese estado, si el carácter a la entrada tiene varias posibles transiciones no se sabe cual escoger

Los autómatas finitos deterministas no son formalismos adecuados para representar lenguajes regulares

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 23

Especificaciónformaldeanalizadoresléxicos

EspecificaciónmedianteautómatasfinitosLa tercera forma de definir lenguajes regulares es a través del uso de autómatas finitos. Un autómata finito reconoce una cadena de entrada si consumidos todos los caracteres de la misma acaba en un estado final de aceptación

La construcción de un autómata finito determinista a partir de uno no determinista requiere de la identificación de todos los estados alcanzables desde cada estado a través de ع–transiciones y transiciones múltiples

Conversióndeautómatasfinitosnodeterministasaautómatasfinitosdeterministas

L = {<, <<, <=} Ejemplo

0 <

1

4

7 =

otro

5

8<

<

2< ع

ع

ع

<

<<

<=

›  {0} = {1 4 7}

›  {1 4 7} < = {2 5 8}

›  {2 5 8} < = {6}

›  {2 5 8} = = {9}

›  {2 5 8} otro = {3}

{147} {258}< <

=

3

6

9

{3}

{6}

{9}

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 24

Especificaciónformaldeanalizadoresléxicos

ConversióndeformalismosDado cualquiera de los 3 formalismos de representación estudiados es posible encontrar un isomorfismo para expresarlo en cualquiera de los otros 2

Cada regla se expresa en términos de los operadores de concatenación, cierre + y cierre *

ConversióndeGramá8casaexpresiones

A ::= l B A = l B

B ::= l B B = l B = l +

B ::= d B B = d B = d +

B ::= ع B = ع

B = ( l+ | d+ | ع) = ( l | d | ع )+ = ( l | d )*

A = l ( l | d ) *

Se genera un estado por cada no terminal. El estado del axioma es el de inicio. Las reglas se traducen a transiciones. Si la regla es terminal (A ::= x) entonces se genera una transición otro a un estado de aceptación final. Si sale no determinista, convertirlo a determinista.

ConversióndeGramá8casaautómatas

A ::= l B

B ::= l B

B ::= d B

B ::= ع A

l

l, d

otro *

Lenguajesregulares

Gramá8caslineales

Expresionesregulares

Autómatasfinitos

B

2

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 25

Especificaciónformaldeanalizadoresléxicos

ConversióndeformalismosDado cualquiera de los 3 formalismos de representación estudiados es posible encontrar un isomorfismo para expresarlo en cualquiera de los otros 2

Transformar primero la expresión regular desfactorizando los cierres + y *. Después aplicar las transformaciones + a recursividad y * a recursividad con ع producción

ConversióndeExpresionesagramá8cas

L = l ( l | d ) * = l ( l * | d * )

A ::= l B B representa ( l* | d* )

B ::= l B Se captura l+

B := d B Se captura d+

B ::= ع Se captura l* | d*

La conversión de expresiones regulares a autómatas finitos se realiza utilizando las transformaciones atómicas definidas anteriormente al discutir la composición de lenguajes

ConversióndeExpresionesaautómatas

Lenguajesregulares

Gramá8caslineales

Expresionesregulares

Autómatasfinitos

x . y x yع

x | y

x ع

x+ x

ع

x* x

ع

ع

ع

00 1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 26

Especificaciónformaldeanalizadoresléxicos

ConversióndeformalismosDado cualquiera de los 3 formalismos de representación estudiados es posible encontrar un isomorfismo para expresarlo en cualquiera de los otros 2

Cada estado se convierte a un no terminal. El estado de arranque corresponde con el axioma. Cada transición A → B etiquetada con x se traduce en A ::= x B. Si B es un estado final se genera A ::= x. Si x = otro se genera A ::= ع

Conversióndeautómatasagramá8cas

[0] ::= l [1]

[1] ::= l [1]

[1] := d [1]

]1[ ::= ع

Para la transformación de autómatas a expresiones basta con hacer una lectura inversa de las transformaciones atómicas definidas anteriormente

Conversióndeautómatasaexpresión

Lenguajesregulares

Gramá8caslineales

Expresionesregulares

Autómatasfinitos

ع

x . y x yع

x | y

x ع

x+ x

ع

x* x

ع

ع

ع

00 10

l

l, d

otro *

1

2

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 27

Implementacióndeanalizadoresléxicos

¿Quéesunanalizadorléxico?

El analizador léxico responde bajo demanda a las solicitudes de siguiente token que le va haciendo el analizado sintáctico. Cada vez que éste último hace una solicitud al primero, el analizador léxico consume un número de caracteres de la entrada y retorna un artefacto computacional que representa el siguiente token en la entrada. En lo venidero utilizaremos el término token para referirnos a dicho artefacto

Analizadorléxico

e·l·i·h·w

<WHILE,PR>

While(a>b)doa:=a+1;

Analizadorsintác8co

}

nextToken()Id

nFila

nColumna

lexema

valor

En la práctica el artefacto software que representa un token suele ser una estructura de datos o un objeto en los lenguajes orientados a objetos

}

Un analizador léxico o scanner es un programa capaz de descomponer una entrada de caracteres – generalmente contenidas en un fichero – en una secuencia ordenada de tokens.

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 28

Implementacióndeanalizadoresléxicos

Implementacióndeanalizadoresléxicosbasadaencasos

letra=[a..z]

digito=[0..9]

estado=0

fin=false

c=leerCaracter()

while(!fin){

switch(estado){

0:switch(c){

letra:estado=1

lexema+=c

c=leerCaracter()

break

digito:throwerror()

}

De acuerdo a esta estrategia de implementación es necesario disponer de una variable de estado para codificar el estado actual y una batería de casos que describen la lógica de transición del autómata finito determinista.

break;

1:switch(c){

letra:

digito:estado=1

lexema+=c

c=leerCaracter()

break

default:estado=2;

}

break

2:token=crearToken(lexema...)

fin=true

}

returntoken

letra

letra, dígito

otro *

0

2

1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 29

Implementacióndeanalizadoresléxicos

Implementacióndeanalizadoresléxicosdirigidaportabla

tTransicion=[][]

sFinales={estadosfinales}

estado=0

fin=false

c=leerCaracter()

while(!fin){

s=tTransicion[s][c]

if(s!=null)

if(!(sinsFinales)){

lexema+=c

c=leerCaracter()

}elsefin=true

elsethrowerror()}

returncrearToken(lexema...)

Podemos codificar computacionalmente un autómata como una matriz bidimensional de Q x T → Q que indique, para cada entrada y estado el nuevo estado. El algoritmo se limita a leer dicha matriz

letra

letra, dígito

otro *

0

2

1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 30

Implementacióndeanalizadoresléxicos

Implementacióndeanalizadoresléxicosguiadaporherramientas

letra=[a..z]

digito=[0..9]

letra(letra|digito)*{returnnewToken(ID);}

digito+{returnnewToken(ENT);}

digito*.digito+{returnnewToken(FRAC);}

“(”{returnnewToken(PI);}

“)”{returnnewToken(PD);}

“[”{returnnewToken(PI);}

“]”{returnnewToken(PD);}

...

Existen herramientas para la construcción automática de analizadores léxicos [Lex] [Flex] [JFlex]. Estas herramientas se basan en la definición de una colección de reglas patrón - acción

›  Dan prioridad al token más largo

›  DO / DOT

›  > / >=

›  Ante igualdad de longitud

›  Anteponer la regla mas específica

›  When

›  While

›  Id

}

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 31

Implementacióndeanalizadoresléxicos

Estrategiasdeimplementación

I.Reconocimientodepalabrasreservadas

Reconocimientodepalabrasreservadas

Resoluciónexplícita

Resoluciónimplícita

›  Se indican todas con su patrón léxico

›  Se integran en el diagrama global

›  Se utilizan herramientas generadoras (FLex)

›  Las palabras reservadas (PR) se reconocen como identificadores

›  Las k palabras reservadas se meten en la tabla de símbolos (TS)

›  Se busca cada id en TS. Si su índice es < k es PR

II.Reconocimientoestructurascomplejasdeformahíbrida

›  Implementación manual de las estructuras más sencillas

›  Operadores

›  Identificadores

›  Números

›  Implementación tabular o guiada por herramientas con estructuras complejas

›  Cadenas no específicas

›  Prefijos comunes

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 32

Ges6óndeerrores

ErroresléxicosLos errores léxicos son aquellos que se producen en el ámbito del reconocimiento de patrones para construir tokens del lenguaje. Podemos establecer una clasificación de errores de naturaleza léxica

›  Errores básicos

›  Aparición de caracteres ajenos al conjunto T (ñ, Ç, etc.)

›  Ausencia de concordancia con ningún patrón (1abc, +*, etc.)

›  Errores complejos

›  Cadena de caracteres sin cierre (falta “ final)

›  Cadena de caracteres sin apertura (falta “ inicial)

›  Comentario sin cierre (falta */ final)

›  Comentario sin apertura (falta /* inicial)

›  Error en el anidamiento de comentarios (/* .. /* .. */)

Son en realidad de esta categoría

No son en realidad errores capturables por un reconocedor de lenguajes regulares aunque las herramientas generadoras son capaces de reconocerlos

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 33

Construccióndeanalizadoresléxicosenlaprác6ca

¿QuéesJFlex?JFlex es una herramienta para la generación de analizadores léxicos escritos en java. A partir de un fichero de especificación que describe las características léxicas de un lenguaje, JFlex genera un código fuente compilable que puede ser utilizado como analizador léxico

JFlex JavacScanner.flex

Framework

Scanner.java JavaScanner.clas

s

JFlex compile JFlexTest

Esta es la especificación del analizador léxico. Todo cambio en el escáner debe indicarse aquí

Esta es la clase generada a partir de la especificación. Atención! No incluir aquí ningún código manualmente ya que en la próxima generación se perderá

Esta es la clase java compilada que puede ser interpretada por la JVM

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 34

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex?El fichero de especificación de JFlex esta dividido en tres secciones separadas por el delimitador %%. Cada una de ellas tiene una semántica diferente

I.SeccióndecódigodeusuarioLa sección de código de usuario se utiliza para incluir cualquier declaración java (paquete, importación o clase) que sea necesario para compilar el scanner

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 35

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex?El fichero de especificación de JFlex esta dividido en tres secciones separadas por el delimitador %%. Cada una de ellas tiene una semántica diferente

II.Seccióndedirec8vasSe incluyen directivas de compatibilidad con cup, gestión de fila, columna y lexema, declaración de estados y macros e inclusión de código de inicialización

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 36

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex?El fichero de especificación de JFlex esta dividido en tres secciones separadas por el delimitador %%. Cada una de ellas tiene una semántica diferente

III.Seccióndereglaspatrón-acciónEn esta última sección se define una familia de escáneres léxicos, cada uno asociado a un estado distinto (YYINITIAL, COMMENT, etc.). Es posible saltar de uno a otro. La definición se basa en reglas patrón acción que indican el código java que debe ejecutarse cuando la entrada encaja con determinado patrón léxico. Si el código java no acaba con un return el scanner continua buscando un nuevo token

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 37

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex? Consúltese el documento “Manual de JFlex”

I.SeccióndecódigodeusuarioLa sección de código intermedio se copia tal cual al inicio de la clase fuente que representa el escáner (Scanner.java), por tanto todo lo que va en esta sección es código puro java de carácter declarativo

Copia en vervatim

Scanner.java

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 38

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex?

Directiva

›  %full

›  %unicode

›  %{ … %}

›  %init{ … %}

›  %intthow{ … %}

›  %yylexthrow{ … %}

›  %eof{ … %}

›  %eofval{ … %}

›  %eofthrow{… %}

›  %ignorecase

›  %char

›  %line

›  %notunix

Descripción

Utiliza el código ASCII extendido 8 bits

Utiliza codificación UNICODE de 16 bits

Se incluye el código como declaración dentro de la clase Scanner

Incluye código dentro de los constructores

Declara excepciones que el constructor puede lanzar

Declara excepciones que el método de escaneo puede lanzar

Incluye código que se ejecuta tras encontrar EOF

Define el valor de retorno al encontrar EOF

Excepción de se lanza al encontrar EOF

No distinguir entre mayúsculas y minúsculas

Contabiliza el número de caracteres en la variable yychar

Contabiliza el número de líneas en la variable yyline

Reconoce \r\n como carácter (doble) de nueva línea

Consúltese el documento “Manual de JFlex”

II.Seccióndedirec8vas

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 39

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex?

Directiva

›  %class name

›  %public

›  %function name

›  %interface name

›  %type name

›  %integer

›  %intwrap

›  %yyeof

›  %cup

›  %state nombre

›  nombre = valor

Descripción

Da nombre a la clase del escáner

Define como pública la clase del escáner

Da nombre a la función de escaneo

Declara los interfaces que debe implementar el escáner

Define el tipo de retorno de la función de escaneo

Define el tipo de retorno de la función de escaneo como un int

Define el tipo de retorno de la función de escaneo como Integer

Define la constante Yylex.YYEOF (obligatorio uso de %integer)

Habilita la compatibilidad con Cup

Define el estado nombre

Define una macro (LETRA = [A-Za-z])

Consúltese el documento “Manual de JFlex”

II.Seccióndedirec8vas

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 40

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex? Consúltese el documento “Manual de JFlex”

III.Reglaspatrón-acción

›  Despliegue de macros

›  Utilización de estados

{LETRA}({LETRA}|{DIGITO})*{returncrearToken(ID);}{DIGITO}*{returncrearToken(NUM);}

Se utilizan los caracteres { y } para encerrar el nombre de la macro, definida en la sección de directivas, que se quiere desplegar

Cada estado, declarado en la sección de directivas, corresponde con un autómata distinto. Cada regla debe asociarse a un estado precediendo al patrón léxico el nombre del mismo encerrando entre < y > Desde una regla r de un estado A se puede saltar a un estado B mediante la instrucción yybegin (B) invocada en la acción de r. El estado inicial por defecto es YYINITIAL. Este es un estado que no es preciso declarar

<YYINITIAL>“+”{returncrearToken(MAS);}<YYINITIAL>“-”{returncrearToken(MENOS);}<YYINITIAL>“*”{returncrearToken(MUL);}<YYINITIAL>“/”{returncrearToken(DIV);}...<YYINITIAL>“/*”{yybegin(COMMENT);}...

<COMMENT>“/*”{nComments++;}<COMMENT>“*/”{nComments--;if(nComments==0)yybegin(YYINITIAL);}<COMMENT>{COMMENT}{}

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 41

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómofuncionaJFlex? Consúltese el documento “Manual de JFlex”

III.Reglaspatrón-acciónSecuencias de escape

›  \b

›  \n

›  \t

›  \f

›  \r

›  \ddd

›  \xdd

›  \udddd

›  \^C

›  \c

Descripción

Retroceso

Nueva línea

Tabulador

Avance de página

Retorno de carro

Número octal

Número hexadecimal

Hexadecimal de 4 dígitos

Carácter de control

Backslash seguido del c

Metacaracteres

›  \b

›  $

›  .

›  “…”

›  {name}

›  *

›  +

›  ?

›  (…)

›  […]

›  [^…]

›  a-b

Descripción

Retroceso

Fin de fichero

Cualquier carácter menos \n

Expansión de una macro

Clausura de Kleene

Una o más repeticiones

Opcionalidad

Agrupación de expresiones regulares

Conjunto de caracteres

Conjunto complementario

Rango a - b Secuencias de escape Descripción

›  yychar

›  yyline

›  yytext ()

Número de columna

Numero de línea

lexema

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 42

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómoseusaJFlex?Los analizadores sintácticos de JFlex están pensados para usarse bajo demanda. Se trata de artefactos con una API bien definida. El método más relevante es el de escaneo que devuelve el siguiente token a la entrada. El framework prescribe que el método de escaneo debe devolver un objeto de la clase Token

Analizad

orléxico

Analizad

orsintác8co

e·l·i·h·w <WHILE,PR>

While(a>b)doa:=a+1;

La clase Token

Token es una clase hija que hereda de la clase que u s a c u p p a r a i n t e g r a r s e c o n J F l e x (javacup.runtime.Symbol). Esta clase facilita y encapsula la comunicación entre el analizador léxico y el analizador sintáctico desarrollado en Cup proporcionando una colección de métodos de interés

Javacup.run6me.Symbol

Token

+ getID () + getLexema () + getline () + getColumn ()

JFlex Cup

next_Token()

Tokennext_Token()

}

}

Consúltese el documento “Directrices de implementación”

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 43

Construccióndeanalizadoresléxicosenlaprác6ca

¿CómoseusaJFlex?Para adaptar JFlex al framework de desarrollo es necesario realizar una serie de tareas sobre el fichero de especificación. Éstas ya vienen realizadas en la plantilla Jflex que proporciona el framework por lo tanto lo aquí contado es meramente explicativo y no requiere trabajo alguno del estudiante

›  El escáner pertenece al paquete compiler.lexical

›  Debe importarse

›  La clase Token

›  El interfaz ScannerIF

›  Las clases de gestión de errores

›  Debe activarse la compatibilidad con el framework

›  %cup

›  %implements ScannerIF

›  %scanerror LexicalError

›  Opcionalmente declararse la función crearToken

›  Cada acción debe acabar con un return crearToken (…);

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 44

Construccióndeanalizadoresléxicosenlaprác6ca

Ges8óndeerroresenJFlexLa gestión de errores léxicos está soportada dentro del framework por la clase LexicalErrorManager. Los métodos para emitir error son

LexicalError

usa

<YYINITIAL>“+”{returncrearToken(MAS);}<YYINITIAL>“-”{returncrearToken(MENOS);}<YYINITIAL>“*”{returncrearToken(MUL);}<YYINITIAL>“/”{returncrearToken(DIV);}...<YYINITIAL>.{LexicalErrorManager.lexicalFatal(“ufff!”);}

›  error (). Emite un mensaje de error

›  fatal (). Emite un mensaje de error y para el scanner

Ejemplo

Estos métodos están doblemente sobrecargados. Pueden recibir un mensaje de error (String) o un objeto LexicalError que representa un error léxico

Consúltese el documento “Directrices de implementación”

LexicalErrorManager

+ lexicalDebug (String message) + lexicalInfo (String message) + lexicalWarn (String message) + lexicalError (String message) + lexicalError (LexicalError error) + lexicalFatal (String message) + lexicalFatal (LexicalError error)

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 45

Construccióndeanalizadoresléxicosenlaprác6ca

Desarrollopasoapaso

1.  Especificación del escáner

›  Abrir el documento de especificaciones JFlex doc/specs/scanner.flex

›  No cambiar nada de lo que está escrito!

›  Declarar macros necesarias (ALFA, DIGIT, SPACE, NEWLINE…)

›  Declarar el estado de comentarios %%state COMMENT

›  Definir las reglas de YYINITIAL

›  Definir las reglas de COMMENT (contemplar el anidamiento si procede)

2.  Generar el escáner

›  Limpiar (tarea clear)

›  Generar el escáner (tarea jflex)

›  Compilar el escáner (tarea compile)

3.  Probar el escáner

›  Abrir fichero LexicalTestCase src/compiler/test/LexicalTestCase.java

›  Descomentar y comentar lo indicado en el fichero (léelo atentamente)

›  Si funciona, fin. Sino volver a 1

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 46

Bibliograla

MaterialdeestudioBibliografía básica

Construcción de compiladores: principios y práctica

Kenneth C. Louden International Thomson Editores,

2004 ISBN 970-686-299-4

Javier Vélez Reyes [email protected]

Análisisléxico.LenguajesRegulares

2 - 47

Bibliograla

MaterialdeestudioBibliografía complementaria

Compiladores: Principios, técnicas y herramientas.

Segunda Edición Aho, Lam, Sethi, Ullman

Addison – Wesley, Pearson Educación, México 2008

Diseño de compiladores. A. Garrido, J. Iñesta, F. Moreno

y J. Pérez. 2002. Edita Universidad de Alicante

ProcesadoresdeLenguajesIngenieríaTécnicasuperiordeIngenieríaInformá8ca

DepartamentodeLenguajesySistemasinformá6cos

JavierVé[email protected]

DepartamentodeLenguajesYSistemasInformáAcosUNED

3Análisissintác*coILenguajeslibresdecontexto

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 2

Obje6vos

Obje8vos

›  Conocer los lenguajes libres de contexto

›  Conocer las responsabilidades del analizador sintáctico

›  Aprender a utilizar gramáticas libres de contexto

›  Aprender a diseñar gramáticas libres de contexto

›  Aprender a reconocer y resolver fuentes de ambigüedad

›  Aprender a eliminar la recursividad por la izquierda

›  Aprender a factorizar por la izquierda

›  Conocer el uso y tipos de derivaciones y árboles sintácticos

›  Conocer la representación de lenguajes mediante diagramas de sintaxis

›  Presentar los diferentes tipos de autómatas utilizados para construir analizadores sintácticos

›  Discutir los diferentes tipos de analizadores sintácticos

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 3

Índice

Índice›  Introducción

›  Gramáticas libres de contexto

›  Notación BNF y EBNF

›  Derivación gramatical

›  Árboles sintácticos

›  Limpieza gramatical

›  Ambigüedad gramatical

›  Recursividad por la izquierda

›  Factorización por la izquierda

›  Diagramas de sintaxis

›  Autómatas a pila deterministas

›  Bibliografía

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 4

Introducción

Análisissintác8coLa fase de análisis sintáctico tiene por objetivo solicitar tokens al analizador léxico y construir una representación arborescente de todo el código fuente. Este proceso se encuentra dirigido por el conocimiento gramatical que del lenguaje tiene el analizador sintáctico

El analizador sintáctico va pidiendo nuevos tokens al analizador léxico para construir un árbol del programa fuente

Foco de atención

¿Cómo se especifica formalmente un analizador sintáctico?

¿Cómo se implementa un analizador sintáctico?

›  Formalismos

›  Tratamiento de formalismos

›  Conversión entre formalismos

›  Estrategias análisis sintáctico

›  Tipos de gramáticas

›  Tipos de analizadores

Analizadorsintác8co

SWhile

WHILEEDOS

E>E

<WHILE,PR>

<a,ID><>,GT><b,ID>

<DO,PR>...

<(,PI>

<),PD>

Tema 3

Temas 4 y 5

} }

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 5

Introducción

LenguajeslibresdecontextoDesde una perspectiva sintáctica un lenguaje es una colección de construcciones sintácticas bien formadas desde un alfabeto de entrada y correctamente combinadas entre sí de acuerdo a una colección de reglas sintácticas

EjemploEl lenguaje Pascal tiene unas normas de carácter gramatical que definen su naturaleza y expresividad. Visto de manera extensiva, el lenguaje Pascal sería el conjunto infinito de todos los posibles códigos fuente correctos escritos en sintaxis Pascal

Pascal

Usescrt;varcantidad,cont,numero,s:integer;beginclrScr;s:=0;write('Cantidad:');read(canditad);forcont:=1tocantidaddobeginwrite('Numero',cont,':');Read(numero);s:=s+numero;end;write('Promedio:',s/cantidad:0:2);readKey;end;.

usescrt;varcontador:integer;beginClrScr;forcontador:=2to999dobegincontador:=contador+1;Write(contador,',');ifcontador>999thenbegincontador:=999;end;end;ReadKey;end.

Usescrt;varsuma,numero,contador:integer;beginclrScr;write('Numero:');readln(numero);suma:=0;forcontador:=1tonumerodobeginsuma:=suma+contador;end;write('Suma:',suma);readKey;end.

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 6

Introducción

EspecificacióndelenguajeslibresdecontextoExisten 3 diferentes maneras de definir formalmente un lenguaje de contexto libre. A lo largo de esta sección estudiaremos cada una de ellas en detalle y veremos cómo se puede pasar de cada una a las otras 2

Lenguajeslibresdecontexto

Gramá8caslibresdecontexto

Diagramasdesintaxis

Autómatasapila

›  Elementos

›  Gramáticas libres de contexto

›  Diagramas de sintaxis

›  Autómatas a pila

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 7

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Definicióndegramá8calibredecontextoUna gramática libre de contexto es un conjunto de 4 elementos G = (T, N, S, P) donde:

›  T es un conjunto de símbolos terminales

›  N es un conjunto de símbolos no terminales

›  S Є N axioma gramatical

›  P un conjunto de reglas de producción de la forma

1.  A ::= X donde X es una secuencia de elementos en N U T

2.  A ::= x donde x es una secuencia de elementos en T

3.  A :: = ع siendo ع la cadena vacía

A veces T se elide, N se deduce de los antecedentes de las reglas de P y se asume que el antecedente de la primera regla es S con lo G sólo a través de P

Ejemplo

L = Lenguaje de operadores

Sea G = (T, N A, P) con

T = {+, -, *, /, n}

N = {E}

P = {

E ::= E + E

E ::= E - E

E ::= E * E

E ::= E / E

E ::= n

}

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 8

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Notación

E → E + E

E → E – E

E → id

¿Cómo se escriben las reglas?

Notación BNF Las reglas se escriben como A ::= X. Las reglas de un mismo antecedente se escriben como A ::= X | Y | Z… Cada regla con antecendente distinto se escribe en una nueva línea

Notación EBNF Se usa la notación BNF. Las reglas recursivas se pueden esquematizar con los meta-caracteres { y }

Notación estándar Las reglas se escriben como A → X. Cada regla se escribe en una linea distinta

D ::= T L

T ::= int | bool | char

L ::= id , L | id

D ::= T L

T ::= int | bool | char

L ::= { id , } id

Foco

de

aten

ción

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 9

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontexto

Derivacióngrama8cal

L = Lenguaje de operadores

Sea G = (T, N A, P) con

T = {+, -, *, /, n}

N = {E}

P = {

E ::= E + E

E ::= E - E

E ::= E * E

E ::= E / E

E ::= n

}

Se plantea el siguiente problema de decisión: Dado un lenguaje descrito a través de una gramática G, L(G) determinar si la colección de terminales x pertenece o no al lenguaje al mismo. Esto es ¿x Є L (G)?

E → E + E → n + E → n + E * E → n + n * E → n + n * n

axioma

Paso de derivación

asidero

Frase F o r m a de frase

Cadena de derivación

2+3*5

De manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

(2) (3) (5)

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 10

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Derivacióngrama8calSe plantea el siguiente problema de decisión: Dado un lenguaje descrito a través de una gramática G, L(G) determinar si la colección de terminales x pertenece o no al lenguaje al mismo. Esto es ¿x Є L (G)?

Cadena de derivación

Secuencia de pasos de derivación que parten del axioma gramatical para intentar alcanzar la frase analizada x. Demostración de x Є L (G)

Frase Secuenc ia de t e rm ina les que pertenece al lenguaje definido por la gramática. Si x Є L (G), x es frase de L

Forma de frase

Secuencia de terminales y no terminales que representa una colección de frases del lenguaje. Existe una cadena de derivación que llega hasta ella

Axioma Forma de frase más abstracta que representa a L (cualquier derivación de Si x Є L (G) comienza por el axioma)

Asidero Parte izquierda de cualquier forma de frase de x Є L (G) formada únicamente por símbolos terminales

Paso de derivación

Aplicación de una regla de producción que transforma una forma de frase más general en otra más especifica para x

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 11

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Derivacióngrama8calSe plantea el siguiente problema de decisión: Dado un lenguaje descrito a través de una gramática G, L(G) determinar si la colección de terminales x pertenece o no al lenguaje al mismo. Esto es ¿x Є L (G)?

E → E + E →

n + E →

n + E * E →

n + n * E →

n + n * n ¿ En qué orden se aplican las reglas?

Left Most Derivation En cada paso de derivación se escoge el no terminal más a la izquierda de la forma de frase a derivar

Right Most Derivation En cada paso de derivación se escoge el no terminal más a la derecha de la forma de frase a derivar

E → E + E →

E + E * E →

E + E * n →

E + n * n →

n + n + n

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 12

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Árbolesdeanálisissintác8coyarbolessintác8cosabstractosFrecuentemente no es preciso reflejar el orden de aplicación de las derivaciones sino solamente el proceso de derivación desde el axioma a la frase final. Para ello se interpreta cada regla como un árbol con raíz en el antecedente e hijos los símbolos terminales y no terminales del consecuente de la regla

2+3*5

L = Lenguaje de operadores

Sea G = (T, N A, P) con

T = {+, -, *, /, n}

N = {E}

P = {

R1: E ::= E + E

R2: E ::= E - E

R3: E ::= E * E

R4: E ::= E / E

R5: E ::= ( E )

R6: E ::= n

}

E

E + E

n E * E

n n (2)

(3) (5)

R1

R3

R6

antecedente

consecuente

frase

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 13

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Árbolesdeanálisissintác8coyarbolessintác8cosabstractosExisten dos tipos de representaciones arborescentes que se utilizan frecuentemente para representar las derivaciones de una frase de un lenguaje.

Tipos de árboles sintácticos

Arboles de análisis sintáctico Los hijos de cada regla son una representación exacta de la colección de terminales y no terminales que aparecen en el consecuente de la misma

Arboles sintácticos abstractos Se hace una representación abstracta de la gramática de tal manera que en los hijos del árbol solo aparecen los símbolos semánticamente relevantes

Foco de atención de la asignatura

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 14

If(a>b)thena:=belseb:=aIf(a>b)thena:=belseb:=a(2+3)*5

(2+3)*5

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Árbolesdeanálisissintác8coyarbolessintác8cosabstractos

Arbolesdeanálisissintác8co Arbolessintác8cosabstractos

E

E * E

( E ) n

E + E

n n

*

+ n

n n

IF

> := :=

ID ID ID ID

SIf

IF ( E ) THEN S ELSE S

E > E

while(a>b)doa++

SWhile

WHILE ( E ) DO S

E > E

while(a>b)doa++

WHILE

> ++

ID ID ID

ID ID

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 15

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Ejercicios

›  L1. Declaración de variables en Pascal

›  L2. Declaración de estructuras en C

›  L3. Declaración de procedimientos en Pascal

›  L4. Declaración de procedimientos en C

›  L5. Declaración de sentencias en C

›  L6. Declaración de sentencias en Pascal

›  L7. Sentencia for en C

›  L8. Sentencia Repeat – Until en Pascal

Sentencia ::= BloqueSentencias |

SentenciaIf |

Sentencia While

BloqueSentencias ::= { listaSentencias }

listaSentencias ::= sentencia ; ListaSentencias |

ع

SentenciaIf ::= …

SentenciaWhile ::= …

L5

Construya arboles de análisis sintáctico para frases en cada uno de los lenguajes anteriores

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 16

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Limpiezagrama8calPara no tener problemas en la construcción de analizadores sintácticos es conveniente aplicar ciertas operaciones de trasformación gramatical. Estos problemas son:

Limpieza gramatical

Eliminación de la ambigüedad Es necesario eliminar las expresiones gramaticales que generen una interpretación potencialmente gramatical ambigua

Factorización por la izquierda Las reglas con partes comunes a la izquierda de los consecuentes pueden también generar problemas, en función del analizador que se construya

Eliminación de la recursividad a izquierdas En algunos casos las reglas con recursividad a izquierdas de la forma A ::= A α pueden acarrear problemas en la construcción de analizadores

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 17

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Ambigüedadgrama8cal

R1: E ::= E + E

R2: E ::= E - E

R3: E ::= E * E

R4: E ::= E / E

R5: E ::= ( E )

R6: E ::= n

E

E + E

n E * E

n n

(2)

(3) (5)

E

E * E

E + E

n n (2) (3)

(5)

n

2+3*5Interpretación 1 Interpretación 2

Una gramática es inherentemente ambigua cuando es posible construir dos arboles de derivación para al menos una frase del lenguaje

¿Cuál es el problema?

Ambos árboles son sintácticamente c o r r e c t o s p e r o r e s p o n d e n a interpretaciones semánticamente diferentes, una válida y la otra no, con respecto a la semánt ica operacional matemática

} ü û

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 18

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Fuentesdeambigüedadgrama8calPara demostrar que una gramática es ambigua es suficiente con encontrar dos árboles de derivación diferentes para una misma frase. Sin embargo no existe ninguna manera de demostrar que una gramática no es ambigua. Existen criterios heurísticos que identifican fuentes de potencial ambigüedad

S::=AS::=aA::=S

E::=E…E

S:=AS:=BA:=B

S::=HRSS::=sH::=h|εR::=r|ε

S::=HRH::=h|εH::=h|ε

Gramáticas con ciclos

Reglas con igual principio y fin

Caminos alternativos

Reglas recursivas con ε en casos base

No terminales que derivan ε

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 19

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Correccióndelaambigüedadgrama8calLa forma gramatical puede inducir una interpretación semánticamente invalidada por ello es necesario introducir correcciones para evitar la ambigüedad

Corrección de la ambigüedad gramatical

Corrección explicita Se mantiene la gramática ambigua pero se añaden criterios para indicar al compilador el árbol sintáctico que debe construir en cada caso

Alteración gramatical Se modifica la gramática para conseguir otra equivalente que no presente ambigüedad.

La resolución explicita hace escoger este árbol gramatical

}

Dos gramáticas son equivalentes si reconocen el mismo lenguaje

}

Ambigüedad no esencial Hay situaciones en las que la ambigüedad no presenta problemas para construir analizadores sintácticos

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 20

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

CasosZpicosdeambigüedadgrama8calDado que resulta imposible de resulta imposible ofrecer un algoritmo para descubrir y remediar la ambigüedad gramatical analizaremos casos arquetípicos de ambigüedad que suelen aparecen en los lenguajes de programación

Estudio de casos típicos

de ambigüedad

Gramática de operadores La gramática canónica de operadores es inherentemente ambigua ya que no se sabe el orden en que deben aplicarse los operadores

El problema del else ambiguo Cuando se anidan una sentencia if con otra if–else es imposible saber a qué if emparejar el else.

2 + 3 * 5

If (a>b) if (c>d) c++; else d++;

2 + (3 * 5) (2 + 3) * 5

If (a>b) {

if (c>d) c++;

else d++;

}

If (a>b) {

if (c>d) c++;

}

else d++;

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 21

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Correccióndelaambigüedadengramá8casdeoperadoresLas gramáticas canónicas de operadores son inherentemente ambiguas. Para corregir este hecho es necesario inyectar información sobre la precedencia y la asociatividad de los operadores

Alteraciones gramaticales

Precedencia de operadores La precedencia de operadores indica la prioridad de aplicación de los operadores para combinar subexpresiones en una mayor

Asociatividad de operadores Cuando tres o mas subexpresiones se combinan a través de un mismo operador tiene sentido definir la asociatividad del mismo

E ::= E @ E

E ::= E # E

E ::= E & E

E ::= E % E

E ::= ( E )

E ::= n

Gramática canónica de operadores sobre operadores {@, #, $, %}

A # B & C

(A # B) & C A # (B & C)

# > & & > #

A # B # C

A # (B # C) (A # B) #C

a derechas a izquierdas

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 22

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Correccióndelaambigüedadengramá8casdeoperadoresLas gramáticas canónicas de operadores son inherentemente ambiguas. Para corregir este hecho es necesario inyectar información sobre la precedencia y la asociatividad de los operadores

Precedencia de operadores Se ordena en una tabla los niveles de prioridad. Para cada nivel se define un nuevo no terminal. Cada nivel incrementa en 1 la distancia al axioma

+ –

* /

( ) n

+ pr

eced

enci

a -

E ::= E + E

E ::= E – E

E ::= E * E

E ::= E / E

E ::= ( E )

E ::= n

E ::= E + T | E – T | T

T ::= T * F | T / F | F

F ::= ( E ) | n

Gramática de operadores no ambigua

E

E + T

T * F

(2) (3)

(5)

n

2+3*5

T

F F

n

n

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 23

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

Correccióndelaambigüedadengramá8casdeoperadoresLas gramáticas canónicas de operadores son inherentemente ambiguas. Para corregir este hecho es necesario inyectar información sobre la precedencia y la asociatividad de los operadores

Asociatividad de operadores La recursividad a izquierdas marca asociatividad a izquierdas. La recursividad a derecha marca asociatividad a derechas

E ::= E + T | E – T | T

T ::= F * T | T / F | F

F ::= ( E ) | n

E

E + T

E + T

(5)

(2)

(3)

2+3+5

F

n

Gramática de operadores no ambigua

T

F

n

F

n

E

F * T

F * T (2)

(3)

(5)

2*3*5

n

n F

n

T

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 24

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

ElproblemadelelseambiguoDe las dos interpretaciones que presentábamos antes la correcta es la que asocia el else al if mas cercano (esta regla se llama regla de anidamiento más cercano. Veamos cómo es la gramática original y cómo debe transformarse

sentencia ::= sentenciaIf | otra

sentenciaIf ::= IF ( exp ) sentencia |

IF ( exp ) sentencia ELSE sentencia

Sentencia

… sentencia ::= sentEmparejada | sentNoEmparejada

sentEmparejada ::= IF ( exp ) sentEmparejada ELSE sentEmparejada |

otra

sentNoEmparejada ::= IF ( exp ) sentencia |

IF ( exp ) sentEmparejada ELSE sentNoEmparejada

SentNoEmparejada

IF ( exp ) sentencia

IF ( exp ) SentEmparejada ELSE SentEmparejada

SentEmparejada

… otra otra

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 25

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

EliminacióndelarecursividadporlaizquierdaLas reglas con recursividad por la izquierda de la forma A ::= Aα | β pueden presentar problemas a la hora de construir analizadores sintácticos por tanto es conveniente reformularlas equivalentemente

A ::= Aα | β

A ::= αA’

A’ ::= β A’ | ع

Recursividaddirecta

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

E ::= E + T | E – T | T

T ::= T * F | T / F | F

F ::= ( E ) | n

Gramática de operadores no ambigua Gramática de operadores LL (1)

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 26

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

EliminacióndelarecursividadporlaizquierdaLas reglas con recursividad por la izquierda de la forma A ::= Aα | β pueden presentar problemas a la hora de construir analizadores sintácticos por tanto es conveniente reformularlas equivalentemente

A →+ A NumerarlosnoterminalesA1,A2,…An

fori:=1tondo

forj:=1toi–1do

SustituircadaAi::=Ajγpor

Ai::=δ1γ|δ2γ|...|δkγdonde

Aj::=δ1|δ2|...|δksontodaslas

reglasactualesdeAjeliminarrecursividadporlaizquierdadeAi

Recursividadindirecta

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 27

Gramá6caslibresdecontexto

Especificaciónmediantegramá8caslibresdecontextoDe manera similar a como ocurre en los lenguajes regulares, los lenguajes libres de contexto se pueden expresar mediante el uso de gramáticas libres de contexto. Su definición es una extensión de las gramáticas regulares con reglas de producción potencialmente más complejas

FactorizaciónporlaizquierdaLas reglas con factores comunes por la izquierda en sus consecuentes de la forma A ::= α β1 | α β2 pueden generar problemas para construir analizadores sintácticos y conviene transformarlas

A ::= α β1 | α β2 | … | α βn | γ

A ::= αA’ | γ

A’ ::= β1 | β2 | … | βn

Ejemplo

SentenciaIf::=IF(exp)THENsentencia|

IF(exp)THENsentenciaELSEsentencia

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 28

Diagramasdesintaxis

EspecificaciónmediantediagramasdesintaxisLos diagramas de transición son una forma gráfica de representar las restricciones sintácticas de los lenguajes libres de contexto. Cada diagrama de sintaxis está etiquetada con el nombre de un no terminal al que representa y se compone de cajas y esferas que representan terminales y no terminales unidas por flechas que indican secuencias y selecciones .

E ::= E + T |

E - T |

T

T ::= T * F |

T / F |

F

F ::= ( E ) |

n

La equivalencia entre gramáticas y diagramas de sintaxis resulta evidente

T E

+

-T

F T

*

/F

Fn

( )E

}

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 29

Autómatasapiladeterministas

EspecificaciónmedianteautómatasapiladeterministasLos autómatas a pila son una extensión con memoria de los autómatas finitos deterministas que se utilizan para realizar analizadores sintácticos. Constan de una cinta de entra donde se leen los tokens del programa fuente, una pila de estados (la memoria) y una máquina de estados. Las transiciones de estados dependen ahora de la entrada y de la historia del proceso de análisis almacenada en la pila

DefinicióndeautómataapiladeterministaUn autómata a pila es una tupla AP = (T, P, Q, A0, q0, f, F) donde

›  T es un alfabeto de símbolos terminales de entrada

›  P es un alfabeto de estados de la pila

›  Q es un conjunto de estados finito no vacío

›  A0 Є P es el simbolo inicial en la pila

›  q0 Є Q es un estado inicial o estado de arranque

›  f: Q x T U { ع } x P → Q x P una función de transición

›  F C Q es un subconjunto de estados finales de aceptación

A

x, y

x

B

2

0

Máquina de estados

BA

CPila

de

esta

dos

Cinta de entrada

}

x

1

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 30

Autómatasapiladeterministas

EspecificaciónmedianteautómatasapiladeterministasLos autómatas a pila son una extensión con memoria de los autómatas finitos deterministas que se utilizan para realizar analizadores sintácticos. Constan de una cinta de entra donde se leen los tokens del programa fuente, una pila de estados (la memoria) y una máquina de estados. Las transiciones de estados dependen ahora de la entrada y de la historia del proceso de análisis almacenada en la pila

MovimientosenunautómataapiladeterministaUn movimiento de un autómata a pila consiste en consumir un elemento de la entrada (x), la cima de la pila (A) y transitar desde el estado en curso (0) a un nuevo estado (1) apilando un nuevo estado en la cima de la pila

A

x, y

x

B

2

0

Máquina de estados

BA

CPila

de

esta

dos

Cinta de entrada

}

x

1Reconocimientodelenguajes

Reconocimiento de lenguajes

Reconocimiento por estados finales Se reconoce una frase si tras una secuencia de movimientos se llega a un estado final de aceptación. El estado final de la pila no importa

Reconocimiento por vaciado de pila Se reconoce una frase si tras una secuencia de movimientos se llega a vaciar completamente la pila. El estado del autómata no importa

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 31

Autómatasapiladeterministas

EspecificaciónmedianteautómatasapiladeterministasLos autómatas a pila son una extensión con memoria de los autómatas finitos deterministas que se utilizan para realizar analizadores sintácticos. Constan de una cinta de entra donde se leen los tokens del programa fuente, una pila de estados (la memoria) y una máquina de estados. Las transiciones de estados dependen ahora de la entrada y de la historia del proceso de análisis almacenada en la pila

Clasificacióndeanalizadoressintác8cos

Ana

lizad

ores

si

ntác

ticos

Analizadores no deterministas

Son analizadores generales que imponen pocas restricciones sobre la naturaleza sintáctica del lenguaje. Suelen tener complejidad asintótica O (n3)

Analizadores deterministas

Son analizadores que imponen ciertas restricciones sobre la naturaleza de los lenguajes que soportan

Cualquier tipo de gramática

Analizadores en backtracking

Analizadores sintácticos descendentes

Se parte del axioma y se aplica una cadena de derivaciones para construir un árbol sintáctico

Gramáticas LL

Reconocimiento por vaciado de pila

Analizadores sintácticos ascendentes

Se parte de los terminales y se construye la inversa de una derivación para intentar alcanzar el axioma

Gramáticas LR

Reconocimiento por estados finales

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 32

BibliograUa

MaterialdeestudioBibliografía básica

Construcción de compiladores: principios y práctica

Kenneth C. Louden International Thomson Editores,

2004 ISBN 970-686-299-4

Javier Vélez Reyes [email protected]

Análisissintác8co.Lenguajeslibresdecontexto

3 - 33

BibliograUa

MaterialdeestudioBibliografía complementaria

Compiladores: Principios, técnicas y herramientas.

Segunda Edición Aho, Lam, Sethi, Ullman

Addison – Wesley, Pearson Educación, México 2008

Diseño de compiladores. A. Garrido, J. Iñesta, F. Moreno

y J. Pérez. 2002. Edita Universidad de Alicante

ProcesadoresdeLenguajesIngenieríaTécnicasuperiordeIngenieríaInformá8ca

DepartamentodeLenguajesySistemasinformá6cos

JavierVé[email protected]

DepartamentodeLenguajesYSistemasInformáAcosUNED

4Análisissintác*coIIAnalizadoresdescendentes

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 2

Obje6vos

Obje8vos

›  Conocer en qué consiste el análisis descendente

›  Conocer los tipos de analizadores descendentes que existen

›  Entender en qué consiste el análisis descendente predictivo

›  Aprender las condiciones necesarias sobre gramáticas para aplicar análisis predictivos

›  Aprender a transformar gramáticas para aplicar análisis predictivos

›  Entender el uso de los conjuntos de predicción

›  Aprender a construir conjuntos de predicción

›  Aprender a calcular los conjuntos Primeros

›  Aprender a calcular los conjuntos Siguientes

›  Aprender a construir y utilizar analizadores sintácticos predictivos

›  Aprender a construir analizadores predictivos recursivos

›  Aprender a construir analizadores predictivos dirigidos por tabla

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 3

Índice

Índice›  Introducción

›  Análisis sintáctico descendente con retroceso

›  Análisis sintáctico descendente predictivo

›  Conjuntos de predicción

›  Condiciones LL (1)

›  Construcción de los conjuntos de predicción

›  Conjuntos Primeros

›  Conjuntos Siguientes

›  Analizadores sintácticos descendentes predictivos

›  Analizador descendente predictivo recursivo

›  Analizados descendente predictivo dirigido por tabla

›  Gestión de errores en analizadores descendentes

›  Bibliografía

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 4

Introducción

¿Quéeselanálisisdescendente?

El análisis sintáctico descendente es una técnica de análisis sintáctico que intenta comprobar si una cadena x pertenece al lenguaje definido por una gramática L (G) aplicando los siguientes criterios

›  Partir del axioma de la gramática

›  Escoger reglas gramaticales estratégicamente

›  Hacer derivaciones por la izquierda (Left Most Derivation)

›  Procesar la entrada de izquierda a derecha

›  Obtener el árbol de análisis sintáctico o error

Cadenadederivación Árboldeanálisissintác8coEn cada paso de derivación se transforma siempre el no terminal más a la izquierda de la forma de frase

R1: E ::= E + E

R2: E ::= E - E

R3: E ::= E * E

R4: E ::= E / E

R5: E ::= ( E )

R6: E ::= n

E → E + E →

n + E →

n + E * E →

n + n * E →

n + n * n

Se parte del axioma gramatical y se van aplicando reglas estratégicamente hasta alcanzar la frase X como nodos hojas del árbol

E

E + E

n E * E

n n (2)

(3) (5)

R1

R3

R6

R6

R6 �

� �

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 5

Introducción

Analizadoressintác8cosdescendentes

Ana

lizad

ores

de

term

inis

tas

Analizadores descendentes Se parte del axioma y se apl ica una cadena de derivaciones para construir un árbol sintáctico

Analizadores ascendentes

Se parte de los terminales y se construye la inversa de una derivación para intentar alcanzar el axioma

Analizadores predictivos

Se determina qué regla aplicar a partir de un análisis de los primeros tokens a la entrada

Analizadores con retroceso

Se hace una búsqueda en profundidad con retroceso para garantizar que se encuentra la frase. Coste O (kn)

¿Como se selecciona el siguiente no terminal a derivar? }

¿Como se selecciona la regla de producción en cada paso de derivación?

Analizadores predictivos LL (1)

Determinan que regla de producción aplicar en cada paso en función de token que s e e n c u e n t r a e n c a d a momento en la cabeza de lectura

Analizadores predictivos LL (k)

Determinan que regla de producción aplicar en cada paso en función de los k p r imeros tokens que se encuentra en cada momento en la cabeza de lectura

}

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 6

Análisissintác6codescendenteconretroceso

Análisissintác8codescendenteconretrocesoEn el análisis sintáctico con retroceso se van probando una por una todas las reglas candidatas a ser aplicadas para construir el árbol de análisis sintáctico. Cuando una regla seleccionada falla, entonces se retrocede y se prueba con la siguiente regla

1.  Se selecciona un nuevo no terminal a derivar por la estrategia Left Most Derivation

2.  Se selecciona el conjunto de todas las reglas con antecedente igual al no terminal

3.  Se ordena el conjunto de reglas arbitrariamente

4.  Se selecciona una regla

1.  Se extrae la regla del conjunto

2.  Se aplica la derivación por dicha regla

3.  Si la regla encaja volver a 1 sino retroceder la derivación y volver a 4

r1. S ::= c A d

r2. A ::= a b

r3. A ::= a

S

c A d

S

c A d

c a d

S

c a d

a b

S

c A d

a

c a d

r1 r2 r3

retroceso }

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 7

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

Analizadores predictivos

Se determina qué regla aplicar a partir de un análisis de los primeros tokens a la entrada

Analizadores predictivos LL (1)

Determinan que regla de producción aplicar en cada paso en función de token que se encuentra en cada momento en la cabeza de lectura

LL (k)

Derivación más a la izquierda (Left Most Derivatión)

Lectura de izquierda a derecha

Número de terminales consultados para determinar la regla de producción a aplicar

Analizadores predictivos LL (k)

Determinan que regla de producción aplicar en cada paso en función de los k primeros tokens que se encuentra en cada momento en la cabeza de lectura

Lenguajes LL (K)

Lenguajes LL (1)

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 8

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

ConjuntosdepredicciónPara aplicar el análisis descendente predictivo LL (1) es necesario asociar a cada regla de producción un conjunto de predicción. El conjunto de predicción de una regla está formado por la colección de todos los posibles terminales que es necesario encontrar en la cabeza de lectura para poder aplicar dicha regla

A → a b B

a b c Entrada

Derivación

r1. A ::= a b B { a }

r2. A ::= B { b, c }

r3. B ::= b { b }

r4. B ::= c { c }

}

De todas las reglas candidatas para el no terminal en curso se escoge aquella que contiene en su conjunto de predicción el terminal a la entrada

A → a b B

a b c }

A → a b B → a b c

a b c

}

r1. A ::= a b B { a }

r2. A ::= B { b, c }

r3. B ::= b { b }

r4. B ::= c { c }

r1. A ::= a b B { a }

r2. A ::= B { b, c }

r3. B ::= b { b }

r4. B ::= c { c }

}

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 9

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

CondicionesLL(1)Para poder aplicar el análisis descendente predictivo LL (1) es necesario que se cumplan las condiciones LL (1) que garanticen la predictibilidad absoluta a la hora de seleccionar una regla de producción:

r1. A ::= a b B { a }

r2. A ::= B { b, c }

r3. B ::= b { b }

r4. B ::= c { c }

Para poder aplicar el análisis predictivo LL (1) es necesario que los conjuntos de predicción de todas las reglas con un mismo antecedente

sean disjuntas entre sí

r1. A ::= a b B { a }

r2. A ::= B { b, c }

r3. B ::= b { b }

r4. B ::= c { c }

{ a } ∩ { b, c } = Ø LL (1) ü

{ b } ∩ { c } = Ø LL (1) ü

LL (1) ü

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 10

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

CondicionesLL(1)Para cumplir las condiciones LL (1) la gramática debe satisfacer necesariamente 3 requisitos:

›  No ambigua

›  Factorizada por la izquierda

›  No recursiva a izquierdas

Consúltese el tema 3 para obtener una descripción acerca de cómo se puede transformar una gramática para que cumpla estas restricciones

} E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

E ::= E + T | E – T | T

T ::= T * F | T / F | F

F ::= ( E ) | n

Gramática de operadores no ambigua

Gramática de operadores LL (1)

E ::= E + E

E ::= E – E

E ::= E * E

E ::= E / E

E ::= ( E )

E ::= n

Gramática de operadores canónica

� Eliminación de la ambigüedad � Factorización por la izquierda

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 11

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

ConstruccióndelosconjuntosdepredicciónLa construcción de los conjuntos de predicción de una regla A ::= α se apoya en el uso de dos conjuntos asociados respectivamente a la parte derecha e izquierda de la regla:

›  Primeros (α) devuelve el conjunto de todos los terminales que se

pueden encontrar a la cabeza de cualquier derivación

de la frase α

›  Siguientes (A) devuelve el conjunto de todos los terminales que se

pueden encontrar siguiendo a A en cualquier derivación

posible

α

... aβ

βAa

γAb

δAc

...

...

...

...

...

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 12

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

ConstruccióndelosconjuntosdepredicciónLa construcción de los conjuntos de predicción de una regla A ::= α se apoya en el uso de dos conjuntos asociados respectivamente a la parte derecha e izquierda de la regla:

Predicción ( A ::= α ) =

Si ع Є Primeros ( α ) entonces = Primeros ( α ) – { ع } ∪ Siguientes ( A)

Sino = Primeros( α )

βAγ βAγ

ab

βAγ βAγ

entonces ع Si α no deriva en عPredicción (A ::= α) = Primeros (α) } Si α puede derivar en ع

entonces Predicción (A ::= α) incluye Siguientes (α)

}

� �

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 13

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

ConjuntosprimerosSi α es una forma de frase compuesta por una concatenación de símbolos Primeros (α) es el conjunto de terminales incluyendo potencialmente ع que pueden aparecer iniciando las cadenas que derivan de α

α

... aβ

...

...

Primeros (ع { = )ع }

Primeros (a) = {a}

Primeros (A) = ∪ Primeros (αi) Para todo A := αi

Primeros (Aα) =

si ع Є Primeros (A), = Primeros (A) – { ع } U Primeros (α)

sino, = Primeros (A)

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

EjercicioCalcular el conjunto Primeros para todas las reglas de la siguiente gramática

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 14

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

ConjuntosSiguientesSi A es un símbolo no terminal de la gramática SIG (A) es el conjunto de terminales potencialmente incluyendo $1 que pueden aparecer a continuación de A en alguna forma de frase derivada del axioma

1 $ representa el carácter fin de fichero

1.  Inicialmente

Siguiente (A) = { }

2. Si A es el axioma

Siguiente (A) = Siguiente (A) ∪ { $ }

3. Para cada regla B := α A β

Siguiente (A) = Siguiente (A) ∪ { Primeros (β) – { ε } }

4. Para cada regla B := α A o B:= α A β con ε є Primeros (β)

Siguiente (A) = Siguiente (A) ∪ Siguiente (B)

5. Repetir 3 y 4 hasta que no se aumentar Siguiente (A)

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

EjercicioCalcular el conjunto Siguientes para todas las reglas de la siguiente gramática

βAa

γAb

δAc

...

...

...

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 15

Análisissintác6codescendentepredic6vo

Análisissintác8codescendentepredic8voLos analizadores sintácticos predictivos son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LL (K)

EjerciciosComprobar el cumplimiento de las condiciones LL (1) para las siguientes gramáticas

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

S ::= A a | b

A ::= A c | S d

S ::= A a | b

A ::= A c | S d | ع

S ::= A B | s

A ::= a S c | e B f | ع

B ::= b A d | ع

A ::= A a | B C D

B ::= b | ع

C :: = c | ع

D ::= d | Ce

A ::= A a | B C D

B ::= b | ع

C :: = c | ع

D ::= d | Ce | ع

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 16

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

Analizadores descendentes predictivos

Tratarán de encontrar la cadena de entrada partiendo del axioma y aplicando pasos de derivación. La selección de reglas está dirigida por los conjuntos de predicción

Analizadores descendentes recursivos

Para dar soporte a la pila se utilizan las capacidades de recursión del lenguaje. La gramática queda expresada a través de llamadas explicitas a distintas funciones asociadas a los no terminales

Analizadores descendentes dirigidos por tabla

La pila se da soporte a través de una representación explicita. La selección de reglas se realiza con ayuda de una tabla que representa la gramática del lenguaje

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 17

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesrecursivosPara dar soporte a la pila se utilizan las capacidades de recursión del lenguaje. La gramática queda expresada a través de llamadas explicitas a distintas funciones asociadas a los no terminales

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

voidmatch(Terminaltoken){

if(cabeza==token)cabeza=scanner.nextToken();

elsethrownewSyntaxError();

}

voide(){

t();

ePrima();

}

voidePrima(){

if(!(cabezain{‘+’,‘-’})thrownewSyntaxError();

switch(cabeza){

case‘+’:match(‘+’);

t();

ePrima();

break;

Ejemplo

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 18

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesrecursivosPara dar soporte a la pila se utilizan las capacidades de recursión del lenguaje. La gramática queda expresada a través de llamadas explicitas a distintas funciones asociadas a los no terminales

case‘-’:match(‘-’);

t();

ePrima();

break;

default:break;

}

}

voidt(){

f();

tPrima();

}

voidtPrima(){

if(!(cabezain{‘*’,‘/’,‘+’,‘-’})thrownew

SyntaxError();

switch(cabeza){

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 19

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesrecursivosPara dar soporte a la pila se utilizan las capacidades de recursión del lenguaje. La gramática queda expresada a través de llamadas explicitas a distintas funciones asociadas a los no terminales

case‘*’:match(‘*’);

f();

tPrima();

break();

case‘/’:match(‘/’);

f();

tPrima();

break();

default:break;

}

}

voidf(){

switch(cabeza)

case‘(’:e();

match(‘)’);break;

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 20

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesrecursivosPara dar soporte a la pila se utilizan las capacidades de recursión del lenguaje. La gramática queda expresada a través de llamadas explicitas a distintas funciones asociadas a los no terminales

casen:match(n);

break;

default:thrownewSyntaxError();

}

}

Tokencabeza;

Scannerscanner=newScanner(file);

main(){

cabeza=scanner.nextToken();

e();

}

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 21

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesrecursivosPara dar soporte a la pila se utilizan las capacidades de recursión del lenguaje. La gramática queda expresada a través de llamadas explicitas a distintas funciones asociadas a los no terminales

2 + 3 * 5

e

}

2 + 3 * 5

ePrima

}

t tPrima

f

2 + 3 * 5

}

tPrima

+ 3 * 5

}

3 * 5

}

3 * 5

ePrima

}

tPrima

t

tPrima

* 5

}

t

tPrima

5

}

t

ePrima ePrima

f f

t

tPrima

$

}

t

}

$

}

$

Ok!

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 22

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesrecursivosPara dar soporte a la pila se utilizan las capacidades de recursión del lenguaje. La gramática queda expresada a través de llamadas explicitas a distintas funciones asociadas a los no terminales

Ventajas

›  Fácil de entender e interpretar

›  Gramática explícitamente representada

›  Cada función representa un no terminal

›  Adecuado para gramáticas sencillas

Inconvenientes

›  Pesado de desarrollar y mantener

›  Específico para cada lenguaje

›  Coste computacional (recursividad)

›  No da soporte a gran número de lenguajes

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 23

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesdirigidosportablaLos analizadores descendentes dirigidos por tabla están constituidos por dos elementos que se utilizan para llevar a cabo el proceso de análisis sintáctico

›  Una pila, donde se almacenan símbolos gramaticales

›  Una tabla de doble entrada que representa la gramática

›  En columnas el conjunto de terminales T U { $ }

›  En filas el conjunto de no terminales N

›  M ( t, n ) = la regla que debe aplicarse

Tabla gramatical (M)

Pila

Cinta de entrada

}

x

$

T

N r n,t

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 24

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesdirigidosportablaEl algoritmo de análisis descendente predictivo para este tipo de analizadores consiste en ir consultando la tabla para saber que regla aplicar y apoyarse en la pila asociada:

cabeza=<<primerterminaldew$>>

pila=[$,Axioma]

do{

p=pila.cima()

a=scanner.nextToken()

if(pinTU{$})

id(cabeza==a){

cabeza=scanner.nextToken()

pila.pop()

}elsenewthrowSyntaxError();

else{

if(M(p,a)==X::=Y1...Yk){

pop()

for(i=k;i>=1;i++)push(Yi)

}elsethrownewSyntaxError();

}

while(p!=‘$’)

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 25

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesdirigidosportablaEl algoritmo de análisis descendente predictivo para este tipo de analizadores consiste en ir consultando la tabla para saber que regla aplicar y apoyarse en la pila asociada: T

E’

E

T’

F

TE’

+ - * / ( ) n $

TE’

-TE’+TE’ ع ع

FT’FT’

ع ع *FT’ /FT’ ع ع

n(E)

- -- -

- -- -

- -- -

- --

-

-

- -

-

-

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

$E

$E’T

$E’T’F

$E’T’n

$E’T’

$E’

Pila

n+n*n$

n+n*n$

n+n*n$

n+n*n$

+n*n$

+n*n$

Entrada

E::=TE’

T::=FT’

F::=n

match(n)

T’::=ع

E’::=+TE’

Acción

-

-

--

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 26

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesdirigidosportablaEl algoritmo de análisis descendente predictivo para este tipo de analizadores consiste en ir consultando la tabla para saber que regla aplicar y apoyarse en la pila asociada: T

E’

E

T’

F

TE’

+ - * / ( ) n $

TE’

-TE’+TE’ ع ع

FT’FT’

ع ع *FT’ /FT’ ع ع

n(E)

- -- -

- -- -

- -- -

- --

-

-

- -

-

-

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

$E’T+

$E’T

$E’T’F

$E’T’n

$E’T’

$E’T’F*

Pila

+n*n$

n*n$

n*n$

n*n$

*n$

*n$

Entrada

match(+)

T::=FT’

F::=n

match(n)

T’::=*FT’

match(*)

Acción

-

-

--

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 27

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesdirigidosportablaEl algoritmo de análisis descendente predictivo para este tipo de analizadores consiste en ir consultando la tabla para saber que regla aplicar y apoyarse en la pila asociada: T

E’

E

T’

F

TE’

+ - * / ( ) n $

TE’

-TE’+TE’ ع ع

FT’FT’

ع ع *FT’ /FT’ ع ع

n(E)

- -- -

- -- -

- -- -

- --

-

-

- -

-

-

E ::= TE’

E’ ::= + TE’ | – TE’ | ع

T ::= FT’

T’ ::= * FT’ | / FT’ | ع

F ::= ( E ) | n

Ejemplo

$E’T’F

$E’T’n

$E’T’

$E’

$

Pila

n$

n$

$

$

$

Entrada

F::=n

match(n)

T’::=ع

E’::=ع

Ok!

Acción

-

-

--

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 28

Analizadoressintác6cosdescendentespredic6vos

Analizadoressintác8cosdescendentespredic8vosLos analizadores sintácticos descendentes predictivos son autómatas a pila deterministas que reconocen las frases de un lenguaje por la estrategia de vaciado de pila. En esta sección estudiaremos dos tipos distintos de analizadores descendentes predictivos que se diferencian en la forma de implementar el autómata y dar soporte a la pila

AnalizadoresdescendentesdirigidosportablaEl algoritmo de análisis descendente predictivo para este tipo de analizadores consiste en ir consultando la tabla para saber que regla aplicar y apoyarse en la pila asociada

Ventajas

›  Ágil de desarrollar y mantener

›  Representación tabular de las reglas

›  Bajo coste computacional (no recursividad)

›  Adecuado para gramáticas sencillas

Inconvenientes

›  Más complejo de interpretar

›  Gramática no explícitamente representada

›  Reglas distribuidas en la tabla

›  No da soporte a gran número de lenguajes

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 29

Ges6óndeerroresenanalizadoresdescendentes

Ges8óndeerroresLa labor de un analizador sintáctico no se limita exclusivamente a reconocer que una frase pertenece al lenguaje generado por una gramática. Adicionalmente, en el caso de que existan errores sintácticos (o léxicos no reconocidos en la fase de análisis léxico), el analizador debe ser capaz de reconocer errores y emitir mensajes de información asociados

I.Iden8ficacióndeerrores

II.Localizacióndeerrores

El reconocimiento de la existencia de un error debe realizarse lo más temprano posible dentro del proceso de análisis sintáctico. No hacerlo así puede provocar que el analizador abandone el contexto sintáctico donde éste se ha producido lo c u a l p r o v o c a m e n s a j e s d e e r r o r inadecuados

La gest ión de errores conl leva la localización de los mismos dentro del código fuente de la manera más precisa posible. El mensaje de error generado deberá contener información detallada y correcta acerca del número de fila y columna donde se encuentra el error

III.Emisióndemensajes

II.Recuperacióndeerrores

La existencia de errores se comunica al programación a través de la emisión de mensajes de error. Estos mensajes deben ser lo más específicos posibles de manera que el propio mensaje de información acerca de que acción correctiva debe ser aplicada

El analizador sintáctico no debe abortar el proceso de compilación al encontrar un error sino que debe escapar del contexto sintáctico de error para avanzar a una nueva situación estable. Esta técnica se reconoce por el nombre recuperación de errores

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 30

Ges6óndeerroresenanalizadoresdescendentes

Ges8óndeerroresLa labor de un analizador sintáctico no se limita exclusivamente a reconocer que una frase pertenece al lenguaje generado por una gramática. Adicionalmente, en el caso de que existan errores sintácticos (o léxicos no reconocidos en la fase de análisis léxico), el analizador debe ser capaz de reconocer errores y emitir mensajes de información asociados

Recuperacióndeerroresenanálisissintác8codescendentepredic8vo

Recuperacióndeerroresenanálisissintác8codescendentedirigidoportabla

Al identificar un error sintáctico se entra en estado de pánico y el analizador empieza a consumir tokens hasta encontrar un contexto de compilación estable, escapando del error. La identificación del contexto estable se dirige por conjuntos de sincronización asociados a cada tipo de error. El compilador consumirá tokens hasta encontrar un token perteneciente al conjunto de sincronización. El conjunto de sincronización suele construirse a partir de Primeros y Siguientes

Wile(a>b)a++;

}

El proceso de recuperación de errores es esencialmente el mismo que en los analizadores descendentes recursivos. La tabla contiene ahora información para gestionar los errores. En las celdas de error pueden aparecer 3 acciones de recuperación

›  Extraer el no terminal de la cima de la pila

›  Consumir tokens en estado de pánico dirigido por conjunto de sincronización

›  Insertar un nuevo terminal en la pila

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 31

BibliograCa

MaterialdeestudioBibliografía básica

Construcción de compiladores: principios y práctica

Kenneth C. Louden International Thomson Editores,

2004 ISBN 970-686-299-4

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresdescendentes

4 - 32

BibliograCa

MaterialdeestudioBibliografía complementaria

Compiladores: Principios, técnicas y herramientas.

Segunda Edición Aho, Lam, Sethi, Ullman

Addison – Wesley, Pearson Educación, México 2008

Diseño de compiladores. A. Garrido, J. Iñesta, F. Moreno

y J. Pérez. 2002. Edita Universidad de Alicante

ProcesadoresdeLenguajesIngenieríaTécnicasuperiordeIngenieríaInformá8ca

DepartamentodeLenguajesySistemasinformá6cos

JavierVé[email protected]

DepartamentodeLenguajesYSistemasInformáAcosUNED

5Análisissintác*coIIIAnalizadoresascendentes

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 2

Obje6vos

Obje8vos

›  Comprender el análisis ascendente por reducción desplazamiento

›  Aprender el algoritmo general de análisis ascendente

›  Conocer la arquitectura general de un analizador sintáctico ascendente

›  Aprender a construir analizadores ascendentes en complejidad creciente

›  Analizadores LR (0)

›  Analizadores SLR

›  Analizadores LALR

›  Analizadores LR (1)

›  Entender cómo los analizadores sintácticos realizan la gestión de errores

›  Entender los conflictos reducción – reducción

›  Entender los conflictos reducción – desplazamiento

›  Entender la clasificación de gramáticas inducida en virtud de los métodos de análisis empleados

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 3

Índice

Índice›  Introducción

›  Análisis sintáctico ascendente

›  Análisis ascendente por reducción – desplazamiento

›  Arquitectura general de análisis sintáctico ascendente

›  Algoritmo general de análisis sintáctico ascendente

›  Analizadores sintácticos ascendentes

›  Analizadores LR (0)

›  Analizadores LR (1)

›  Analizadores LALR

›  Analizadores LR (1)

›  Gestión de errores en analizadores ascendentes

›  Tipos de gramáticas y análisis ascendente

›  Interpretación de conflictos en los tipos de analizadores

›  Clasificación de gramáticas por tipos de analizadores

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 4

Índice

Índice›  Constricción de analizadores sintácticos en la práctica

›  ¿Qué es Cup?

›  ¿Cómo funciona Cup?

›  ¿Cómo se usa Cup?

›  Gestión de errores en Cup

›  Desarrollo paso a paso

›  Bibliografía

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 5

Introducción

¿Quéeselanálisisascendente?

El análisis sintáctico ascendente es una técnica de análisis sintáctico que intenta comprobar si una cadena x pertenece al lenguaje definido por una gramática L (G) aplicando los siguientes criterios

›  Partir de los elementos terminales de la frase x

›  Escoger reglas gramaticales estratégicamente

›  Aplicar a la inversa derivaciones por la derecha (Right Most Derivation)

›  Procesar la cadena de izquierda a derecha

›  Intentar alcanzar el axioma para obtener el árbol de análisis sintáctico o error

Cadenadederivación Árboldeanálisissintác8coEl análisis ascendente genera una cadena de derivación por la derecha leída en sentido inverso

R1: E ::= E + E

R2: E ::= E - E

R3: E ::= E * E

R4: E ::= E / E

R5: E ::= ( E )

R6: E ::= n

n + n * n ←

E + n * n ←

E + E * n ←

E + E * E ←

E + E ←

E

Se parte la cadena de entrada leída de izquierda a derecha y se aplican reglas a la inversa para intentar alcanzar el axioma

E

E + E

n E * E

n n (2)

(3) (5)

R1

R3

R6

R6

R6

� �

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 6

Introducción

Analizadoressintác8cosascendentes

Analizadores deterministas

Analizadores descendentes Se parte del axioma y se apl ica una cadena de derivaciones para construir un árbol sintáctico

Analizadores ascendentes

Se parte de los terminales y se construye la inversa de una derivación para intentar alcanzar el axioma

LR (0)

Determinan la regla que hay que aplicar sin consultar terminales a la entrada

¿Como se selecciona el siguiente no terminal a derivar? } ¿Como se selecciona la regla de

producción en cada paso de derivación inversa? }

SLR

Determinan la regla a apl icar consultado el pr imer terminal a la entrada

LALR

LR (1)

LR (k)

Determinan la regla a aplicar consultando los k primeros terminales a la entrada

Son analizadores que i m p o n e n c i e r t a s restricciones sobre la n a t u r a l e z a d e l o s lenguajes que soportan

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 7

Análisissintác6coascendente

Análisissintác8coascendente

LR (k)

Derivación más a la derecha (Right Most Derivatión)

Lectura de izquierda a derecha

Número de terminales consultados para determinar la regla de producción a aplicar

Lenguajes LR (k) Lenguajes

LR (1) Lenguajes LALR Lenguajes

SLR Lenguajes LR (0)

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 8

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendenteLos analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

2 operaciones

A cada paso el analizador decide realizar una de dos operaciones posibles

Desplazar

Reducir

Análisisporreducción–desplazamiento

El analizador debe procesar un número suficiente de terminales desplazando la cabeza lectora antes de a p l i c a r u n a r e g l a d e producción a la inversa. Esta operación se llama desplazar

Cuando se reconoce en la forma de frase en curso un fragmento igual a la parte derecha de una regla se s u s t i t u y e é s t e p o r e l antecedente. Esta operación se llama reducir

r1. E ::= E + E

r2. E ::= E - E

r3. E ::= E * E

r4. E ::= E / E

r5. E ::= ( E )

r6. E ::= n mango

ddesplazar

rreducir

}

d

}

r

n + n * n n + n * n

}

d

E + n * n

}

d

E + n * n

}

r

E + n * n

}

d

E + E * n

}

d

E + E * n

}

r

E + E * n

} r

E + E * E

}

r

E + E E

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 9

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendente

2 tipos de conflictos

Pueden surgir en este proceso 2 tipos de conflictos que el analizador debe ser capaz de resolver

Reducción - reducción

El analizador puede tanto aplicar un paso de reducción como uno de desplazamiento

El analizador puede aplicar dos reglas distintas para realizar diferentes pasos de reducción

Reducción - desplazamiento

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

}

d

}

r

n + n * n n + n * n

}

d

E + n * n

}

d

E + n * n

}

r

E + n * n

}

d

E + E * n

}

d

E + E * n

}

r

E + E * n

} r

E + E * E

}

r

E + E E

mango

ddesplazar

rreducir

Análisisporreducción–desplazamiento

r1. E ::= E + E

r2. E ::= E - E

r3. E ::= E * E

r4. E ::= E / E

r5. E ::= ( E )

r6. E ::= n

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 10

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendente

Arquitecturageneraldeanálisissintác8coascendente

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

El analizador sintáctico puede atravesar, a lo largo del proceso de análisis, distintos estadios de compilación que dependen del lenguaje analizado. Estos estadios se identifican con estados codificados numéricamente que se gestionan en una pila. En cada momento el estado en curso aparece en la cima de la pila

Todos los tipos de analizadores sintácticos ascendentes tienen un mismo modelo de arquitectura que consta de 3 elementos: una pila de estados, una tabla de acciones y una tabla Ir-A

Pila

de

esta

dos

Cinta de entrada

}

x

Tabla de acciones Tabla Ir-A

I. Pila de estados

Pila

de

esta

dos

1

5

7

3

}

La diferencia entre los tipos de analizadores sintácticos estriba en cómo se construyen estas tablas y en el tipo de gramáticas (lenguajes) que admiten

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 11

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendente

Arquitecturageneraldeanálisissintác8coascendente

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

Todos los tipos de analizadores sintácticos ascendentes tienen un mismo modelo de arquitectura que consta de 3 elementos: una pila de estados, una tabla de acciones y una tabla Ir-A

Pila

de

esta

dos

Cinta de entrada

}

x

Tabla de acciones Tabla Ir-A

4

3

2

1

La diferencia entre los tipos de analizadores sintácticos estriba en cómo se construyen estas tablas y en el tipo de gramáticas (lenguajes) que admiten

}

Para cada estado y cada terminal (o $) a la entrada el analizador tiene información de que acciones debe realizar. Las operaciones posibles son:

II. Tabla de acciones 0

T

$

A i,j

›  dj Desplazar y apilar el estado j

›  rk Reducir por la regla r

›  e Emitir un error

›  Ok Aceptar la cadena de entrada

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 12

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendente

Arquitecturageneraldeanálisissintác8coascendente

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

Todos los tipos de analizadores sintácticos ascendentes tienen un mismo modelo de arquitectura que consta de 3 elementos: una pila de estados, una tabla de acciones y una tabla Ir-A

Pila

de

esta

dos

Cinta de entrada

}

x

Tabla de acciones Tabla Ir-A

4

3

2

1

La diferencia entre los tipos de analizadores sintácticos estriba en cómo se construyen estas tablas y en el tipo de gramáticas (lenguajes) que admiten

}

En el caso de aplicar reducción, y del estado de compilación en curso, esta tabla indica el estado que hay que apilar en función del antecedente de la regla de producción aplicada

III. Tabla Ir-A 0

N

J

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 13

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendente

Algoritmogeneraldeanálisissintác8coascendenteEl algoritmo de análisis sintáctico ascendente también es independiente del tipo de analizador que se utilice. Una vez que disponemos de la información de las tablas acción e ir-A se procede de la siguiente forma

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

pila=[0]

a=scanner.nextToken()

do{

s=pila.cima()

if(Acción[s,a]==dj){

pila.push(j)

a=scanner.nextToken()

}

}elseif(acción[s,a]==rk){

for(inti=0;i<longitud(partederechark);i++)

pila.pop()

p=pila.cima()

A=ParteIzquierda(rk)

pila.push(irA(p,A))

}elseif(Acción(s,a)=aceptar)return

elsethrownewSyntaxError()

}while(true)

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 14

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendente

Algoritmogeneraldeanálisissintác8coascendenteEl algoritmo de análisis sintáctico ascendente también es independiente del tipo de analizador que se utilice. Una vez que disponemos de la información de las tablas acción e ir-A se procede de la siguiente forma

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

Ejemplo

0 1 2 3 4 5 6 7 8 9 10

end begin codigo tipo id $

-

-

-

-

d8

-

-

-

r2

r3

-

-

d6

-

-

-

r5

-

-

-

-

-

-

-

-

d10

-

-

-

-

d3

-

-

d3

-

-

-

-

-

-

d4

-

-

d4

-

-

-

-

-

-

-

ok

-

-

-

-

-

r1

-

-

- r4 - - - -

1

5

2

7

9

S A B C

PILA ENTRADA ACCIÓN

0

04

043

047

02

026

02610

0269

025

0258

01

idtipobegincodigoend$

tipobegincodigoend$

begincodigoend$

begincodigoend$

begincodigoend$

codigoend$

end$

end$

end$

$

$

d4

d3

r4

r5

d6

d10

r3

r2

d8

r1

Ok

r0. S ::= S’ ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 15

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLa construcción de las tablas de análisis acción e ir-A para cada uno de los cuatro tipos de analizadores sintácticos utilizan 4 tipos de conceptos. Éstos tienen una interpretación distinta para analizadores LR (0), SLR, LR (1) y LALR (1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

LR (0)

SLR

LALR

LR (1)

Elemento P. Viable F. Cierre F. Ir-A C. Canónica Autómata

LR (0)

LR (0)

LALR

LR (1)

LR (0)

LR (0)

LALR

LR (1)

LR (0)

LR (0)

LR (1)

LR (1)

LR (0)

LR (0)

LR (1)

LR (1)

LR (0)

LR (0)

LALR

LR (1)

LR (0)

LR (0)

LALR

LR (1)

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 16

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Elementos LR (0)

Prefijo viable LR (0)

Un elemento es una regla de producción que tiene un punto (.) en algún lugar de la parte derecha de la regla. El punto se utiliza para identificar el estado de avance de procesamiento de la regla

B ::= • a A

B ::= a • A

B ::= a A •

A := ع

B ::= a A

A := •

Un prefijo viable de un elemento corresponde con la forma de frase que queda a la izquierda del punto de dicho elemento. El prefijo viable identifica, de forma abstracta, la frase que se ha reconocido a la entrada y que valida, parcialmente, la selección de esa regla para proceder con la reducción

B ::= • a A B ::= a • A B ::= a A •

Prefijo viable

Elemento reductible

Elemento de comienzo

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 17

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(0)ySLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Conjunto de elementos LR (0)

Colección canoníca de los conjuntos de elementos LR (0)

Un conjunto de elementos es una colección no ordenada de elementos. Los conjuntos de e lementos se ut i l i zan para caracter izar formalmente los estados potenciales por lo que atraviesa un compilador a lo largo del proceso de análisis

I = { S’ ::= • S,

S ::= • ( S ) S,

S ::= • }

La colección de todos los conjuntos de elementos potenciales en los que se puede encontrar el analizador sintáctico se recoge en un conjunto llamado colección canónica de los conjuntos de elementos. Para su definición formal se utilizan dos funciones

S’ ::= S

S ::= ( S ) S | ع

Cierre ( I )

Ir- A (I, a)

Se cierra un conjunto para incluir todos los elementos que pueden alcanzarse a partir de uno dado

Se genera un nuevo conjunto a partir de I y del simbolo terminal o no terminal a

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 18

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Función Cierre ( I ) LR (0) El cierre de un conjunto I consiste en ampliar dicho conjunto con todos aquellos elementos con un punto al inicio de su parte derecha que son accesibles de forma directa o indirecta desde I

I0 = Cierre ( { S’ ::= • S } ) = {

S’ ::= • S,

S ::= • ( S ) S,

S ::= • }

S’ ::= S

S ::= ( S ) S | ع

Estar a punto de comenzar el procesamiento de S incluye estar a punto de procesar (S) S o ع

}

Cierre (I) = I

repetir

Para cada elemento A := α • B β є Cierre (I) hacer

Para cada B ::= δ1 | δ2 | … | δn hacer

Cierre (I) = Cierre (I) ∪ {B := • δi} para todo i = 1..n

hasta no se pueden añadir más elementos a Cierre (I)

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 19

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Función Ir-A ( I, a ) LR (0)

Ir-A ( I0, ‘(’ ) = Cierre ( { S ::= ( • S ) S } )

= { S ::= ( • S ) S,

S ::= • ( S ) S,

S ::= • }

S’ ::= S

S ::= ( S ) S | ع

La aplicación de la función Ir-A (I0, ‘(‘ ) indica cuál es la transición de estado que debe hacer el analizador sintáctico cuando se está en I0 y llega un token ‘(’ a la entrada

Ir-A es una función que toma un estado y un elemento a Є N U T y devuelve un nuevo estado. La operación consiste en avanzar el punto una posición sobre todos aquellos elementos en los que a preceda al punto. En los que no ocurra así se eliminan del conjunto. Finalmente se cierra el conjunto resultante

Para todo elemento B ::= α • Aβ є I con A Є N U T hacer

Ir-A (I, A) = Cierre ( { B ::= α A • β } )

}

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 20

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Colección canónica de los conjuntos de elementos C LR (0)

Se comienza por ampliar la gramática con la producción S’ ::= S donde S es el axioma y S’ es el nuevo axioma. Esto se hace para cubrir todas las alternativas de S. Después se aplica sistemáticamente el siguiente algoritmo hasta que C no pueda crecer más

Ampliar la gramática con S’ ::= S

C = Cierre ( { S’ ::= • S } ) = { I0 }

Para cada conjunto Ii є C Hacer

Para cada a є T ∪ N Hacer

Si existe un elemento B := α • a β є Ii

C = C ∪ Ir-A (Ii , a)

I0 = Cierre ({S' ::= •S}) = {S' ::= •S, S ::= •BA end, B::= •tipo, B ::= •id B}

I1 = IrA (I0, S) = Cierre ({S' ::= S•}) = {S' ::= S•}

I2 = IrA (I0, B) = Cierre ({S ::= B•A end}) = {S ::= B•A end, A ::= •begin C}

I3 = IrA (I0, tipo) = Cierre ({B ::= tipo•}) = {B ::= tipo•}

I4 = IrA (I0, id) = Cierre ({B ::= id•B}) = {B ::= id•B, B::= •tipo, B ::= •id B}

I5 = IrA (I2, A) = Cierre ({S ::= BA•end}) = {S ::= BA•end}

I6 = IrA (I2, begin) = Cierre ({A ::= begin•C}) = {A ::= begin•C, C ::= •codigo}

I7 = IrA (I4, B) = Cierre ({B ::= id B•}) = {B ::= id B•}

I8 = IrA (I4, tipo) = Cierre ({B ::= tipo•}) = {B ::= tipo•} = I3

I8 = IrA (I4, id) = Cierre ({B ::= id•B}) = {B ::= id•B, B::=•tipo, B::=•id B} = I4

I8 = IrA (I5, end) = Cierre ({S ::= BA end•}) = {S::= BA end•}

I9 = IrA (I6, C) = Cierre ({A ::= begin C•}) = {A ::= begin C•}

I10 = IrA (I6, codigo) = Cierre ({C ::= codigo•}) = {C ::= codigo•}

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 21

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Autómata reconocedor de prefijos viables LR (0)

De manera similar se puede construir un autómata reconocedor de prefijos viables donde cada Ii se corresponde con un Si y cada transición etiquetada con a de Si a Sj se corresponde con Ij = Ir-A (Ii, a)

S0 = Cierre( { S’ ::= • S } )

Para cada Si Hacer

Para cada a є N ∪ T Hacer

Si Existe B ::= α • aβ є Si Entonces

Crear estado nuevo Sn = Ir-A (Si, A

Crear transición de Si a Sn etiquetada con a

S'::=S•

S::=B•Aend,

A::=•beginC

B::=6po•

B::=id•B,

B::=•6po,

B::=•idB

S::=BA•end

A::=begin•C,

C::=•codigo

A::=beginC• C::=codigo•

S::=BAend•

4

1

2

3

5

8

6

9 10

B::=IdB•7

S

B

tipo

tipo

id B

A

begin

end

C codigo

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

S'::=•S,

S::=•BAend,

B::=•6po,

B::=•idB

id

0

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 22

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener C = {I0, I1, …, In}

Cada Ij є C se corresponde con el estado j del analizador

Construir la tabla Ir-A [s, A]

Si Ir-A (Ii, A) = Ij, A Є N Entonces Ir-A [i, A] = j

Construir la tabla Acción [s, a]

Para todo A ::= α • aβ Є Ii, a Є T Hacer

Si Ir-A (Ii, a) = Ij Entonces Acción [i, a] = dj

Para todo A ::= β • o A ::= • Є Ii Hacer

Acción [i, a] = rk

Si S’ ::= S • Є Ii entonces Acción [i, $] = Aceptar

Todas las demás entradas de Acción [k, s] = error

A partir de la colección canónica de elementos es posible construir las tablas de los analizadores LR (0)

›  Cada conjunto de elementos es un estado

›  La tabla Ir-A (I, A) A Є N refleja la función Ir-A

›  La tabla Ir-A (I, a) a Є T refleja los desplazamientos

›  Para los elementos de reducción

›  Se rellena todas las celda con reducción

TablasLR(0)apar8rdelacoleccióncanónica

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 23

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener El autómata reconocedor de prefijos viables

Cada estado Sj corresponde con el estado j

Construir la tabla Ir-A [s, A]

Si existe transición de Si a Sj con A, A Є N Entonces

Ir-A [i, A] = j

Construir la tabla Acción [s, a]

Para todo A ::= α • aβ Є Si, a Є T Hacer

Si existe transición de Si a Sj con a entonces

Acción [i, a] = dj

Para todo A ::= β • o A ::= • Є Si Hacer

Acción [i, a] = rk

Si S’ ::= S • Є Si entonces Acción [i, $] = Aceptar

Todas las demás entradas de Acción [k, s] = error

A partir del autómata reconocedor de prefijos viables es posible construir las tablas de los analizadores SLR

›  Cada estado del autómata es un estado

›  Transiciones Si a Sj con A Є N reflejan Ir-A

›  Transiciones Si a Sj con a Є T reflejan los desplazamientos

›  Para los elementos de reducción

›  Se calcula Siguientes del antecedente

›  Se rellena la cela con reducción por esa regla

TablasLR(0)apar8rdelautómatadeprefijosviables

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 24

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

Se rellena la tabla Ir-A a partir de las transiciones del autómata etiquetadas con no terminales

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 25

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

d3 d4

d6

d3 d4

d8

d10

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

Se rellenan los desplazamientos de la tabla de acción a partir de las transiciones del autómata etiquetadas con terminales

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 26

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

d3 d4

Ok

d6

r4 r4 r4 r4 r4 r4

d3 d4

d8

d10

r5 r5 r5 r5 r5 r5

r1 r1 r1 r1 r1 r1

r2 r2 r2 r2 r2 r2

r3 r3 r3 r3 r3 r3

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

Se rellenan las reducciones y la aceptación de la tabla Acción a partir de los estados de reducción

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 27

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

error error error d3 d4 error

error error error error error Ok

error d6 error error error error

r4 r4 r4 r4 r4 r4

error error error d3 d4 error

d8 error error error error error

error error d10 error error error

r5 r5 r5 r5 r5 r5

r1 r1 r1 r1 r1 r1

r2 r2 r2 r2 r2 r2

r3 r3 r3 r3 r3 r3

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

El resto de casillas se rellenan con error

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 28

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

VentajaseinconvenientesdelosanalizadoresLR(0)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Los analizadores sintácticos ascendentes del tipo LR (0) son los más sencillos de construir que existen pero el conjunto de gramáticas que reconocen es relativamente pequeño. En efecto, estos autómatas no utilizan ninguna estrategia predictiva en función de los terminales a la cabeza para dirigir los procesos de reducción

Ventajas

›  Fácil de entender y construir

›  La estrategia de reducción es sencilla

›  Cada estado de reducción es por 1 regla

›  Los errores se delegan a desplazamiento

Inconvenientes

›  Conjunto reducido de gramáticas

›  No aplica estrategias predictivas

›  No pueden existen 2 reducciones por estado

›  Mensajes de error menos localizados

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 29

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

DesdeelLR(0)haciaelSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Existe un tipo de analizadores sintácticos ascendentes más potentes que utiliza los mismos artefactos que el análisis LR (0) y que sin embargo es capaz de hacer reducciones predictivamente en función del terminal a la cabeza

Sólo si x Є Siguientes (A) aparece a la en la cabeza de

lectura en el momento en curso es legítimo aplicar la

reducción por el elemento reducible A ::= α •

Precisión de errores Mayor precisión de análisis Conjunto de gramáticas

Muchas celdas marcadas como reducción en LR (0) deberían ser consideradas como errores lo que redunda en una mayor precisión de los mensajes

Al predecir la reducción que debe producirse en función en la entrada se consigue afinar el proceso de análisis

Ahora en un mismo estado de puede haber ce ldas con distintas reducciones, con desplazamientos y con error con que las restr icciones gramaticales no son tan fuertes

S ::= a A b | A c

A ::= d e

A

d e

b A

d e

c a A

d e

f …

}

r

}

r

}

r

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 30

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Función cierre SLR

S’ ::= S

S ::= ( S ) S | ع

Para refinar el proceso de análisis sintáctico, los analizadores ascendentes del tipo SLR hacen un uso extendido del autómata de prefijos viables y la colección canónica de elementos LR (0) Sin embargo, los conceptos que manejan ambos tipos de analizadores son esencialmente los mismos

Elemento SLR

Prefijo viable SLR

Función Ir-A SLR

Colección canónica SLR

Autómata SLR

Función cierre LR (0)

Elemento LR (0)

Prefijo viable LR (0)

Función Ir-A LR (0)

Colección canónica LR (0)

Autómata LR (0)

=

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 31

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener C = {I0, I1, …, In}

Cada Ij є C se corresponde con el estado j del analizador

Construir la tabla Ir-A [s, A]

Si Ir-A (Ii, A) = Ij, A Є N Entonces Ir-A [i, A] = j

Construir la tabla Acción [s, a]

Para todo A ::= α • aβ Є Ii, a Є T Hacer

Si Ir-A (Ii, a) = Ij Entonces Acción [i, a] = dj

Para todo A ::= β • o A ::= • Є Ii Hacer

Para todo a Є Siguiente (A) hacer

Acción [i, a] = rk

Si S’ ::= S • Є Ii entonces Acción [i, $] = Aceptar

Todas las demás entradas de Acción [k, s] = error

A partir de la colección canónica de elementos es posible construir las tablas de los analizadores SLR

›  Cada conjunto de elementos es un estado

›  La tabla Ir-A (I, A) A Є N refleja la función Ir-A

›  La tabla Ir-A (I, a) a Є T refleja los desplazamientos

›  Para los elementos de reducción

›  Se calcula Siguientes del antecedente

›  Se rellena la celda con reducción por esa regla

TablasSLRapar8rdelacoleccióncanónica

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 32

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener El autómata reconocedor de prefijos viables

Cada estado Sj corresponde con el estado j

Construir la tabla Ir-A [s, A]

Si existe transición de Si a Sj con A, A Є N Entonces

Ir-A [i, A] = j

Construir la tabla Acción [s, a]

Para todo A ::= α • aβ Є Si, a Є T Hacer

Si existe transición de Si a Sj con a entonces

Acción [i, a] = dj

Para todo A ::= β • o A ::= • Є Si Hacer

Para todo a Є Siguiente (A) hacer

Acción [i, a] = rk

Si S’ ::= S • Є Si entonces Acción [i, $] = Aceptar

Todas las demás entradas de Acción [k, s] = error

A partir del autómata reconocedor de prefijos viables es posible construir las tablas de los analizadores SLR

›  Cada estado del autómata es un estado

›  Transiciones Si a Sj con A Є N reflejan Ir-A

›  Transiciones Si a Sj con a Є T reflejan los desplazamientos

›  Para los elementos de reducción

›  Se calcula Siguientes del antecedente

›  Se rellena la cela con reducción por esa regla

TablasSLRapar8rdelautómatadeprefijosviables

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 33

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

Se rellena la tabla Ir-A a partir de las transiciones del autómata etiquetadas con no terminales

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 34

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

d3 d4

d6

d3 d4

d8

d10

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

Se rellenan los desplazamientos de la tabla de acción a partir de las transiciones del autómata etiquetadas con terminales

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 35

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

d3 d4

Ok

d6

r4

d3 d4

d8

d10

r5

r1

r2

r3

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

Se rellenan las reducciones y la aceptación de la tabla Acción a partir de los estados de reducción y la información de los conjuntos Siguientes

Siguiente (B) = Primero (A end)

= Primero (A) = { begin }

Siguiente (S) = Siguiente (S’) = { $ } Siguiente (C) = Siguiente (A) = { end }

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 36

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploend begin código 6po id $

error error error d3 d4 error

error error error error error Ok

error d6 error error error error

error r4 error error error error

error error error d3 d4 error

d8 error error error error error

error error d10 error error error

error r5 error error error error

error error error error error r1

r2 error error error error error

r3 error error error error error

0

1

2

3

4

5

6

7

8

9

10

S A B C

1 2

5

7

9

El resto de casillas se rellenan con error

r0. S' ::= S

r1. S ::= B A end

r2. A ::= begin C

r3. C ::= codigo

r4. B ::= tipo

r5. B ::= id B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 37

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

VentajaseinconvenientesdelosanalizadoresSLR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Los analizadores sintácticos ascendentes del tipo SLR suponen una mejora con respecto a los del tipo LR (0) que refinan las condiciones de entrada que deben darse para poder hacer una reducción por una determinada regla

Ventajas

›  Fácil de entender y construir

›  Predice reducción mediante Siguientes

›  Varias reducciones por el mismo estado

›  Utiliza el mismo autómata LR (0)

Inconvenientes

›  Conjunto mayor pero reducido de gramáticas

›  Estrategia de reducción más compleja

›  No existen estados de (única) reducción

›  El autómata LR (0) no contempla predicción

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 38

d

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

DesdeelSLRhaciaelLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

El análisis predictivo que realizan los analizadores ascendentes del tipo SLR resulta demasiado tosco ya que aún se pueden afinar más los criterios de aplicación predictiva de desplazamientos

No todos los x Є T, ni siquiera los x Є Siguientes (B) a la

cabeza de la entrada en un momento dado son candidatos

viables para hacer un avance por el elemento A ::= α • B γ

S ::= A b | c B d

A ::= a B c | a B

B ::= d e

A

a c

b

B •

A

a

b

B•

A

a B •

Conjunto de gramáticas

Además de las características destacadas anteriormente, ahora la caracterización del conjunto de terminales que deben aparecer a la entrada para hacer un paso de derivación se ve más afinado. Esto impone menos restricciones gramaticales lo que permite articular un gran número de gramáticas

Precisión de errores

Como consecuencia también ocurre que la identificación de los tipos de errores, y sus mensajes asociados mejora ya que cada uno describe más precisamente el contexto sintáctico en el que se produce y los terminales que se deberían haber esperado

B

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 39

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Elementos LR (1)

Prefijo viable LR (1)

Un elemento LR (1) es un par formado por un elemento LR (0) y un terminal de búsqueda hacia delante. La idea es acarrear en cada elemento el terminal que debe encontrarse a la entrada a la hora de realizar la reducción. Debe pertenecer al conjunto Siguiente del antecedente

[ B ::= • a A, x]

[ B ::= a • A , x]

[ B ::= a A •, x]

A := ع

B ::= a A

[ A := •, x]

Un prefijo viable de un elemento corresponde con la forma de frase que queda a la izquierda del punto de dicho elemento. El prefijo viable identifica, de forma abstracta, la frase que se ha reconocido a la entrada y que valida, parcialmente, la selección de esa regla para proceder con la reducción

[B ::= • a A, x] [B ::= a • A, x] [B ::= a A •, x]

Prefijo viable

Elemento reductible

Elemento de comienzo

Para todo x Є Siguientes (B)

Terminal de búsqueda hacia delante

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 40

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Conjunto de elementos LR (1)

Colección canoníca de los conjuntos de elementos LR (1)

Un conjunto de elementos es una colección no ordenada de elementos. Los conjuntos de e lementos se ut i l i zan para caracter izar formalmente los estados potenciales por lo que atraviesa un compilador a lo largo del proceso de análisis

I = { [ S’ ::= • S , $ ],

[ S ::= • ( S ) , $ ],

[ S ::= • a , $ ] }

La colección de todos los conjuntos de elementos potenciales en los que se puede encontrar el analizador sintáctico se recoge en un conjunto llamado colección canónica de los conjuntos de elementos. Para su definición formal se utilizan dos funciones

S’ ::= S

S ::= ( S ) | a

Cierre ( I )

Ir- A (I, a)

Se cierra un conjunto para incluir todos los elementos que pueden alcanzarse a partir de uno dado

Se genera un nuevo conjunto a partir de I y del simbolo terminal o no terminal a

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 41

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Función Cierre ( I ) LR (1) El cierre de un conjunto I consiste en ampliar dicho conjunto con todos aquellos elementos con un punto al inicio de su parte derecha que son accesibles de forma directa o indirecta desde I. Además debe actualizarse el terminal de búsqueda hacia delante

Cierre (I) = I

repetir

Para cada elemento [A := α • B β, a] є Cierre (I) hacer

Para cada B ::= δ1 | δ2 | … | δn hacer

Para cada b є Primeros (β a)

Cierre (I) = Cierre (I) ∪ { [B := • δi, b] } para todo i = 1..n

hasta no se pueden añadir más elementos a Cierre (I)

I0 = Cierre ( { [S’ ::= • S, $] } ) =

{ [S’ ::= • S, $],

[S ::= • ( S ) , $ ],

[S ::= • a , $ ] }

I2 = Cierre ( { [S’ ::= ( • S ), $] } ) =

{ [S’ ::= ( • S ), $],

[S ::= • ( S ), ‘)’ ],

[S ::= • a, ‘)’ ] }

S’ ::= S

S ::= ( S ) | a

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 42

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Función Ir-A ( I, a ) LR (1)

Ir-A ( I0, ‘(’ ) = Cierre ( { [ S ::= ( • S ), $ ] } )

= { [ S ::= ( • S ), $ ],

[ S ::= • ( S ), ) ],

[ S ::= • a, ) ] }

Ir-A es una función que toma un estado y un elemento a Є N U T y devuelve un nuevo estado. La operación consiste en avanzar el punto una posición sobre todos aquellos elementos en los que a preceda al punto. En los que no ocurra así se eliminan del conjunto. Finalmente se cierra el conjunto resultante

Para todos los elementos B := [α • Aβ, b] є I hacer

Ir-A (I, A) = Cierre ( { [B := α A • β, b] } )

S’ ::= S

S ::= ( S ) | a

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 43

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Colección canónica de los conjuntos de elementos C LR (1)

Se comienza por ampliar la gramática con la producción S’ ::= S donde S es el axioma y S’ es el nuevo axioma. Esto se hace para cubrir todas las alternativas de S. Después se aplica sistemáticamente el siguiente algoritmo hasta que C no pueda crecer más

Ampliar la gramática con S’ ::= S

C = Cierre ( { S’ ::= • S } ) = { I0 }

Para cada conjunto Ii є C Hacer

Para cada a є T ∪ N Hacer

Si existe un elemento B := α • a β є Ii

C = C ∪ Ir-A (Ii , a)

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

I0 = Cierre ( { [S’ ::= •S, $] } )

= {[S’ ::= •S, $], [S ::= • CC, $],

[C ::= • cC, c],

[C ::= • cC, d],

[C ::= •d, c],

[C ::= •d, d] }

I1 = Ir-A (I0, S)

= Cierre ( { [S’ ::= S •, $] } )

= { [S’ ::= S •, $] }

I2 = Ir-A (I0, C)

= Cierre ( { [S ::= C •C,$] } )

= { [S ::= C•C,$],

[C::= •cC, $],

[C::= •d, $] }

I3 = Ir-A (I0, c)

= Cierre ( { [C ::= c•C, c] [C ::= c•C, d] } )

= { [C ::= c•C, c ],

[C::= •cC, c],

[C ::= •d, c],

[C ::= c•C, d ],

[C::= •cC, d],

[C ::= •d, d] }

I4 = Ir-A (I0, d)

= Cierre ( { [C ::= d •, c] [C::= d •, d] } )

= { [C ::= d •, c] [C::= d •, d] }

I5 = Ir-A (I2,C)

= Cierre ( { [S ::= CC•, $] } )

= { [S ::= CC•, $] }

Continúa…

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 44

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Colección canónica de los conjuntos de elementos C LR (1)

Se comienza por ampliar la gramática con la producción S’ ::= S donde S es el axioma y S’ es el nuevo axioma. Esto se hace para cubrir todas las alternativas de S. Después se aplica sistemáticamente el siguiente algoritmo hasta que C no pueda crecer más

Ampliar la gramática con S’ ::= S

C = Cierre ( { S’ ::= • S } ) = { I0 }

Para cada conjunto Ii є C Hacer

Para cada a є T ∪ N Hacer

Si existe un elemento B := α • a β є Ii

C = C ∪ Ir-A (Ii , a)

I6 = Ir-A (I2, c)

= Cierre ( { [C::=c •C,$] } )

= { [C ::= c •C,$],

[C: := •cC, $],

[C ::= •d, $] }

I7 = Ir-A (I2, d)

= Cierre ( { [C::= d •, $] } )

= { [C ::= d •,$] }

I8 = Ir-A (I3, C)

= Cierre ( { [C ::= cC •, c],

[C ::= cC •, d] } )

= { [C ::= cC •,c],

[C ::= cC •,d] }

I9 = Ir-A (I3, c)

= Cierre( { [C::= c•C, c], [C ::= c•C, d] } ) = I3

I9 = Ir-A (I3, d)

= Cierre ( { [C ::= d •, c] [C::= d •, d] } ) = I4

I9 = Ir-A (I6, C)

= Cierre( { [C ::= cC•, $] } ) = { [C ::= cC•, $] }

I10 = Ir-A (I6, c)

= Cierre ( { [C::=c•C, $] }) = I6

I10 = Ir-A (I6, d)

= Cierre ( { [C::= d•, $] } ) = I7

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 45

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Autómata reconocedor de prefijos viables LR (1)

De manera similar se puede construir un autómata reconocedor de prefijos viables donde cada Ii se corresponde con un Si y cada transición etiquetada con a de Si a Sj se corresponde con Ij = Ir-A (Ii, a)

S0 = Cierre( { S’ ::= • S } )

Para cada Si Hacer

Para cada a є N ∪ T Hacer

Si Existe B ::= α • aβ є Si Entonces

Crear estado nuevo Sn = Ir-A (Si, A

Crear transición de Si a Sn etiquetada con a

[S’::=•S,$]

[S::=•CC,$],

[C::=•cC,c],

[C::=•cC,d],

[C::=•d,c],

[C::=•d,d]

[S’::=S•,$]

[S::=C•C,$],

[C::=•cC,$],

[C::=•d,$]

[S::=CC•,$]

[C::=c•C,$],

[C::=•cC,$],

[C::=•d,$]

[C::=cC•,$]

[C::=d•,$][C::=c•C,c],

[C::=•cC,c],

[C::=•d,c],

[C::=c•C,d],

[C::=•cC,d],

[C::=•d,d],[C::=cC•,c],

[C::=cC•,d]

[C::=d•,c],

[C::=d•,d]

c

C

c

d

S

d

C

C

c

d d

C

c

0 1

2

3

4

5

6

7

8

9

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 46

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener C = {I0, I1, …, In}

Cada Ij є C se corresponde con el estado j del analizador

Construir la tabla Ir-A [s, A]

Si Ir-A (Ii, A) = Ij, A Є N Entonces Ir-A [i, A] = j

Construir la tabla Acción [s, a]

Para todo [A ::= α • aβ, b] Є Ii, a Є T Hacer

Si Ir-A (Ii, a) = Ij Entonces Acción [i, a] = dj

Para todo [A ::= α •, a] Є Ii a Є T Hacer

Acción [i, a] = rk

Si [S’ ::= S •, $] Є Ii entonces Acción [i, $] = Aceptar

Todas las demás entradas de Acción [k, s] = error

A partir de la colección canónica de elementos es posible construir las tablas de los analizadores LR (1)

›  Cada conjunto de elementos es un estado

›  La tabla Ir-A (I, A) A Є N refleja la función Ir-A

›  La tabla Ir-A (I, a) a Є T refleja los desplazamientos

›  Para los elementos de reducción

›  Se mira el terminal de búsqueda adelantada

›  Se rellena la celda con reducción por esa regla

TablasLR(1)apar8rdelacoleccióncanónica

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 47

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener El autómata reconocedor de prefijos viables

Cada estado Sj corresponde con el estado j

Construir la tabla Ir-A [s, A]

Si existe transición de Si a Sj con A, A Є N Entonces

Ir-A [i, A] = j

Construir la tabla Acción [s, a]

Para todo [A ::= α • aβ, b] Є Si, a Є T Hacer

Si existe transición de Si a Sj con a entonces

Acción [i, a] = dj

Para todo [A ::= α •, a] Є Si a Є T Hacer

Acción [i, a] = rk

Si [S’ ::= S •, $] Є Si Acción [i, $] = Aceptar

Todas las demás entradas de Acción [k, s] = error

A partir del autómata reconocedor de prefijos viables es posible construir las tablas de los analizadores SLR

›  Cada estado del autómata es un estado

›  Transiciones Si a Sj con A Є N reflejan Ir-A

›  Transiciones Si a Sj con a Є T reflejan los desplazamientos

›  Para los elementos de reducción

›  Se mira el terminal de búsqueda adelantada

›  Se rellena la cela con reducción por esa regla

TablasLR(1)apar8rdelautómatadeprefijosviables

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 48

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemploc d $

0

1

2

3

4

5

6

7

8

9

S C

1 2

5

8

9

c d $

d3 d4

d6 d7

d3 d4

d6 d7

0

1

2

3

4

5

6

7

8

9

S C

1 2

5

8

9

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 49

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

c d $

d3 d4

d6 d7

d3 d4

r4 r4

r2

d6 d7

r4

r3 r3

r3

0

1

2

3

4

5

6

7

8

9

S C

1 2

5

8

9

Ejemplo

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

c d $

d3 d4 error

error error ok

d6 d7 error

d3 d4 error

r4 r4 error

error error r2

d6 d7 error

error error r4

r3 r3 error

error error r3

0

1

2

3

4

5

6

7

8

9

S C

1 2

5

8

9

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 50

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

VentajaseinconvenientesdelosanalizadoresLR(1)

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Los analizadores sintácticos ascendentes del tipo LR (1) son los más generales que existen y admiten un gran número de gramáticas. No obstante la complejidad de los autómatas reconocedores de prefijos viables os hacen inaplicables en la práctica

Ventajas

›  Gran conjunto de gramáticas posibles

›  Predicción con terminales de búsqueda

›  Varias reducciones por el mismo estado

›  La predicción está muy ajustada

Inconvenientes

›  Mas difícil de entender y construir

›  Estrategia de reducción más compleja

›  No existen estados de (únicos) de reducción

›  Utiliza un autómata muy complejo

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 51

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

DesdeelLR(1)haciaelLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

El único inconveniente del análisis LR (1) es la explosión combinatoria de estados que surge en el autómata reconocedor de prefijos viables cuando se tienen en cuenta los terminales de búsqueda adelantada. LALR simplifica estos autómatas a partir de 2 principios

El núcleo de un estado de un autómata reconocedor de

prefijos viables LR (1) es igual al estado equivalente de LR (0)

Llamamos núcleo de un estado al conjunto formado por los primeros componentes de cada elemento de dicho estado

PrimerprincipiodelanálisisLALR

Dados 2 estados s1 y s2 de un autómata LR (1) con el mismo

núcleo. Si s1 tiene una transición con X a t1, entonces s2

también lo tiene con X a algún t2 y t1 y t2 comparten el mismo

núcleo

SegundoprincipiodelanálisisLALR

I = { [ S’ ::= • S , $ ],

[ S ::= • ( S ) , $ ],

[ S ::= • a , $ ] }

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 52

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Elementos LALR

Prefijo viable LALR

Un elemento LR (1) es un par formado por un elemento LR (0) y un o varios terminales de búsqueda hacia delante. La idea es acarrear en cada elemento el/los terminales que deben encontrarse a la entrada a la hora de realizar la reducción. Debe pertenecer al conjunto Siguiente del antecedente

[ B ::= • a A, a / b…]

[ B ::= a • A , a / b…]

[ B ::= a A •, a /b,…]

A := ع

B ::= a A

[ A := •, a, b,…]

Un prefijo viable de un elemento corresponde con la forma de frase que queda a la izquierda del punto de dicho elemento. El prefijo viable identifica, de forma abstracta, la frase que se ha reconocido a la entrada y que valida, parcialmente, la selección de esa regla para proceder con la reducción

[B ::= • a A, a/b…] [B ::= a • A, a/b…] [B ::= a A •, a/b…]

Prefijo viable

Elemento reductible

Elemento de comienzo

Terminales de búsqueda hacia delante

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 53

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Conjunto de elementos LALR Un conjunto de elementos es una colección no ordenada de elementos. Los conjuntos de elementos se utilizan para caracterizar formalmente los estados potenciales por lo que atraviesa un compilador a lo largo del proceso de análisis

I = { [ S’ ::= • S , $ ],

[ S ::= • ( S ) , $ ],

[ S ::= • a , $ ] }

S’ ::= S

S ::= ( S ) | a

Cierre (I) LALR

Ir-A (I, a) LALR

Cierre (I) LR (1)

Ir-A (I, a) LR (1) =

Función Cierre ( I ) LALR El cierre de un conjunto I consiste en ampliar dicho conjunto con todos aquellos elementos con un punto al inicio de su parte derecha que son accesibles de forma directa o indirecta desde I. Además debe actualizarse el terminal de búsqueda hacia delante

Función Ir-A ( I, a ) LALR

Ir-A es una función que toma un estado y un elemento a Є N U T y devuelve un nuevo estado. La operación consiste en avanzar el punto una posición sobre todos aquellos elementos en los que a preceda al punto. En los que no ocurra así se eliminan del conjunto. Finalmente se cierra el conjunto resultante

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 54

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Colección canónica de los conjuntos de elementos C LALR

Todos los conjuntos de elementos con el mismo núcleo se fusionan en un mismo conjunto de elementos. Se devuelve la colección canónica resultante

Ampliar la gramática con S’ ::= S

C = Cierre ( { S’ ::= • S } ) = { I0 }

C’ = { }

Mientras (C != { } )

I = c.extraer ()

Js = c.buscarMismoNucleo (I)

Para todo J en Js

I = I U J

C = C U { I }

I0 = { [S ::= • CC, $],

[C ::= • cC, c/d],

[C ::= •d, c/d] }

I1 = { [S’ ::= S •, $] }

I2 = { [S ::= C •C,$],

[C::= •cC, $],

[C::= •d, $] }

I3 = { [C ::= c•C, c/d/$ ],

[C::= •cC, c/d/$],

[C ::= •d, c/d/$] } = I6

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

I4 = { [C ::= d •, c/d/$] } = I7

I5 = { [C ::= CC•, $] }

I8 = { [C ::= cC•, $] } = I9

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 55

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConceptosesencialesLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Autómata reconocedor de prefijos viables LALR

Hacer el autómata para LR (1)

Para cada subconjunto S1 … Sk con el mismo núcleo

S’1 = U Si

Fusionar también todas las transiciones

[S’::=•S,$]

[S::=•CC,c/d/$],

[C::=•d,c/d],

[S’::=S•,$]

[S::=C•C,$],

[C::=•cC,$],

[C::=•d,$]

[S::=CC•,$]

[C::=c•C,c/d/$],

[C::=•cC,c/d/$],

[C::=•d,c/d/$],

[C::=cC•,c/d/$]

[C::=d•,c/d/$]

c

C

c

d

S

d

C

C

c

0 1

2

36

47

5

89

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

Todos los conjuntos de elementos con el mismo núcleo se fusionan en un mismo conjunto de elementos. Se devuelve la colección canónica resultante

d

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 56

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener C = {I0, I1, …, In} de LR (1)

Obtener C’ = {J0, J1, …, Jk} de LALR

Construir la tabla Ir-A [s, A]

Si Ji = { I0,, …, Im } Entonces

Ir-A (Ji, a) = U Ir-A (Ii, a)

Construir la tabla Acción [s, a]

Construir la tabla Acción [s, a] de LR (1)

Fusionar todas las celdas de las filas con estados fusionados

Si aparecen conflictos G no es LALR

A partir de la colección canónica de elementos es posible construir las tablas de los analizadores LALR

›  Cada conjunto de elementos es un estado

›  La tabla Ir-A (I, A) A Є N refleja la función Ir-A

›  La tabla Ir-A (I, a) a Є T refleja los desplazamientos

›  Para los elementos de reducción

›  Se mira el terminal de búsqueda adelantada

›  Se rellena la celda con reducción por esa regla

›  Se fusionan los resultados de la tabla acción

TablasLALRapar8rdelacoleccióncanónica

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 57

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Obtener el autómata LR (1) con estados Tj

Obtener el autómata LALR con estados Si

Construir la tabla Ir-A [s, A]

Si Si = { Ta,, …, Tb }, Sj = { Tc,, …, Td } Entonces

Si existe alguna transición de Tv Є Si a Tr Є Sj con X

Trazar transición de Si a Sij con X

Construir la tabla Acción [s, a]

Construir la tabla Acción [s, a] de LR (1)

Fusionar toda celda de filas con estados fusionados

Si aparecen conflictos G no es LALR

A partir del autómata reconocedor de prefijos viables es posible construir las tablas de los analizadores LALR

›  Cada estado del autómata es un estado

›  Transiciones Si a Sj con A Є N reflejan Ir-A

›  Transiciones Si a Sj con a Є T reflejan los desplazamientos

›  Para los elementos de reducción

›  Se mira el terminal de búsqueda adelantada

›  Se rellena la cela con reducción por esa regla

›  Se fusionan los resultados de la tabla acción

TablasLALRapar8rdelautómatadeprefijosviables

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 58

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemplo

c d $

0

1

2

36

47

5

89

S C

1 2

5

89

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

c d $

d36 d47

d36 d47

d36 d47

0

1

2

36

47

5

89

S C

1 2

5

89

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 59

Análisissintác6coascendenteporreducción–desplazamiento

Analizadoressintác8cosascendentes

ConstruccióndelastablasLALR

Los diferentes tipos de analizadores sintácticos ascendentes – LR (0), SLR, LALR, LR (1) y LR (k) – sólo se diferencian entre sí por el procedimiento de construcción de las tablas acción e ir-A. En esta sección abordaremos su estudio

Ejemplo

c d $

d36 d47

d36 d47

d36 d47

r4 r4 r4

r2

r3 r3 r3

0

1

2

36

47

5

89

S C

1 2

5

89

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

c d $

d36 d47 error

error error ok

d36 d47 error

d36 d47 error

r4 r4 r4

error error r2

r3 r3 r3

0

1

2

36

47

5

89

S C

1 2

5

89

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 60

Análisissintác6coascendenteporreducción–desplazamiento

Análisissintác8coascendente

EjerciciosUna vez estudiados la construcción de las tablas para los 4 tipos de analizadores sintácticos ascendentes es posible comprobar su viabilidad con diferentes gramáticas

Los analizadores sintácticos ascendentes son capaces de decidir qué regla de producción aplicar a cada paso en función de los elementos terminales que se encuentran en la cabeza de lectura de la cadena de entrada. Como consecuencia se consigue un proceso de análisis con complejidad lineal O (n) con respecto al tamaño del problema. Estos analizadores son llamados genéricamente analizadores LR (K) o analizadores por reducción desplazamiento

E ::= E + T | E – T | T

T ::= T * F | T / F | F

F ::= id | n | ( E )

S ::= P

P ::= ( P ) P | ع

P ::= C L F

C ::= id ;

L ::= id ; L | ع

F ::= id ( L ) ;

P ::= L

L := S ; L | ع

S ::= E | B

B ::= { L }

E ::= id = E | n

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 61

Ges6óndeerroresenanalizadoresascendentes

Ges8óndeerroresLa labor de un analizador sintáctico no se limita exclusivamente a reconocer que una frase pertenece al lenguaje generado por una gramática. Adicionalmente, en el caso de que existan errores sintácticos (o léxicos no reconocidos en la fase de análisis léxico), el analizador debe ser capaz de reconocer errores y emitir mensajes de información asociados

I.Iden8ficacióndeerrores

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

c d $

d3 d4 error

error error error

d6 d7 error

d3 d4 error

r4 r4 error

r2 r2 error

d6 d7 error

error error r4

r3 r3 error

error error r3

Cada entrada vacía de la tabla de acción de los analizadores ascendentes identifica una casuística diferente de error. En p r inc ip io cada e r ro r debería incorporar un mensaje característico diferente

Terminación inesperada de la frase. Se esperaba c o d

Se encontró un c inesperado

II.GeneracióndemensajesCada celda de la tabla de acción permite identificar un tipo de error distinto y asociarle un mensaje de error diferente

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 62

Ges6óndeerroresenanalizadoresascendentes

Ges8óndeerroresLa labor de un analizador sintáctico no se limita exclusivamente a reconocer que una frase pertenece al lenguaje generado por una gramática. Adicionalmente, en el caso de que existan errores sintácticos (o léxicos no reconocidos en la fase de análisis léxico), el analizador debe ser capaz de reconocer errores y emitir mensajes de información asociados

III.Localizacióndeerrores

r1. S’ ::= S

r2. S ::= C C

r3. C ::= c C

r4. C::= d

c d $

d3 d4 error

error error error

d6 d7 error

d3 d4 error

r4 r4 r4

r2 r2 r2

d6 d7 error

r4 r4 r4

r3 r3 r3

r3 r3 r3

Para reducir el número de m e n s a j e s d e e r r o r p o d e m o s f o r z a r reducciones en todos los estados donde solo se reduzca por una regla. Esto atrasa la emisión del error hasta el siguiente desplazamiento lo que p u e d e c o m p l i c a r l a localización

Como heurística general nunca se deben consumir más de 3 tokens en modo de pánico

Las reducciones en rojo corresponden en realidad a

situaciones de error

VI.RecuperacióndeerroresSe pasa a consumición de t okens en modo de pánico. Debe procurarse que el número de tokens consumido no sea muy elevado. Este proceso esta dirigido por conjuntos de predicción

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 63

Tiposdegramá6casyanálisisascendente

Interpretacióndeconflictosenlos8posdeanalizadoresComo describimos al inicio del tema, existen dos tipos de conflictos que pueden darse dentro del análisis sintáctico ascendente por reducción desplazamiento. En este apartado discutiremos, para cada tipo gramática, qué condiciones debe verificar la tabla de acción de los analizadores para que no se den tales conflictos

Nopuedehaber2reglasdis6ntasenlamismafiladeunestadodereducción

Nopuedehaberaccionesreducirydesplazarenunamismafila

›  Conflictos reducción – reducción

›  Conflictos reducción desplazamiento

LenguajesLR(0)

Nopuedehaber2reglasdis6ntasenlamismaceldadereducción

Nopuedehaberunaacciónreduciryotradesplazarenunamismacelda

LenguajesSLR

LenguajesLALR

LenguajesLALR

Reducción-Reducción Reducción-Desplazamiento

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 64

Tiposdegramá6casyanálisisascendente

Clasificacióndegramá8caspor8posdeanalizadoresCuando la tabla de un analizador sintáctico de un determinado tipo no presenta conflictos de análisis se puede asegurar que la gramática del lenguaje bajo análisis es del tipo del analizador utilizado. Esto, en conjunción con la información extraída del tema anterior permite trazar la siguiente clasificación conjuntista de gramáticas independientes del contexto en función del tipo de análisis que soportan

Gramáticas Independientes de contexto

LR (k) Lenguajes No Deterministas

LR (1)

LALR

SLR LR(0)

LL (k)

LL (1)

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 65

Construccióndeanalizadoressintác6cosenlaprác6ca

¿QuéesCup?Cup es una herramienta para la generación de analizadores sintácticos escritos en java. A partir de un fichero de especificación que describe las características sintácticas de un lenguaje, Cup genera un código fuente compilable que puede ser utilizado como analizador sintáctico

Cup

Javac

Parser.cup

Framework

Sym.java

Parser.class

Cup compile CupTest

Esta es la especificación del analizador sintáctico. Todo cambio en el parser debe indicarse aquí

Clase que contiene declaración de constantes para cada terminal gramatical

El scanner modifica para incorporar en los ID de los tokens los valores de Sym

Paser.java

JFlex JavacScanner.java Scanner.class

JFlex

Java

compile

Esta es la clase generada a partir de la especificación. Atención! No incluir aquí ningún código manualmente ya que en la próxima generación se perderá

Esta es la clase Parser que corresponde con un analizador ascendente de tipo LALR

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 66

Construccióndeanalizadoressintác6cosenlaprác6ca

¿QuéesCup?Cup es una herramienta para la generación de analizadores sintácticos escritos en java. A partir de un fichero de especificación que describe las características sintácticas de un lenguaje, Cup genera un código fuente compilable que puede ser utilizado como analizador sintáctico

Scanner.java

While(a>b)doa:=a+1;

Parser.java

next_Token() Sym.java

La clase Sym.java contiene las declaración de las constantes que identifican los símbolos terminales de la gramática. Estos deben corresponderse con aquellos emitidos por la clase Token

La clase Token es el vehículo de información que comunica unidades léxicas del fichero de entrada al analizador léxico

Token

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 67

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

I.PaqueteseimportacionesSe incluye la declaración de todas clases y paquetes necesarias para compilar adecuadamente el analizador sintáctico. Ninguna de las importaciones de la plantilla debe ser eliminada!

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 68

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

II.Ac8oncodeSe incluyen declaraciones de variables y métodos auxiliares que serán utilizados dentro de la gramática. Algunas de las declaraciones presentes en la plantilla son necesarias solamente de cara al segundo cuatrimestre. Si las elimina o comenta deberá recuperarlas en la segunda entrega. En el primer cuatrimestres sólo SyntaxErrorManager es utilizado

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 69

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

III.ParsercodePermite incluir declaraciones de variables y métodos que ayudan a adaptar el comportamiento del analizador. La plantilla incluye la declaración del SyntaxErrorManager y funciones manejadoras de los errores recuperables y no recuperables. Ninguna de estas declaraciones deben ser eliminadas

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 70

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

IV.DeclaracióndeterminalesSe deben declarar extensivamente todos los símbolos terminales utilizados en la gramática. Se comienza por la palabra reservada terminal seguida de la clase java que representa el terminal y finalmente el nombre del terminal seguido de punto y coma (;)

Palabra reservada terminal

Clase que tipifica el Token

Nombre del Token

Todos y cada uno de los terminales definidos aquí aparecerán en la clase Sym para que puedan referirse desde el escáner

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 71

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

V.DeclaracióndenoterminalesSe deben declarar extensivamente todos los símbolos no terminales utilizados en las partes izquierda de las reglas de la gramática. Se comienza por la palabra reservada terminal seguida de la clase java que representa el no terminal y finalmente el nombre del no terminal seguido de punto y coma (;)

Palabra reservada non terminal

Clase que tipifica el no terminal

Nombre del no terminal

La tipificación de los no terminales puede omitirse y postergarse hasta el segundo cuatrimestre

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 72

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

VI.Declaraciónexplícitadeprecedenciayasocia8bidadEn Cup las gramáticas de operadores pueden ser ambiguas. La resolución de la ambigüedad se realiza de forma explícita a partir de la información de precedencia y asociatividad

Palabra reservada precedence

Información de asociatividad (left | right | nonassoc)

Nombre del terminal

La tipificación de los no terminales puede omitirse y postergarse hasta el segundo cuatrimestre

Igual precedencia Precedencia creciente

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 73

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

VII.DeclaracióndelaxiomaEn Cup es posible declarar el axioma de la gramática. Esta declaración es opcional. Si no aparece se asume por defecto que el axioma corresponde con el antecedente de la primera regla de producción. No borre esta declaración

Palabra reservada start with

Nombre del no terminal axioma

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 74

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómofuncionaCup?La especificación de un analizador sintáctico en cup está compuesta por varias secciones diferentes. El marco de trabajo tecnológico utilizado para el desarrollo del compilador proporciona una plantilla de tal especificación que debe ser extendida pero NO modificada (seguir comentarios)

VIII.DeclaracióndelreglasdeproducciónLa última sección permite declarar las reglas de producción gramatical. Los no terminales van en minúscula, los terminales en mayúscula y el símbolo de producción es ::=

Antecedente

Consecuente

La parte derecha incluye acciones semánticas . Se usarán en el segundo cuatrimestre. No borre las acciones de la plantilla

Consúltese el manual de usuario de Cup

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 75

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómoseusaCup?El analizador sintáctico generado por Cup debe integrarse con el analizador léxico generado por JFlex. Ambas herramientas están preparadas para integrarse fácilmente. Además el marco de trabajo donde se desarrolla el compilador garantiza dicha integración

Scanner.java

While(a>b)doa:=a+1;

Parser.java

next_Token() Sym.java

Lo único que el usuario debe asegurar es que los identificadores de los tokens generados por el escaner correspondan con constantes declaradas en la clase Sym. Síganse los siguientes pasos:

Consúltese el manual de usuario de Cup y JFlex

<WHILE,PR>

1. Crear escaner con ID de token falsos

2. Crear el analizador sintáctico

1. Declarar terminales

2. Declara no terminales

3. Declarar reglas…

4. General el parser invocando a Cup

3. Reconstruir escáner

1.  Sustituir los ID falsos por los de Sym

2. Generar el escaner invocando a JFlex

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 76

Construccióndeanalizadoressintác6cosenlaprác6ca

¿CómoseusaCup?El analizador sintáctico generado por Cup debe integrarse con el analizador léxico generado por JFlex. Ambas herramientas están preparadas para integrarse fácilmente. Además el marco de trabajo donde se desarrolla el compilador garantiza dicha integración

Scanner.java

While(a>b)doa:=a+1;

Parser.java

Cada vez que el escáner reconoce un nuevo patrón léxico a la entrada genera un token y lo entrega al parser. El framework proporciona la clase Token para vehicular esta entrega

Consúltese el manual de usuario de Cup y JFlex

<WHILE,PR>

Javacup.run6me.Symbol

Token

+ getID () + getLexema () + getline () + getColumn ()

TokenString TokenNumber

+ getLiteral () + getValue ()

1.  Especificar el escáner en JFlex

2.  Para cada patrón léxico

1.  Emitir el tipo de token apropiado

2.  Enriquecer el token con datos

3.  Si el tipo de token es especial

1.  Implementar una clase nueva

2. Devolver una instancia de ella

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 77

Construccióndeanalizadoressintác6cosenlaprác6ca

Ges8óndeerroresenCupCuando se realiza un análisis ascendente en Cup de una cadena de entrada es posible que el parser generado encuentre dos posibles situaciones de error

exp::=expADDexp|expSUBexp|expMULexp|expDIVexp|NUMBER|error;

I. Errores recuperables

Los errores recuperables son aquellos de los que el compilador es capaz de escaparse en estado de pánico y continuar después en un contexto gramatical estable. Se describen con la producción error al final de la gramática

Consúltese el manual de usuario de Cup

exp::=expADDexp|expSUBexp|expMULexp|expDIVexp|NUMBER|errorPYC|errorPI;

Cada vez que se reduce por una producción de error, Cup invoca automáticamente al manejador de errores recuperables syntax_error. En la plantilla del framework el tratamiento consiste en emitir un mensaje de error con el SyntaxErrorManager . No altere este código Cuando la cadena a la entrada no encaja con

ninguna de las partes derechas de las reglas de exp se reduce por las reglas de error. Estas deben ir normativamente las últimas

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 78

Construccióndeanalizadoressintác6cosenlaprác6ca

Ges8óndeerroresenCupCuando se realiza un análisis ascendente en Cup de una cadena de entrada es posible que el parser generado encuentre dos posibles situaciones de error

II. Errores irrecuperables

Los errores irrecuperables son aquellos de los que el compilador no es capaz de recuperarse una vez que han sido encontrados y provocan que el parser aborte el proceso de análisis sintáctico

Consúltese el manual de usuario de Cup

Cada vez que se produce un error irrecuperable, Cup invoca automáticamente al manejador de errores recuperables unrecovered_syntax_error. En la plantilla del framework el tratamiento consiste en emitir un mensaje de error fatal con el SyntaxErrorManager . No altere este código

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 79

Construccióndeanalizadoressintác6cosenlaprác6ca

Ges8óndeerroresenCupCuando se realiza un análisis ascendente en Cup de una cadena de entrada es posible que el parser generado encuentre dos posibles situaciones de error

Traza de errores

Además es posible trazar los error del compilador, o la ejecución del mismo a lo largo del proceso ascendente mediante la inserción de acciones en las partes derechas de la regla que invoquen el gestor de errores sintácticos proporcionado por el framework de desarrollo

Consúltese el manual de usuario de Cup

SyntaxErrorManager

+ syntaxDebug (String message) + syntaxInfo (String message) + syntaxWarn (String message) + SyntaxError (String message) + SyntaxFatal (String message) ...

exp::=expMASexp{:syntaxErrorManager.syntaxDebug(“sumando”);:}|expPORexp{:syntaxErrorManager.syntaxDebug(“multiplicando”);:}|error{:syntaxErrorManager.syntaxDebug(“error”);:}

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 80

Construccióndeanalizadoressintác6cosenlaprác6ca

Desarrollopasoapaso

1.  Seleccionar un código fuente representativo (completo)

2.  Organizarlo estructuralmente en bloques sintácticos

3.  Nombrar simbólicamente a cada bloque (con un no terminal)

El proceso de desarrollo del analizador sintáctico puede resumirse en una serie de pasos que pasamos a describir detalladamente a continuación

I. Análisis del lenguaje Lo primero es analizar la estructura sintáctica del lenguaje para el cual tratamos de generar un analizador sintáctico. Para este proceso recomendamos los siguientes pasos

ProgramPrueba;ConstPI=3.14TypeTPunto=RECORDx,y:INTEGER;ENDTCirculo=RECORDcentro:TPunto;radio:REAL;END;Varx,y:REAL;c:TCirculo;PROCEDUREcrear(p:TPunto,r:REAL,VARc:TCirculo)BEGINc.centro:=p;c.radio:=rEND;FUNCTIONarea(c:TCirculo):REALVARradio:REAL;FUNCTIONpotencia(r:REAL,n:INTEGER):REALBEGIN...END;BEGINradio:=c.radio;area:=PI*Potencia(radio,2);ENDBEGIN...END;

Programa Declaraciones DeclaracionConstantes DeclaracionConstante DeclaraciónTipos DeclaracionTipo DeclaraciónRegistro DeclaracionVariable…

DeclaraciónSubprogramas DeclaraciónSubprogrograma DeclaraciónProcedimiento DeclaraciónFunción DeclararaciónCabecera DeclaraciónCuerpo…

Sentencia ListaSentencias BloqueSentencias SentenciaWhile…

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 81

Construccióndeanalizadoressintác6cosenlaprác6ca

Desarrollopasoapaso

1.  Declare conjunto de no terminales

2.  Declare conjunto de terminales

3.  Escribir reglas de producción

El proceso de desarrollo del analizador sintáctico puede resumirse en una serie de pasos que pasamos a describir detalladamente a continuación

II. Especificación gramatical El siguiente paso es realizar la especificación gramatical del lenguaje dentro de Cup.

Declaraciones ::= DeclaraciónContantes | DeclaraciónTipos | DeclaraciónVariables; DeclaraciónVariables ::= VAR ListaDeclaraciónVariables;

Las reglas de refinamiento se encargar de redefinir una abstracción sintáctica – representada por un no terminal – en un conjunto de terminales y no terminales

Reglas de refinamiento Reglas de resolución de recursividad

ListaDeclaraciónVariables ::= DeclaraciónVariable | ListaDeclaraciónVariables DeclaraciónVariable; ListaParamActuales ::= exp COMA ListaParamActuales | ;

Las reglas de resolución de recursividad se encargan de establecer las definiciones recursivas de los terminales de refinamiento

Solo deben existir en la especificación estos dos tipos de reglas. Nunca escriba una regla mezcla de ambos tipos

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 82

Construccióndeanalizadoressintác6cosenlaprác6ca

Desarrollopasoapaso

1.  Genere el analizador sintáctico con Cup

1.  Ejecute Clean

2.  Ejecute Cup

3.  Ejecute compile

2.  Adapte la especificación de JFlex

1.  Importe la clase Sym en JFlex

2.  Cambie las acciones de JFlex para generar tokens con ID en Sym

3.  Ejecute jflex para generar de nuevo el escáner

3.  Pruebe el parser

1.  Ejecute cupTest

2.  Cambie en el build.xml el fichero fuente de entrada para probar distintos casos

El proceso de desarrollo del analizador sintáctico puede resumirse en una serie de pasos que pasamos a describir detalladamente a continuación

III. Generación y prueba del parser

El tercer y ultimo paso consiste en generar el analizador sintáctico y probarlo

Alternativamente el framework también proporciona la tarea build que ejecuta clean + cup + flex + compile

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 83

Bibliogra`a

MaterialdeestudioBibliografía básica

Construcción de compiladores: principios y práctica

Kenneth C. Louden International Thomson Editores,

2004 ISBN 970-686-299-4

Javier Vélez Reyes [email protected]

Análisissintác8co.Analizadoresascendentes

5 - 84

Bibliogra`a

MaterialdeestudioBibliografía complementaria

Compiladores: Principios, técnicas y herramientas.

Segunda Edición Aho, Lam, Sethi, Ullman

Addison – Wesley, Pearson Educación, México 2008

Diseño de compiladores. A. Garrido, J. Iñesta, F. Moreno

y J. Pérez. 2002. Edita Universidad de Alicante