 
 
 
 
 
 
 
 
 
 










 
Para la construcción de las tablas de un analizador SLR
se construye el autómata finito determinista (DFA) 
 equivalente al NFA 
presentado en la sección
8.23
usando el algoritmo de construcción del subconjunto.
 equivalente al NFA 
presentado en la sección
8.23
usando el algoritmo de construcción del subconjunto.
Como recordará, en la construcción del subconjunto,
partiendo del estado de arranque  del NFA con
 del NFA con  -transiciones
se calcula su clausura
-transiciones
se calcula su clausura 
 y las 
clausuras de los conjuntos de estados
 y las 
clausuras de los conjuntos de estados 
 a los que transita.  Se repite el proceso
con los conjuntos resultantes hasta que no se introducen nuevos
conjuntos-estado.
 
a los que transita.  Se repite el proceso
con los conjuntos resultantes hasta que no se introducen nuevos
conjuntos-estado.
La clausura 
 de un subconjunto de estados del autómata
 de un subconjunto de estados del autómata  esta formada
por todos los estados que pueden ser alcanzados mediante transiciones
etiquetadas con la palabra vacía (denominadas
 esta formada
por todos los estados que pueden ser alcanzados mediante transiciones
etiquetadas con la palabra vacía (denominadas  transiciones)
desde los estados de
 transiciones)
desde los estados de  . Se incluyen en
. Se incluyen en 
 , naturalmente los estados 
de
, naturalmente los estados 
de  .
.
 
Aquí 
 denota la función de transición del autómata extendida  a cadenas
de
 denota la función de transición del autómata extendida  a cadenas
de  .
.
En la práctica, y a partir de ahora así lo haremos, se prescinde de diferenciar
entre  y
 y 
 usándose indistintamente la notación
 usándose indistintamente la notación
 para ambas funciones.
 para ambas funciones.
La clausura puede ser computada usando una estructura de pila o aplicando la expresión recursiva dada en la ecuación 8.1. Una forma de computarla viene dada por el siguiente seudocódigo:
function closure(I : set of LR(0)-items) 
begin
  J = I;
  repeat
    changes = FALSE;
    for A->alpha . B beta in J do
      for B->gamma in G do
        next if B->.gamma in J
        insert B->.gamma in J
        changes = TRUE;
      end for
    end for
  until nochanges;
  return J
end
Para el NFA mostrado en el ejemplo 8.23.1 el DFA construído mediante esta
técnica es el que se muestra en la figura 8.24.2. Se ha utilizado el símbolo
# como marcador. Se ha omitido el número 3 para que los estados coincidan
en numeración con los generados por eyapp (véase el cuadro
8.24.2).
Un analizador sintáctico LR utiliza una tabla para su análisis. Esa tabla se construye a partir de la tabla de transiciones del DFA. De hecho, la tabla se divide en dos tablas, una llamada tabla de saltos o tabla de gotos y la otra tabla de acciones.
La tabla goto de un analizador SLR
no es más que la tabla de transiciones del autómata DFA 
obtenido aplicando la construcción del subconjunto al NFA
definido en 8.23.4. De hecho es la tabla
de transiciones restringida a  (recuerde que el alfabeto del
autómata es
 (recuerde que el alfabeto del
autómata es 
 ).
Esto es,
).
Esto es, 
 .
. 
 
La parte de la función de transiciones
del DFA que corresponde a los terminales que no producen rechazo, 
esto es, 
 se adjunta a una tabla que se denomina tabla de acciones.
La tabla de acciones es una tabla de doble entrada en los estados
y en los símbolos de
se adjunta a una tabla que se denomina tabla de acciones.
La tabla de acciones es una tabla de doble entrada en los estados
y en los símbolos de  .
Las acciones de transición ante terminales 
se denominan acciones de desplazamiento o (acciones shift):
.
Las acciones de transición ante terminales 
se denominan acciones de desplazamiento o (acciones shift):
 
 
Cuando un estado  contiene un LR(0)-item de la forma
 contiene un LR(0)-item de la forma 
 , 
esto es, el estado corresponde a un posible rechazo,
ello indica que hemos llegado a un final del prefijo viable, que hemos
visto
, 
esto es, el estado corresponde a un posible rechazo,
ello indica que hemos llegado a un final del prefijo viable, que hemos
visto  y que, por tanto, es probable que
 y que, por tanto, es probable que 
 sea el handle de la forma sentencial derecha actual. Por tanto,
añadiremos en entradas de la forma
sea el handle de la forma sentencial derecha actual. Por tanto,
añadiremos en entradas de la forma  de la tabla de acciones 
una acción que indique que hemos encontrado el mango en la 
posición actual y que la regla asociada es
 de la tabla de acciones 
una acción que indique que hemos encontrado el mango en la 
posición actual y que la regla asociada es 
 .
A una acción de este tipo se la denomina acción de reducción.
.
A una acción de este tipo se la denomina acción de reducción.
La cuestión es, ¿para que valores de 
 debemos disponer que
la acción para
 debemos disponer que
