-
Notifications
You must be signed in to change notification settings - Fork 0
/
capitulo4.ptex
1965 lines (1757 loc) · 75.2 KB
/
capitulo4.ptex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\section{Introducción}
\subsection{Análisis con retroceso}
El an\'alisis sintáctico descendente (ASD) intenta encontrar
entre las producciones de la gram\'a\-tica
la derivaci\'on por la izquierda del s\'{\i}mbolo inicial
para una cadena de entrada. Una forma intuitiva de realizar un
análisis descendente sería utilizando {\em backtracking\/} o
análisis con retroceso, que puede implicar examinar varias
veces la entrada. Sin embargo, en la práctica no se suele
utilizar esta técnica ya que su complejidad es exponencial en el
peor caso y, como hemos comentado en el capítulo anterior, es necesario que
el analizador sintáctico tenga (como todo o casi todo el compilador)
una complejidad lineal con respecto al tamaño del programa fuente.
\begin{ejemplo}
$$
\begin{array}{lcl}
\nter{S} \der \ter{c} \nter{A} \ter{d} \\
\nter{A} \der \ter{a} \ter{b} \opt \ter{a} \\
\end{array}
$$
Analicemos la cadena de entrada: ``\verb!cad!''
\begin{enumerate}
\item En la
situaci\'on en la que el s\'{\i}mbolo analizado es el
primero, ``\texttt{\underline{c}ad}'',
la \'unica producci\'on que se puede escoger es la
primera; luego $S \deriva cAd$, y el
primer s\'{\i}mbolo de la entrada ``\texttt{\underline{c}}''
queda emparejado con la primera hoja izquierda del \'arbol que
tambi\'en es ``\verb!c!'',
con lo que se puede seguir adelante con el an\'alisis.
\item Se avanza la
marca de entrada al segundo s\'{\i}mbolo, ``\texttt{c\underline{a}d}'',
y se considera la siguiente hoja del \'arbol (siempre de
izquierda a derecha), etiquetada con $A$.
Entonces se expande el \'arbol con la primera producci\'on
de $A$, $cAd \deriva cabd$, y como el segundo
s\'{\i}mbolo de la entrada ``\texttt{\underline{a}}''
queda emparejado con la segunda hoja por la izquierda, podemos
avanzar la marca de an\'alisis.
\item Se avanza la
marca de entrada al s\'{\i}mbolo siguiente, ``\texttt{ca\underline{d}}'',
y se compara con la siguiente hoja etiquetada con ``\verb!b!''.
Como no concuerda con ``\texttt{\underline{d}}'',
se indica el error y se vuelve a $A$
para ver si hay otra alternativa no intentada, y se reestablece la
marca de entrada a la posici\'on que ocupaba entonces.
\item Con la marca en ``\texttt{c\underline{a}d}''
se expande la producci\'on no intentada $A \rightarrow a$,
que hace que $cAd \deriva cad$.
Ahora el s\'{\i}mbolo de entrada ``\texttt{\underline{a}}''
coincide con la nueva hoja ``\verb!a!''
y se puede proseguir el an\'alisis.
\item Se avanza de
nuevo la marca a ``\texttt{ca\underline{d}}''
y coincide con la hoja de la derecha que quedaba por visitar en el
\'arbol, por lo que se da por finalizado el an\'alisis con
\'exito.
\end{enumerate}
\end{ejemplo}
\subsection{An\'alizadores sint\'acticos predictivos}
Para que el algoritmo tenga una complejidad lineal, siempre debe saber
qu\'e regla se debe aplicar, por lo que es
necesario que el analizador realice una {\em predicci\'on\/} de la regla
a aplicar.
Para ello, se debe conocer, dado el {\em token\/} de la entrada, $a$,
que est\'e siendo analizado y el no terminal a expandir $A$,
cu\'al de las alternativas de producci\'on
$A \rightarrow \alpha_1 \opt \alpha_2 \opt \ldots \opt \alpha_n$
es la \'unica posible que da lugar a que el resto de la cadena que
se est\'a analizando empiece por $a$. Dicho de otra manera,
la alternativa apropiada debe poderse predecir s\'olo con ver el
primer s\'{\i}mbolo que produce (como as\'{\i} sucede en la
mayor\'{\i}a de lenguajes de programaci\'on). Veremos qu\'e
forma deben tener las gram\'aticas a las que se puede aplicar
esta metodolog\'{\i}a.
\begin{ejemplo}
$$
\begin{array}{lcl}
\nter{Sent} \der \ter{if} \nter{Expres}\; \ter{then} \nter{Sent} \\
\nter{Sent} \der \ter{while} \nter{Expres}\; \ter{do} \nter{Sent} \\
\nter{Sent} \der \ter{begin} \nter{Sent}\; \ter{end} \\
\end{array}
$$
En esta gram\'atica siempre existe s\'olo una posibilidad
de derivaci\'on, seg\'un que el primer símbolo que
haya en la entrada en el momento de tomar esa decisi\'on sea {\bf if},
{\bf while} o {\bf begin}.
\end{ejemplo}
Seg\'un la nomenclatura que ya hemos introducido, las gram\'aticas
que son susceptibles de ser analizadas sint\'acticamente de
forma descendente mediante un an\'alisis predictivo y consultando
únicamente un símbolo de entrada
pertenecen al conjunto de gram\'aticas denominado LL(1). En un
an\'alisis de izquierda a derecha de la cadena de entrada y
haciendo derivaciones por la izquierda, debe bastar con ver un solo
símbolo (terminal) en la cadena para saber en cada caso qu\'e
producci\'on escoger. A partir de las gram\'aticas de tipo
LL(1) se pueden construir autom\'aticamente {\em analizadores
sint\'acticos descendentes predictivos\/} (ASDP), que no son
más que ASD sin retroceso.
\subsection{Conjuntos de predicci\'on}
Los conjuntos de
predicci\'on son conjuntos de símbolos terminales que ayudan a
predecir qu\'e regla se debe aplicar para el no terminal que hay
que derivar. Se construyen, como veremos a continuaci\'on, a
partir de los s\'{\i}mbolos de las partes derechas de las
producciones de la gram\'atica.
Para saber qu\'e regla se debe aplicar en cada caso, el
analizador consulta el siguiente símbolo en la entrada y si
pertenece al conjunto de predicci\'on de una regla (correspondiente al
no terminal que hay que derivar), aplica esa regla. Si no
puede aplicar ninguna regla, se produce un mensaje de error.
\begin{ejemplo} \label{ejanalisis}
Sup\'ongase la siguiente gram\'atica:
$$
\begin{array}{lcl}
\nter{A} \der \tertt{a} \nter{B} \tertt{c} \opt \tertt{x} \nter{C} \opt \nter{B} \\
\nter{B} \der \tertt{b} \nter{A} \\
\nter{C} \der \tertt{c} \\
\end{array}
$$
y la entrada ``\verb!babxcc!''.
Supongamos que el an\'alisis ha progresado a lo largo de los
s\'{\i}mbolos subrayados: ``\texttt{\underline{bab}xcc}''.
En esta situaci\'on, la cadena de derivaciones habr\'a sido
esta:
$$
A \deriva B \deriva \texttt{b}A \deriva \texttt{ba}B\texttt{c} \deriva
\texttt{bab}A\texttt{c}
$$
La cuesti\'on en este momento es: ¿qu\'e producci\'on
tomar para seguir el an\'alisis? Para seguir analizando, hay que
desarrollar la variable $A$ para lo que hay
tres posibles opciones. Es f\'acil,
observando las producciones de $A$
en la gram\'atica, darse cuenta que para escoger la primera
opci\'on el resto de la cadena deber\'{\i}a empezar por ``\verb!a!'';
para escoger la segunda, por ``\verb!x!'' y para la tercera, por ``\verb!b!''.
Como el resto de la cadena es ``\verb!xcc!'',
no hay duda de que hay que tomar la segunda opci\'on. Hemos hecho
uso de los conjuntos de predicci\'on.
\end{ejemplo}
\begin{ejemplo}
La siguiente gram\'atica (de la que se muestra s\'olo las
producciones del no terminal $A$,
pues el resto no influye en este caso) no cumple los requisitos para ser
LL(1):
$$
\begin{array}{lcl}
\ldots \\
\nter{A} \der \tertt{a} \nter{B} \tertt{c} \opt \tertt{a} \nter{C} \opt \nter{B} \\
\ldots \\
\end{array}
$$
Si tenemos que derivar el no terminal $A$,
no podemos saber, viendo un \'unico s\'{\i}mbolo en la
entrada, cu\'al es la opci\'on a escoger, pues si aparece
``\verb!a!'' en la entrada tenemos dos posibles opciones: la primera
y la segunda. Luego el an\'alisis no puede ser predictivo y la
gram\'atica no es LL(1).
\end{ejemplo}
\section{Cálculo de los conjuntos de predicción}
Los conjuntos de predicci\'on de una regla se calculan en funci\'on de los
primeros s\'{\i}mbolos que puede generar la parte derecha de esa
regla y, a veces (cuando esa parte derecha puede generar la cadena
vac\'{\i}a), en funci\'on de los s\'{\i}mbolos que pueden
aparecer a continuaci\'on de la parte izquierda de la regla en
una forma sentencial derivable del símbolo inicial. Para especificar
formalmente c\'omo se
calculan los conjuntos de predicci\'on es necesario estudiar
antes c\'omo se calculan los primeros s\'{\i}mbolos que genera
una cadena de terminales y no terminales (conjunto de \emph{primeros}) y
c\'omo obtener los s\'{\i}mbolos que pueden seguir a un no
terminal en una forma sentencial (conjunto de \emph{siguientes}).
\subsection{C\'alculo del conjunto de primeros}
Dada una gramática $G = (N, T, S, P)$,
la funci\'on \prim~ se aplica a cadenas de s\'{\i}mbolos
de la gram\'atica ($\alpha \in (T \cup N)^{*}$) y
devuelve un conjunto que puede contener cualesquiera terminales de la
gram\'atica y la cadena vacia, $\epsilon$.
A partir de ahora, cuando aparezca \prim$(\alpha)$,
siendo $\alpha$ una cadena de $(T \cup N)^{*}$,
nos referiremos al conjunto resultado de aplicar la
funci\'on \prim~ a la cadena $\alpha$.
\subsubsection{Definici\'on}
Si $\alpha$
es una forma sentencial compuesta por una concatenaci\'on de
s\'{\i}mbolos, \prim$(\alpha)$ es el
conjunto de terminales (o $\epsilon$) que
pueden aparecer iniciando las cadenas que pueden derivar (en cero o
m\'as pasos) de $\alpha$.
\subsubsection{Definici\'on formal}
\begin{displaymath}
a \in \prim(\alpha) \;\;\textrm{si}\;\; a \in (T \cup \{\epsilon\})
\;\;\textrm{y}\;\; \alpha \;\stackrel{*}{\Deriva}\; a\beta
\end{displaymath} para alguna cadena $\beta$.
\subsubsection{Reglas para el c\'alculo de $\prim(\alpha)$}
\begin{enumerate}
\item Si $\alpha \equiv \epsilon$, \prim$(\epsilon) = \{\; \epsilon \;\}$
\item Si $\alpha \in (T \cup N)^{+} , \alpha = a_1 a_2 \ldots a_n$, puede
darse dos casos:
\begin{enumerate}
\item Si $a_1 \equiv a \in T$, \prim$(\alpha) = \{\; a \;\}$.
\item Si $a_1 \equiv A \in N$, es necesario calcular \prim$(A)$, para lo
cual es necesario obtener los primeros de todas las partes derechas de las
producciones de $A$ en la gramática:
\begin{displaymath}
\forall A \rightarrow \alpha_i \in P,\;\; 1 \leq i \leq m,\;\; \prim(A) = \cup_{i=1}^{m} \prim(\alpha_i)
\end{displaymath}
Si, después de calcular \prim$(A)$, $\epsilon \in \prim(A)$ y $A$ no es
el último símbolo de $\alpha$ ($A \neq a_n$), entonces
$$
\prim(\alpha) = (\prim(A) - \{\;\epsilon\;\}) \cup \prim(a_2 \ldots a_n)
$$
Tanto si $A$ es el último símbolo de $\alpha$ como
si resulta que $\epsilon \notin \prim(A)$,
$$
\prim(\alpha) = \prim(A)
$$
\end{enumerate}
\end{enumerate}
Como se puede observar, esta última regla es una regla recursiva en la que
los casos base de la recursión son los terminales de la gramática y $\epsilon$~.
\begin{ejemplo} \label{gramexll}
Sea la siguiente gram\'atica para expresiones aritm\'eticas
con sumas y multiplicaciones:
$$
\begin{array}{lcl}
\nter{E} \der \nter{T} \nter{E'} \\
\nter{E'} \der \tertt{+} \nter{T} \nter{E'} \opt \epsilon \\
\nter{T} \der \nter{F} \nter{T'} \\
\nter{T'} \der \tertt{*} \nter{F} \nter{T'} \opt \epsilon \\
\nter{F} \der \tertt{(} \nter{E} \tertt{)} \opt \ter{ident} \\
\end{array}
$$
C\'alculo de los primeros de todos los no terminales de esta
gram\'a\-tica:
\begin{small}
\begin{tabular}{ll}
\prim($E'$) & $=$ \{ + , $\epsilon$ \} \\
\prim($T'$) & $=$ \{ * , $\epsilon$ \} \\
\prim($F$) & $=$ \{ ( , ident \} \\
\prim($E$) & $=^{E\rightarrow T E', T\in N}$ \prim($T$) $=^{T\rightarrow F T', F\in N}$ \prim($F$) $=$ \{ ( , ident \} \\
\end{tabular}
\end{small}
\end{ejemplo}
\begin{ejemplo}
Sea la gramática siguiente:
$$
\begin{array}{lcl}
\nter{A} \der \nter{A} \ter{a} \opt \nter{B} \nter{C} \nter{D} \\
\nter{B} \der \ter{b} \opt \epsilon \\
\nter{C} \der \ter{c} \opt \epsilon \\
\nter{D} \der \ter{d} \opt \nter{C} \ter{e} \\
\end{array}
$$
Calculamos los conjuntos de primeros de todas las variables de esta
gram\'a\-tica:
\begin{small}
\begin{tabular}{lcl}
\prim($C$) &$=$& \{ c, $\epsilon$ \} \\
\prim($B$) &$=$& \{ b, $\epsilon$ \} \\
\prim($D$) &$=$& \prim(d) $\cup$ \prim($C$e) $=$ \{ d \} $\cup$
(\prim($C$)$-$\{$\epsilon$\}) $\cup$ \prim(e) $=$\\
& & \{ d, c, e \} \\
\prim($A$) &$=$& \prim($A$a) $\cup$ \prim($BCD$) $=$ \prim($BCD$) $=$
\{ b \} $\cup$ \prim($CD$) $=$ \\
& & \{ b, c \} $\cup$ \prim($D$) $=$ \{ b, c, d, e \} \\
\end{tabular}
\end{small}
Si a\~nadimos la regla $D \longrightarrow \epsilon$, hay que cambiar los
cálculos, pues habría que añadir $\epsilon$ a \prim($D$) y eso cambiaría
el cálculo de \prim($A$):
\begin{small}
\begin{tabular}{lcl}
\prim($BCD$) &$=$& \{ b \} $\cup$ \prim($CD$) $=$ \{ b, c \} $\cup$ \prim($D$) $=$ \{ b, c, d, e, $\epsilon$ \} \\
\end{tabular}
\end{small}
Entonces \prim($A$) $=$ \{ b, c, d, e, $\epsilon$ \}, pero puesto que
ahora la regla $A \longrightarrow BCD$ puede derivar a $\epsilon$, eso
implica que $A$ puede desaparecer de la primera posición de la
regla $A \longrightarrow A$a y, por tanto, también hay que añadir ``a'' al
conjunto de \prim($A$):
\begin{small}
\begin{tabular}{lcl}
\prim($A$) &$=$& \{ b, c, d, e, $\epsilon$, a \} \\
\end{tabular}
\end{small}
\end{ejemplo}
\subsection{C\'alculo del conjunto de siguientes}
La funci\'on \sig~ se aplica a no terminales de la
gram\'atica ($A \in N$) y
devuelve un conjunto que puede contener cualesquiera terminales
de la gram\'atica y un s\'{\i}mbolo
especial, ``$\$$'', que representa el final de la cadena de
entrada (el final del fichero en un compilador).
\subsubsection{Definici\'on}
Si $A$ es un s\'{\i}mbolo
no terminal de la gram\'atica, \sig($A$) es el conjunto de
terminales (y $\$$) que pueden aparecer a continuaci\'on de $A$ en alguna
forma sentencial derivada del s\'{\i}mbolo inicial.
\subsubsection{Definici\'on formal}
\begin{displaymath}
a \in \sig(A) \;\;\textrm{si}\;\; a \in (T \cup \{\$\}) \;\;\textrm{y}\;\;
\exists\alpha,\beta\;/\; S \stackrel{*}{\Deriva} \alpha Aa\beta \;\;\textrm{para algún par de cadenas}\;\; \alpha, \beta.
\end{displaymath}
\subsubsection{Reglas para su c\'alculo}
\begin{enumerate}
\item Inicialmente,
\begin{tabular}{l}
\sig($A$) $=$ $\emptyset$
\end{tabular}
\item Si $A$ es el s\'{\i}mbolo inicial, entonces
\begin{tabular}{l}
\sig($A$) $=$ \sig($A$) $\cup$ \{\$\}
\end{tabular}
\item {\bf (S1)} Para cada regla de la forma $B \longrightarrow \alpha A \beta$
\begin{tabular}{l}
\sig($A$) $=$ \sig($A$) $\cup$ (\prim($\beta$) $-$ \{ $\epsilon$ \})
\end{tabular}
\item {\bf (S2)} Para cada regla de la forma $B \longrightarrow \alpha A $ o
bien de la forma $B \longrightarrow \alpha A \beta$ en la que $\epsilon \in$ \prim($\beta$)
\begin{tabular}{l}
\sig($A$) $=$ \sig($A$) $\cup$ \sig($B$)
\end{tabular}
\item Repetir los pasos 3 y 4 hasta que no se puedan a\~nadir m\'as
s\'{\i}mbolos a \sig($A$).
\end{enumerate}
\begin{small}
\paragraph{Nota:} Las reglas {\bf (S1)} y {\bf (S2)} no son excluyentes. Primero
habr\'a que intentar aplicar {\bf (S1)} y luego {\bf (S2)}.
S\'olo en el caso de producciones del tipo $B \longrightarrow \alpha A$
no tendr\'a sentido intentar aplicar {\bf (S1)}.
\end{small}
\begin{ejemplo}
En la gram\'atica de las expresiones aritm\'eticas del
ejemplo~\refej{gramexll} calcularemos los conjuntos siguientes de todos los
s\'{\i}mbolos no terminales:
\begin{small}
\begin{tabular}{l}
\sig($E$) $=$ \{ \$ \} {\tiny (porque $E$ es el símbolo inicial)} $\cup$
{\tiny (\textbf{(S1)} $F\rightarrow (E)$)} \{ ) \} $=$ \{ \$, ) \}\\
\sig($E'$) $=$ {\tiny (\textbf{(S2)} $E\rightarrow TE'$ y
$E'\rightarrow +TE'$)} \sig($E'$) {\tiny ($=\emptyset$)} $\cup$
\sig($E$) $=$ \{ \$, ) \} \\
\sig($T$) $=$ {\tiny (\textbf{(S1)} $E\rightarrow TE'$ y $E'\rightarrow +TE'$)}
(\prim($E'$) $-$ \{ $\epsilon$ \}) $\cup$
{\tiny (\textbf{(S2)} $E'\rightarrow \epsilon$)} (\sig($E$) $\cup$ \sig($E'$)) \\
\hspace{1cm} $=$ \{ + \} $\cup$ \{ \$, ) \} $=$ \{ +, \$ , ) \} \\
\sig($T'$) $=$ {\tiny (\textbf{(S2)} $T\rightarrow FT'$ y
$T'\rightarrow *FT'$)} \sig($T'$) {\tiny ($=\emptyset$)} $\cup$
\sig($T$) $=$ \{ +, \$, ) \} \\
\sig($F$) $=$ {\tiny (\textbf{(S1)} $T\rightarrow FT'$ y $T\rightarrow *FT'$)} (\prim($T'$) $-$ \{ $\epsilon$ \}) $\cup$
{\tiny (\textbf{(S2)} $T'\rightarrow \epsilon$)} (\sig($T$) $\cup$ \sig($T'$)) \\
\hspace{1cm} $=$ \{ * \} $\cup$ \{ +, \$, ) \} $=$ \{ *, +, \$, ) \}\\
\end{tabular}
\end{small}
\end{ejemplo}
\subsection{C\'alculo del conjunto predicción}
La funci\'on \pred~ se aplica a producciones de la
gram\'atica ($A \longrightarrow \alpha$) y
devuelve un conjunto, llamado {\em conjunto de predicci\'on},
que puede contener cualesquiera terminales de la gram\'atica y
el s\'{\i}mbolo ``$\$$'', pero nunca puede contener $\epsilon$.
Cuando el ASDP tiene que derivar un no terminal,
consulta el s\'{\i}mbolo de la entrada que espera a ser analizado y
lo busca en los conjuntos de predicci\'on de cada regla de ese
no terminal (véase el ejemplo~\refej{ejanalisis}). De esta
forma y siempre que los conjuntos de predicci\'on de todas las
reglas de cada no terminal por separado sean disjuntos entre s\'{\i}
(aunque puede suceder que dos conjuntos de predicci\'on de
no terminales distintos tengan s\'{\i}mbolos comunes), el analizador
sint\'actico puede construir una derivaci\'on por la
izquierda de la cadena de entrada.
\subsubsection{Regla para su c\'alculo}
\begin{center}
\begin{tabular}{ll}
\pred($A \longrightarrow \alpha$) $=$ & \\
\hspace{1em} si $\epsilon \in$ \prim($\alpha$) entonces & $=$ (\prim($\alpha$) $-$ \{ $\epsilon$ \}) $\cup$ \sig($A$) \\
\hspace{1em} si no & $=$ \prim($\alpha$) \\
\end{tabular}
\end{center}
\begin{ejemplo}
Supóngase la siguiente gramática:
$$
\begin{array}{lcl}
\nter{S} \der \nter{A} \nter{B} \opt \ter{s} \\
\nter{A} \der \ter{a} \nter{S} \ter{c} \opt \ter{e} \nter{B} \ter{f} \opt \epsilon \\
\nter{B} \der \ter{b} \nter{A} \ter{d} \opt \epsilon \\
\end{array}
$$
Calculamos los conjuntos de predicción utilizando la regla adecuada en cada
caso:
\begin{small}
\begin{tabular}{l}
\pred($S \longrightarrow A B$) $=$ (\prim($AB$)$-$\{$\epsilon$\}) $\cup$ \sig($S$) \\
\hspace{4cm} $=$ \{ a, e, b, \verb|$|, c \} \\
\pred($S \longrightarrow {\bf s}$) $=$ \prim(s) $=$ \{ s \} \\
\pred($A \longrightarrow {\bf a} S {\bf c}$) $=$ \prim(a$S$c) $=$ \{ a \} \\
\pred($A \longrightarrow {\bf e} B {\bf f}$) $=$ \prim(e$B$f) $=$ \{ e \} \\
\pred($A \longrightarrow \epsilon$) $=$ (\prim($\epsilon$)-\{$\epsilon$\}) $\cup$ \sig($A$) $=$ \{ d, b, \verb|$|, c \} \\
\pred($B \longrightarrow {\bf b} A {\bf d}$) $=$ \prim(b$A$d) $=$ \{ b \} \\
\pred($B \longrightarrow \epsilon$) $=$ (\prim($\epsilon$)-\{$\epsilon$\}) $\cup$ \sig($B$) $=$ \{ f, \verb|$|, c \} \\
\end{tabular}
\end{small}
¿Pod\'{\i}a construirse un ASDP a la vista de estos conjuntos?
\end{ejemplo}
\section{La condición LL(1)}
Para que una
gram\'atica pertenezca al conjunto de gram\'aticas LL(1) ha
de cumplir la condici\'on LL(1). Esta condici\'on no ``salta
a la vista'' a partir del aspecto de las producciones de la
gram\'atica, sino que tiene que ver con el contenido de los
conjuntos de predicci\'on de las reglas que derivan de un mismo
no terminal.
Para que la regla a aplicar sea siempre \'unica, se debe exigir
que los conjuntos de predicci\'on de las reglas de cada no
terminal sean disjuntos entre s\'{\i}; es decir, no puede haber
ning\'un s\'{\i}mbolo terminal que pertenezca a dos o
m\'as conjuntos de predicci\'on de las reglas de un mismo no
terminal. Si se cumple esta condici\'on, la gram\'atica es
LL(1) y se puede realizar su an\'alisis sint\'actico en
tiempo lineal.
La condici\'on LL(1) es necesaria y suficiente para poder
construir un ASDP para una gram\'atica. Una gramática que cumple la
condición LL(1) se dice que es una gramática LL(1). Estas gramáticas
tienen las siguientes propiedades o caracter\'{\i}sticas para su
análisis:
\begin{itemize}
\item La secuencia de {\em tokens\/} se analiza de izquierda a derecha.
\item Siempre se deriva el no terminal que aparezca m\'as a la izquierda.
\item S\'olo será necesario ver un
{\em token\/} de la secuencia de entrada para averiguar qu\'e
producci\'on seguir.
\end{itemize}
%Vamos a ver formalmente dicha condici\'on.
\subsubsection{Condici\'on LL(1)}
Dadas todas las producciones de la gram\'atica para un mismo
terminal:
$$
\begin{array}{lcll}
\nter{A} \der \alpha_1 \opt \alpha_2 \opt \ldots \opt \alpha_n & \forall A \in N \\
\end{array}
$$
se debe cumplir la siguiente condici\'on:
$$
\forall i,j \;(i \neq j) \;\;\; \pred(A \rightarrow \alpha_i ) \cap
\pred(A \rightarrow \alpha_j ) = \emptyset
$$
\begin{ejemplo}
Sea la siguiente gram\'atica con sus conjuntos de
predicci\'on ya calculados para cada regla:
$$
\begin{array}{lcll}
\nter{A} \der \ter{a} \ter{b} \nter{B} & \{ \ter{a} \} \\
\nter{A} \der \nter{B} \ter{b} & \{ \ter{b}, \ter{c} \} \\
\nter{B} \der \ter{b} & \{ \ter{b} \} \\
\nter{B} \der \ter{c} & \{ \ter{c} \} \\
\end{array}
$$
Se puede afirmar que es LL(1) porque los conjuntos de predicci\'on de las
dos reglas del no terminal $A$ son disjuntos entre s\'{\i}, y los conjuntos
de predicci\'on de las reglas de $B$ tambi\'en lo son. Como se puede comprobar,
los s\'{\i}mbolos {\bf b} y {\bf c} pertenecen a varios conjuntos de
predicci\'on de reglas de diferentes no terminales y, sin embargo, la gram\'atica
sigue siendo LL(1). Si a\~nadimos la regla
$$
\begin{array}{lcl}
\nter{B} \der \ter{a}
\end{array}
$$
los conjuntos de predicci\'on quedar\'{\i}an de la siguiente manera:
$$
\begin{array}{lcll}
\nter{A} \der \ter{a} \ter{b} \nter{B} & \{ \ter{a} \} \\
\nter{A} \der \nter{B} \ter{b} & \{ \ter{a}, \ter{b}, \ter{c} \} \\
\nter{B} \der \ter{b} & \{ \ter{b} \} \\
\nter{B} \der \ter{c} & \{ \ter{c} \} \\
\nter{B} \der \ter{a} & \{ \ter{a} \} \\
\end{array}
$$
Con esta nueva regla, los conjuntos de predicci\'on de las reglas del no
terminal $A$ ya no son disjuntos (el s\'{\i}mbolo {\bf a} pertenece a
ambos) y por tanto la gram\'atica no es LL(1), independientemente de si
los conjuntos de predicci\'on de las reglas de $B$ son o no disjuntos.
\end{ejemplo}
\begin{ejemplo}
Sea la siguiente gramática:
$$
\begin{array}{lcl}
\nter{E} \der \nter{E} \tertt{+} \nter{T} \opt \nter{T} \\
\nter{T} \der \nter{T} \tertt{*} \nter{F} \opt \nter{F} \\
\nter{F} \der \ter{num} \opt \tertt{(} \nter{E} \tertt{)} \\
\end{array}
$$
Se trata de estudiar si cumple la condición LL(1). Para ello se
calculan los conjuntos de predicción:
\begin{small}
\begin{tabular}{l}
\pred($E \longrightarrow E + T$) $=$ \prim($E+T$) $=$ \{ \textbf{num}, \verb!(! \} \\
\pred($E \longrightarrow T$) $=$ \prim($T$) $=$ \{ \textbf{num}, \verb!(! \} \\
\pred($T \longrightarrow T * F$) $=$ \prim($T*F$) $=$ \{ \textbf{num}, \verb!(! \} \\
\pred($T \longrightarrow F$) $=$ \prim($F$) $=$ \{ \textbf{num}, \verb!(! \} \\
\pred($F \longrightarrow$ num) $=$ \prim(\textbf{num}) $=$ \{ \textbf{num} \} \\
\pred($F \longrightarrow (E)$) $=$ \prim($(E)$) $=$ \{ \verb!(! \} \\
\end{tabular}
\end{small}
Para el símbolo $F$, la intersección de los conjuntos de predicción de
todas las reglas en las que se desarrolla es:
\begin{small}
\begin{tabular}{l}
\pred($F \longrightarrow \ter{num}$) $\cap$ \pred($F \longrightarrow (E)$) $=$
\{ \textbf{num} \} $\cap$ \{ \verb!(! \} $=$ $\emptyset$ \\
\end{tabular}
\end{small}
pero no sucede lo mismo con los conjuntos de predicción de las producciones
de $T$, que
son iguales (por lo tanto, no disjuntos), por lo que la gramática no cumple
la condición LL(1). Con el no terminal $E$ ocurre lo mismo que con $T$.
\end{ejemplo}
\begin{ejemplo}
¿Cumple la condición LL(1) la siguiente gramática?
$$
\begin{array}{lcl}
\nter{E} \der \nter{T} \nter{E'} \\
\nter{E'} \der \tertt{+} \nter{T} \nter{E'} \opt \epsilon \\
\nter{T} \der \nter{F} \nter{T'} \\
\nter{T'} \der \tertt{*} \nter{F} \nter{T'} \opt \epsilon \\
\nter{F} \der \ter{num} \opt \tertt{(} \nter{E} \tertt{)} \\
\end{array}
$$
No hace falta calcular los conjuntos de predicci\'on de aquellas
variables que no tienen m\'as que una opci\'on para su
desarrollo. Si s\'olo hay una opci\'on, no se plantear\'a
nunca dudas sobre qu\'e opci\'on elegir. S\'olo
aquellas variables con dos o m\'as alternativas son las que hay
que estudiar para ver si sus conjuntos de predicci\'on son
disjuntos. Por lo tanto, en este ejemplo no hace falta calcular
\pred($E \rightarrow TE'$) ni \pred($T \rightarrow FT'$).
Vamos a ver qu\'e ocurre con los restantes.
\begin{small}
\begin{tabular}{l}
\pred($E' \longrightarrow \tertt{+} T E'$) $=$ \{ \verb!+! \} \\
\pred($E' \longrightarrow \epsilon$) $=$ \sig($E'$) = \{ \$, \verb!)! \} \\
\\
\pred($T' \longrightarrow \tertt{*} F T'$) $=$ \{ \verb!*! \} \\
\pred($T' \longrightarrow \epsilon$) $=$ \sig($T'$) = \{ \verb!+!, \$, \verb!)! \} \\
\\
\pred($F \longrightarrow \ter{num}$) $=$ \{ \textbf{num} \} \\
\pred($F \longrightarrow (E)$) $=$ \{ \verb!(! \} \\
\end{tabular}
\end{small}
Ahora, para cada uno de estos no terminales con alternativas,
comprobamos si los conjuntos de predicci\'on son disjuntos entre
s\'{\i}:
\begin{small}
\begin{tabular}{l}
\pred($E' \longrightarrow \tertt{+} T E'$) $\cap$ \pred($E' \longrightarrow \epsilon$) $=$
\{ \verb!+! \} $\cap$ \{ \verb!)!, \$ \} $=$ $\emptyset$ \\
\pred($T' \longrightarrow \tertt{*} F T'$) $\cap$ \pred($T' \longrightarrow \epsilon$) $=$
\{ \verb!*! \} $\cap$ \{ \verb!+!, \verb!)!, \$ \} $=$ $\emptyset$ \\
\pred($F \longrightarrow \ter{num}$) $\cap$ \pred($F \longrightarrow (E)$) $=$
\{ \textbf{num} \} $\cap$ \{ \verb!(! \} $=$ $\emptyset$ \\
\end{tabular}
\end{small}
Luego esta
gram\'atica cumple la condici\'on LL(1).
\end{ejemplo}
\section{Modificación de gramáticas no LL(1)}
Existen algunas
caracter\'{\i}sticas que, en el caso de ser observadas en una
gram\'atica, garantizan que no es LL(1) (sin necesidad de
calcular los conjuntos de predicci\'on); sin embargo, si ninguna
de estas caracter\'{\i}sticas aparece, la gram\'atica puede
que sea LL(1) o puede que no lo sea (en este caso s\'{\i} que hay
que calcular los conjuntos de predicci\'on para comprobarlo).
Tambi\'en, si la gram\'atica no es LL(1) no necesariamente
debe tener alguna de estas caracter\'{\i}sticas; puede que tenga
alguna, puede que las tenga todas o puede que no tenga ninguna de
ellas. Estas características son la ambigüedad, los factores comunes
por la izquierda y la recursividad izquierda.
Cualquier gram\'atica recursiva por la izquierda o con s\'{\i}mbolos
comunes por la izquierda en algunas producciones no ser\'a
LL(1). Si en una gram\'atica se elimina (como veremos más adelante)
su recursividad por la izquierda, se factoriza por la izquierda (si tuviera
factores comunes por ese lado) y no presenta ambigüedad\footnote{Si tiene
ambig\"uedad, en alg\'un momento el analizador no sabr\'a qu\'e producci\'on
seleccionar, puesto que hay al menos dos posibles an\'alisis.}, la gram\'atica
modificada resultante podr\'{\i}a ser LL(1) (analizable por un ASDP),
pero también podría resultar que no lo fuera, como la siguiente gramática:
$$
\begin{array}{lcl}
\nter{S} \der \nter{A} \opt \nter{B} \\
\nter{A} \der \ter{a} \ter{a} \\
\nter{B} \der \nter{C} \ter{b} \\
\nter{C} \der \ter{a} \nter{A} \\
\end{array}
$$
Por tanto, que una gramática no sea recursiva por la izquierda, no tenga
factores comunes por la izquierda y no sea ambigua es una condición necesaria
para que sea LL(1), pero no suficiente.
Por otra parte, veremos que si nos encontramos una gram\'atica
que no sea LL(1) existen m\'etodos para modificarla y convertirla en una
gramática que pudiera ser LL(1).
\subsection{Eliminaci\'on de la ambig\"uedad}
Cualquier gram\'atica
ambigua no cumple la condición LL(1) ya que, por la propia definici\'on
de esta propiedad, en alg\'un caso no sabremos qu\'e producci\'on
tomar a la vista de un \'unico s\'{\i}mbolo, pues habr\'a
m\'as de un posible \'arbol de an\'alisis sint\'actico.
Esto no quiere decir que si la gram\'atica no es ambigua
entonces ser\'a LL(1), pues puede presentar otros problemas,
como veremos a continuaci\'on.
El problema de la ambig\"uedad es el m\'as dif\'{\i}cil de
resolver pues no existe una metodolog\'{\i}a para eliminarla y
tampoco hay otra f\'ormula para saber que una gram\'atica
es ambigua más que la de encontrar alguna sentencia que tenga dos o más
\'arboles de an\'alisis sint\'actico distintos.
La mejor opci\'on cuando se presenta una gram\'atica
ambigua es replantearse el dise\~no de la misma para encontrar
una gram\'atica no ambigua equivalente (que genere el mismo
lenguaje).
\subsection{Factorizaci\'on por la izquierda}
Si dos producciones
alternativas de un s\'{\i}mbolo $A$ empiezan igual, no se sabr\'a
por cu\'al de ellas seguir. Se trata de reescribir las
producciones de $A$ para retrasar la decisi\'on hasta haber visto
lo suficiente de la entrada como para elegir la opci\'on
correcta.
\begin{ejemplo}
Sean las producciones:
$$
\begin{array}{lcl}
\nter{Sent} \der \ter{if} \nter{Expr} \ter{then} \nter{Sent} \ter{else} \nter{Sent} \\
\nter{Sent} \der \ter{if} \nter{Expr} \ter{then} \nter{Sent} \\
\nter{Sent} \der \nter{Otras}\\
\end{array}
$$
Al ver ``{\bf if}''
no se sabe cu\'al de las dos producciones hay que tomar para
expandir $Sent$.
De hecho, un analizador sint\'actico descendente no sabr\'{\i}a
qu\'e hacer hasta superar el cuarto s\'{\i}mbolo de esta
producci\'on. Si entonces llega ``{\bf else}''
ya sabe que se trataba de la primera y si entra cualquier otro {\em token\/}
entonces se trataba de la segunda. Pero esto ocurre demasiado {\em tarde\/}
para el an\'alisis sint\'actico predictivo.
\end{ejemplo}
Nos enfrentamos, pues, al problema de producciones que tienen
s\'{\i}mbolos comunes por la izquierda; es decir, si son del tipo
$A \rightarrow \alpha \beta_1 \opt \alpha \beta_2$ .
En estos casos, ante una entrada del prefijo $\alpha$,
no sabemos si derivar por $\alpha \beta_1$ o por $\alpha \beta_2$.
La soluci\'on pasa por modificar las producciones afectadas cambiando
$$
\begin{array}{lcl}
A \der \alpha \beta_1 \opt \alpha \beta_2
\end{array}
$$
por dos producciones:
$$
\begin{array}{lcl}
A \der \alpha A' \\
A' \der \beta_1 \opt \beta_2
\end{array}
$$
Con esto se retrasa el momento de la decisi\'on hasta despu\'es
de analizar los s\'{\i}mbolos comunes y se soluciona uno de los
problemas que ten\'{\i}a esa gram\'atica para no cumplir la
condici\'on LL(1).
Veamos la regla general para factorizar por la izquierda una
gram\'atica. Para todos los no terminales, $A$, de la
gram\'atica, se debe encontrar el prefijo $\alpha$
m\'as largo com\'un a dos o m\'as producciones de $A$, pero siempre
aquel que sea común a más producciones. Es posible que dos producciones
presenten un prefijo común $\gamma$ pero exista otra producción que tenga un
prefijo común con ambas $\delta$ que sea más corto ($ \gamma = \delta\beta\;$ y
$\;|\delta| < |\gamma|$).
En este caso, primero es necesario eliminar el factor común $\delta$ y después
habrá que eliminar el resto de $\gamma$, es decir, $\beta$.
Si existe dicho prefijo común $\alpha \neq \epsilon$, entonces hay que
sustituir las producciones
$$
\begin{array}{lcl}
A \der \alpha \beta_1 \opt \alpha \beta_2 \opt \ldots \opt \alpha \beta_n \opt \gamma_i
\end{array}
$$
donde $\gamma_i$ representa a todas las alternativas que no empiezan por
$\alpha$, por:
$$
\begin{array}{lcl}
A \der \alpha A' \opt \gamma_i \\
A' \der \beta_1 \opt \beta_2 \opt \ldots \opt \beta_n \\
\end{array}
$$
Este paso debe repetirse para todos los prefijos comunes por la izquierda (de
un mismo no terminal, por supuesto) que
queden en la gramática.
\begin{ejemplo}
$$
\begin{array}{lcl}
\nter{Sent} \der \ter{if} \nter{Expr} \ter{then} \nter{Sent} \ter{else} \nter{Sent} \ter{endif} \\
\nter{Sent} \der \ter{if} \nter{Expr} \ter{then} \nter{Sent} \ter{endif}\\
\nter{Sent} \der \nter{Otras}\\
\end{array}
$$
Fij\'andonos en la regla para factorizar, podemos identificar:
$$
\begin{array}{lcl}
\alpha &\equiv& \ter{if} \nter{Expr} \ter{then} \nter{Sent} \\
\beta_1 &\equiv& \ter{else} \nter{Sent} \ter{endif}\\
\beta_2 &\equiv& \ter{endif} \\
\gamma_i &\equiv& \nter{Otras} \\
\end{array}
$$
Con lo que la gram\'atica factorizada queda
$$
\begin{array}{lcl}
\nter{Sent} \der \ter{if} \nter{Expr} \ter{then} \nter{Sent} \nter{Sent'} \\
\nter{Sent} \der \nter{Otras} \\
\nter{Sent'} \der \ter{else} \nter{Sent} \ter{endif} \\
\nter{Sent'} \der \ter{endif} \\
\end{array}
$$
Adicionalmente, sup\'ongase que el no terminal $Otras$ deriva en
un terminal cualquiera ``\verb!x!''. Compru\'ebese que
esta gram\'atica es ahora LL(1).
\end{ejemplo}
\subsection{Eliminaci\'on de la recursividad por la izquierda}
Una gram\'atica es recursiva por la izquierda si
tiene alguna producci\'on que sea recursiva por la izquierda (\emph{recursividad
directa por la izquierda}) o bien si a partir de una forma sentencial como
$A\gamma$ se obtiene (después de dos o más derivaciones) una forma sentencial
$A\beta\gamma$ en la que el no terminal $A$ vuelve a ser el primero por
la izquierda (\emph{recursividad indirecta por la izquierda}). En general,
una gramática es recursiva por la izquierda si
$$
\exists A \in N \;\;/\;\; A \stackrel{*}{\deriva} A \alpha \;\;\;\textrm{para alguna cadena}\;\; \alpha
$$
Los analizadores sint\'acticos descendentes no pueden manejar
estas gram\'a\-ticas pues entrar\'{\i}an en ciclos de
recursividad infinita al ejecutarse. Cualquier gram\'atica
recursiva por la izquierda no cumple la condici\'on LL(1).
Para gram\'aticas de la forma:
$$
\begin{array}{l@{\;\;\;}c@{\;\;\;}l}
A \rightarrow A \alpha \opt \beta \der \textrm{ genera el lenguaje:}\;\; \beta, \beta\alpha, \beta\alpha\alpha, \ldots \\
\end{array}
$$
existe una regla para modificar este tipo de producciones para que
dejen de ser recursivas por la izquierda:
$$
\begin{array}{lcll}
A \der \beta A' & \textrm{(nuevo no terminal auxiliar)} \\
A' \der \alpha A' & \textrm{(recursiva por la derecha)} \\
A' \der \epsilon & \\
\end{array}
$$
Esta gram\'atica modificada ya no es recursiva por la izquierda,
por lo que ya no presenta el problema que le imped\'{\i}a ser LL(1).
\begin{ejemplo} \label{ejarit}
Eliminar la recursividad izquierda de la gram\'atica de las
expresiones aritm\'eticas.
$$
\begin{array}{lcl}
\nter{E} \der \nter{E} \tertt{+} \nter{T} \opt \nter{E} \tertt{-} \nter{T} \opt\nter{T} \\
\nter{T} \der \nter{T} \tertt{*} \nter{F} \opt \nter{T} \tertt{/} \nter{F} \opt \nter{F} \\
\nter{F} \der \ter{num} \opt \tertt{(} \nter{E} \tertt{)} \\
\end{array}
$$
En el caso del no terminal $E$,
$$
\begin{array}{lcl||clcl}
\alpha_1 &\equiv& \tertt{+} \nter{T} & &\nter{E} \der \nter{T} \nter{E'} \\
\alpha_2 &\equiv& \tertt{-} \nter{T} & \deriva & \nter{E'} \der \tertt{+} \nter{T} \nter{E'} \opt \tertt{-} \nter{T} \nter{E'} \opt \epsilon\\
\beta &\equiv& \nter{T} & & \\
\end{array}
$$
Lo mismo sucede con el no terminal $T$. Por tanto nos queda la siguiente
gram\'atica:
$$
\begin{array}{lcl}
\nter{E} \der \nter{T} \nter{E'} \\
\nter{E'} \der \tertt{+} \nter{T} \nter{E'} \opt \tertt{-} \nter{T} \nter{E'} \opt \epsilon \\
\nter{T} \der \nter{F} \nter{T'} \\
\nter{T'} \der \tertt{*} \nter{F} \nter{T'} \opt \tertt{/} \nter{F} \nter{T'} \opt \epsilon \\
\nter{F} \der \ter{num} \opt \tertt{(} \nter{E} \tertt{)} \\
\end{array}
$$
\end{ejemplo}
En el caso general, independientemente de cu\'antas producciones
alternativas haya de $A$, se puede eliminar la recursividad por la
izquierda utilizando las siguientes reglas:
$$
\begin{array}{lcl}
A \der A\alpha_1 \opt A\alpha_2 \opt \ldots \opt A\alpha_m \opt \beta_1 \opt \beta_2 \opt \ldots \opt \beta_n
\end{array}
$$
Se sustituye por:
$$
\begin{array}{lcl}
A \der \beta_1 A' \opt \beta_2 A' \opt \ldots \opt \beta_n A' \\
A' \der \alpha_1 A' \opt \alpha_2 A' \opt \ldots \opt \alpha_m A' \opt \epsilon \\
\end{array}
$$
Estas reglas no sirven para eliminar la recursividad indirecta
por la izquierda, como la que se presenta en el siguiente ejemplo.
\begin{ejemplo} \label{recindirecta}
Sea la siguiente gram\'atica:
$$
\begin{array}{lcl}
\nter{S} \der \nter{A} \ter{a} \opt \ter{b} \\
\nter{A} \der \nter{A} \ter{c} \opt \nter{S} \ter{d} \opt \epsilon \\
\end{array}
$$
$ S \deriva Aa \deriva Sda $, luego $ S \stackrel{2}{\deriva} Sda $ (recursividad indirecta).
\end{ejemplo}
Para resolver este problema se proporciona el siguiente algoritmo capaz de
eliminar la recursividad indirecta sistem\'aticamente. Funciona si la
gram\'atica no tiene ciclos ($A \stackrel{+}{\deriva} A$)
o producciones vac\'{\i}as ($A \rightarrow \epsilon$).
\paragraph{Pasos:}
\begin{enumerate}
\item Ordenar los no terminales seg\'un $A_1, A_2, \ldots, A_n$
\item
\begin{tabbing}
D\=D\=Sus\= \kill
DESDE $i \leftarrow 1$ HASTA $n$ HACER \\
\> DESDE $j \leftarrow 1$ HASTA $i-1$ HACER \\
\>\> Sustituir cada $A_i \rightarrow A_j \gamma$ ~~ por ~~
$A_i \rightarrow \delta_1 \gamma \opt \delta_2 \gamma \opt \ldots \opt \delta_k \gamma$ \\
\>\>\> donde $A_j \rightarrow \delta_1 \opt \delta_2 \opt \ldots \opt \delta_k$ son las producciones \\
\>\>\> actuales de $A_j$ \\
\>\> Eliminar la recursividad izquierda directa de $A_i$ \\
\> FIN\_DESDE \\
FIN\_DESDE \\
\end{tabbing}
\end{enumerate}
\begin{ejemplo}
Vamos a deshacer la recursividad por la izquierda que presentaba el
ejemplo~\refej{recindirecta}:
$$
\begin{array}{lcl}
\nter{S} \der \nter{A} \ter{a} \opt \ter{b} \\
\nter{A} \der \nter{A} \ter{c} \opt \nter{S} \ter{d} \opt \epsilon \\
\end{array}
$$
\begin{enumerate}
\item $A_1 = S, A_2 = A$
\item Para $i=1$: desde $j\leftarrow 1$ hasta $0$ hacer: {\em nada} \newline
Para $i=2$: desde $j\leftarrow 1$ hasta $1$ hacer:
\begin{quote}
tomamos el segundo y lo sustituimos por el primero en todos los
lugares donde \'este aparezca a la derecha:
\begin{small}
$$
\begin{array}{lcl||lcl}
\nter{S} \der \nter{A} \ter{a} \opt \ter{b} \;\; & \;\;\nter{S} \der \nter{A} \ter{a} \opt \ter{b} \\
\nter{A} \der \nter{A} \ter{c} \opt \nter{S} \ter{d} \opt \epsilon \;\; & \;\;\nter{A} \der \nter{A} \ter{c} \opt \nter{A} \ter{a} \ter{d} \opt \ter{b} \ter{d} \opt \epsilon \\
\end{array}
$$
\end{small}
Si hubiera otra regla: $X \rightarrow S a \opt Ab \opt \ldots $
sustituir $S$ y $A$ por su definici\'on en las producciones de $X$.
\end{quote}
\end{enumerate}
A esto le quitamos la recursividad directa. S\'olo hay que modificar $A$ y
queda
$$
\begin{array}{lcl}
\nter{S} \der \nter{A} \ter{a} \opt \ter{b} \\
\nter{A} \der \ter{b} \ter{d} \nter{A'} \opt \nter{A'} \\
\nter{A'} \der \ter{c} \nter{A'} \opt \ter{a} \ter{d} \nter{A'} \opt \epsilon \\
\end{array}
$$
\end{ejemplo}
\begin{ejemplo}
Sea la siguiente gram\'atica:
$$
\begin{array}{lcl}
\nter{S} \der \nter{S} \ter{inst} \opt \nter{T} \nter{R} \nter{V} \\
\nter{T} \der \ter{tipo} \opt \epsilon \\
\nter{R} \der \ter{blq} \nter{V} \ter{fblq} \opt \epsilon \\
\nter{V} \der \ter{id} \nter{S} \ter{fin} \opt \ter{id} \ter{;} \opt \epsilon \\
\end{array}