la acción para  es de reducción?
Podríamos decidir que ante cualquier terminal
 es de reducción?
Podríamos decidir que ante cualquier terminal 
 que produzca un rechazo del autómata, pero podemos ser un poco mas
selectivos. No cualquier terminal puede estar en la entrada en el momento
en el que se produce la antiderivación o reducción. 
Observemos que si
que produzca un rechazo del autómata, pero podemos ser un poco mas
selectivos. No cualquier terminal puede estar en la entrada en el momento
en el que se produce la antiderivación o reducción. 
Observemos que si 
 es el handle
de
 es el handle
de  es porque:
 es porque:
 
Por tanto, cuando estamos reduciendo por 
 los únicos terminales legales que cabe esperar en una reducción por
los únicos terminales legales que cabe esperar en una reducción por 
 son los terminales
 son los terminales 
 .
.
Dada una gramática 
 , podemos construir las tablas de acciones (action table) y  transiciones (gotos table) mediante el siguiente algoritmo:
, podemos construir las tablas de acciones (action table) y  transiciones (gotos table) mediante el siguiente algoritmo:
 equivalente al Autómata Finito No
Determinista (NFA) definido en 8.23.4.
Sea
equivalente al Autómata Finito No
Determinista (NFA) definido en 8.23.4.
Sea 
 el conjunto de estados
del DFA. Cada estado
 el conjunto de estados
del DFA. Cada estado  es un conjunto de LR(0)-items o estados
del NFA. Asociemos un índice
 es un conjunto de LR(0)-items o estados
del NFA. Asociemos un índice  con cada conjunto
 con cada conjunto  .
.
 para todo
 para todo  
 se determinan como sigue:
 se determinan como sigue:
  
 ,
, 
 ,
, 
 entonces:
 
  entonces:
![$ action[i][a] = shift\ j$](img446.png) 
 entonces
 entonces 
![$ action[i][\$] = accept$](img448.png) 
 distinto del anterior hacer
 
  distinto del anterior hacer
![$ \forall a \in\ FOLLOW(A):\ action[i][a] = reduce\ A \rightarrow \alpha$](img450.png) 
 ''.
''.
| 1 | S  a S b | 
| 2 | S     | 
partiendo del autómata finito determinista que se construyó en la figura 8.24.2 y calculando los conjuntos de primeros y siguientes
| FIRST | FOLLOW | |
| S | a,   | b, $ | 
obtenemos la siguiente tabla de acciones SLR:
| a | b | $ | |
| 0 | s2 | r2 | r2 | 
| 1 | aceptar | ||
| 2 | s2 | r2 | r2 | 
| 4 | s5 | ||
| 5 | r1 | r1 | 
Las entradas denotadas con  
  (
 ( por shift) indican un desplazamiento
al estado
 por shift) indican un desplazamiento
al estado  , las denotadas con
, las denotadas con  
  (
 ( por reduce o reducción) indican una operación
de reducción o antiderivación por la regla
 por reduce o reducción) indican una operación
de reducción o antiderivación por la regla  .  Las entradas vacías 
corresponden a acciones de error.
.  Las entradas vacías 
corresponden a acciones de error.
El método de análisis LALR usado por eyapp
es una extensión del método SLR esbozado
aqui. Supone un compromiso entre potencia (conjunto de gramáticas
englobadas) y eficiencia (cantidad de memoria utilizada, tiempo de
proceso).
Veamos como eyapp aplica la construcción del subconjunto a la 
gramática del ejemplo
8.23.1.
Para ello construimos el siguiente programa eyapp:
$ cat -n aSb.yp
     1  %%
     2  S:  # empty
     3      |   'a' S 'b'  
     4  ;
     5  %%
     ......
y compilamos, haciendo uso de la opción -v para que eyapp produzca
las tablas en el fichero aSb.output:
$ ls -l aSb.* -rw-r--r-- 1 lhp lhp 738 2004-12-19 09:52 aSb.output -rw-r--r-- 1 lhp lhp 1841 2004-12-19 09:52 aSb.pm -rw-r--r-- 1 lhp lhp 677 2004-12-19 09:46 aSb.yp
El contenido del fichero aSb.output se muestra
en la tabla 
8.24.2.
Los números de referencia a las producciones en las acciones
de reducción vienen dados por:
                      0:	$start -> S $end
                      1:	S -> /* empty */
                      2:	S -> 'a' S 'b'
 
Observe que el final de la entrada se denota 
por $end y el marcador en un LR-item 
por un punto. Fíjese en el estado 2: 
En ese estado están también los items
S -> . 'a' S 'b'
y S -> .
sin embargo no se explicitan por que se entiende que su pertenencia es consecuencia directa de aplicar la operación de clausura. Los LR items cuyo marcador no está al principio se denominan items núcleo.
aSb.output
en el apéndice que se encuentra en la página 
![[*]](crossref.png) .
.
eyapp con la que obtuvo en el ejemplo
8.24.1.
 
 
 
 
 
 
 
 
 
 










