Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Compiladores
Compiladores
Primer cuatrimestre:
Introduccin
Lenguajes y gramticas
Anlisis Lxico
Anlisis Sintctico
NDICE
1
INTRODUCCIN. ................................................................................................... 1
1.1
Estructura de un compilador.......................................................................... 2
1.2
2.2
2.3
2.4
Diagramas de Conway..................................................................................... 9
2.5
2.6
2.6.1
2.6.2
2.6.3
2.7
2.7.1
2.7.2
2.7.3
2.7.4
Recursividad. ........................................................................................................................11
Reglas con factor repetido por la izquierda. .........................................................................13
Ambigedad. ........................................................................................................................13
2.8
2.9
2.10
Resumen. ..................................................................................................... 20
2.11
Ejercicios..................................................................................................... 21
ANLISIS LXICO............................................................................................... 22
3.1
3.2
3.3
3.4
3.5
Algoritmo de Thompson................................................................................ 27
3.6
3.7
3.8
Implementacin de autmatas...................................................................... 31
3.8.1
3.8.2
3.9
Tabla compacta.....................................................................................................................31
Autmata programado. .........................................................................................................33
3.10
3.11
3.11.1
3.11.2
3.11.3
3.11.4
4.2
4.2.1
4.2.2
4.2.3
4.2.4
4.2.5
iii
BIBLIOGRAFA.
Aho, A.V.; Lam M.; Sethi, R. ; Ullman, J.D.
"Compiladores: Principios, tcnicas y herramientas"
Addison-Wesley, Reading, Massachussetts (2008).
Louden D. K. [2004], Construccin de compiladores. Principios y Prctica,
Paraninfo Thomson Learning.
Garrido, A. ; Iesta J.M. ; Moreno F. ; Prez J.A. [2004] Diseo de
compiladores, Publicaciones Universidad de Alicante.
Sanchis, F.J.; Galn, J.A.
"Compiladores, teora y construccin"
Ed. Paraninfo (1987).
Aho, A.V.; Ullman, J.D.
"The theory of parsing, translation and compiling", I y II
Prentice-Hall (1972).
Aho, A.V.; Ullman J.D.
"Principles of compiler design"
Addison-Wesley, Reading, Massachussetts.
Hopcroff, J.E. ; Motwani R. ; Ullman, J. D. [2002] Introduccin a la teora de
autmatas, lenguajes y computacin, Addison-Wesley, Madrid.
Allen I.; Holub
"Compiler design in C"
Prentice-Hall (1991).
Snchez, G.; Valverde J.A.
"Compiladores e Intrpretes"
Ed. Daz de Santos (1984).
Sudkamp T.A.
Languages and machines
Addison-Wesley.
iv
1 INTRODUCCIN.
Un lenguaje es un conjunto de oraciones finito o infinito, cada una de ellas de
longitud finita (es decir, constitudas cada una de ellas por un nmero finito
de elementos).
Compilacin: Proceso de traduccin en el que se convierte un programa
fuente (en un lenguaje de alto nivel) en un lenguaje objeto, generalmente
cdigo mquina (en general un lenguaje de bajo nivel).
La Teora de compiladores se usa para:
Realizar compiladores.
Disear procesadores de texto.
Manejo de datos estructurados (XML).
Inteligencia Artificial (en el diseo de interfaces hombre-mquina).
Traductores de lenguajes naturales.
Etc.
Se denominan tokens a los lexemas, las unidades mnimas de informacin
(por ejemplo, una instruccin FOR). La identificacin de estos elementos es la
finalidad del anlisis lxico.
Sintaxis de un lenguaje: Conjunto de reglas formales que nos permiten
construir las oraciones del lenguaje a partir de los elementos mnimos.
Semntica: Es el conjunto de reglas que nos permiten analizar el significado
de las frases del lenguaje para su interpretacin.
Intrprete: Conjunto de programas que realizan la traduccin de lenguaje
fuente a objeto, paso a paso, no de todo el programa (aparecieron por
problemas de memoria).
Ensamblador: Compilador sencillo donde el lenguaje es simple, con una
relacin uno-a-uno entre la sentencia y la instruccin mquina.
Compilacin cruzada: La compilacin se realiza en una mquina A y la
ejecucin se realiza en otra mquina B.
Link (encadenar, enlazar): Es el proceso por el cual un programa dividido en
varios mdulos, compilados por separado, se unen en un solo.
Pasadas en compilacin: Recorridos de todo el programa fuente que realiza
el compilador. Cuantas ms pasadas, el proceso de compilacin es ms
completo, aunque ms lento.
Traductor o compilador incremental, interactivo o conversacional: Es un
tipo de compilador que, al detectar un error, intenta compilar el cdigo del
entorno en donde est el error, no todo el programa de nuevo.
1
1
Programa
Fuente
ANALIZADOR
SINTCTICO
scanner
parser
6
Programa
Objeto
ANALIZADOR
LXICO
5
GENERACIN
DE CDIGO
OPTIMIZADOR
ANALIZADOR
SEMNTICO
4
GENERACIN
DE CDIGO
INTERMEDIO
ANALIZADOR SINTCTICO
:=
+
id1
id2
*
id3
60
ANALIZADOR SEMNTICO
:=
+
id1
id2
*
id3
enteroAreal
60
ADDF R2, R1
MOVF R1, id1
2 LENGUAJES Y GRAMTICAS.
Definiciones:
Alfabeto: Conjunto de smbolos que nos permiten construir las sentencias del
lenguaje.
Tira de caracteres: Yustaposicin o concatenacin de los smbolos del
alfabeto.
Tira nula ( ): Tira de longitud 0, es la tira mnima del lenguaje
Longitud de una tira: El nmero de caracteres que tiene la tira. Si tenemos
una tira x, su logitud se representa como |x|.
Ejemplo.-
x = abc |x| = 3
|| = 0
Potencia de una tira: Concatenacin de una tira consigo misma tantas veces
como indique el exponente.
Ejemplo.-
x = abc
x2 = abcabc
x0 =
x1 = abc
x = abc
Head (x) o Cabeza (x) = , a, ab, abc
x = abc
Tail (x) o Cola (x) = , c, bc, abc
An = A.An-1 ; A0={} ; A1 = A
A+ = Ui>0 Ai
A* = Ui0 Ai
A* = A+ U A0 = A+ U {}
5
S
a
S
a
b
b
Con esta definicin podemos observar que podra admitir cualquier estructura
de frase.
b) Gramticas tipo 1, gramticas sensibles al contexto o dependientes del
contexto.
G = (N, T, P, S)
A
, (N U T)*
(N U T)+
AN
, (N U T)+
|| ||
A
AN
(N U T)*
A aB ; A a ; A
aT
A, B N
7
Las gramticas tipo 3 son las ms restrictivas y las tipo 0 las menos pero existe
una peculiaridad porque, de forma terica extricta, un lenguaje
independiente del contexto es tambin un lenguaje dependiente del
contexto, pero una gramtica independiente del contexto puede no ser una
gramtica dependiente del contexto. Esto ocurrir si la gramtica contiene
reglas .
Tambin existe una pequea diferencia entre las dos definiciones mostradas
de gramticas tipo 1. Ejemplo.G = (N, T, P, S)
S ASBc
bB bb
S aBc
BC bc
CB BC
CC cc
AB ab
A
AN
(N U T)*
Gramtica S aSb |
S aSb aaSbb aaaSbbb aaaaSbbbb aaaaaSbbbbb
Es una derivacin de longitud 5.
S BcdH
B Hc
H cd
B
c
H
c
H
c
S
d
Es una derivacin
a la izquierda
Es una derivacin
a la derecha
h
S-D|D
DL|L.L
LN|NL
N0|1|2|3|4|5|6|7|8|9
S es la metanocin
D es un nmero decimal
L es una lista de dgitos
N es un nmero, un dgito
10
1iq
1jp
1jp
1iq
A aA | bA |
Si no queremos introducir reglas en la gramtica la transformacin podra
ser de la siguiente forma:
A j, A jA
A i , A iA
1jp
1iq
S uBDz
B wB
B vB |
D EF
Ey|
Fx|
12
Sa
S S+S
S S*S
S
S
a * a
a *
a + a
13
15
END
viejo := {}
nuevo := {A}
WHILE viejo nuevo DO
BEGIN
viejo := nuevo
nuevo := viejo U {C / B C, B viejo}
END
NA := nuevo
Una vez construidos los conjuntos NX, generamos el conjunto P de la
siguiente forma:
Si B P, y no es una regla unitaria, entonces hacemos que A P
A en los cuales B NA.
NOTA: con este algoritmo tambin eliminaremos las derivaciones de la forma:
A * X , es decir A B C X, y no solamente las cadenas directas.
Ejemplo.E E+T | T
T T*F | F
F (E) | a
Aplicando el algoritmo, algo muy sencillo, vemos que los conjuntos NX son:
NE = {E, T, F}
NT = {T, F}
NF = {F}
Y la gramtica sin reglas cadena resultante sera:
16
E E+T
E T*F
E (E)
Ea
T T*F
T (E)
Ta
F (E)
Fa
17
Ejemplo.Aa
Bc
H Bd
viejo
nuevo
Pasada 1
C
Pasada 2
C
C, A
Pasada 3
C, A
C, A, S, B
Pasada 4
C, A, S, B C, A, S, B
La nueva gramtica es la siguiente:
N= {C, A, S, B}
S aAA
A aAb | aC
B Ac
Cb
Ahora es cuando podemos aplicar el segundo algoritmo, el de eliminacin de
smbolos no accesibles:
viejo
Pasada 1
Pasada 2
Pasada 3
S
S, a, A
S, a, A, b, C
nuevo
S, a, A
S, a, A, b, C
S, a, A, b, C
T= { a, b }
N= { S, A, C }
S aAA
A aAb | aC
Cb
END
2.10 Resumen.
Resumiendo, los problemas que podemos encontrarnos en las gramticas son:
i)
ii)
iii)
Eliminar reglas-.
Eliminar reglas unitarias o cadena.
Eliminar smbolos intiles (1 no terminables y 2 no accesibles).
20
2.11 Ejercicios.
Ejercicio1.Simplificar la siguiente gramtica:
S aS | AB | AC
A aA |
B bB | bS
C cC |
Solucin 1.S aS | a | AB | bB | bS | b | AC | aA | a | cC | c |
S aS | a | AB | bB | bS | b | AC | aA | a | cC | c
A aA | a
B bB | bS | b
C cC | c
Ejercicio 2 .S ACA | CA | AA | C | A |
A aAa | aa | B | C
B bB | b
C cC | c
Solucin 2.S ACA | CA | AA | cC | c | aAa | aa | bB | b |
A aAa | aa | bB | b | cC | c
B bB | b
C cC | c
Ejercicio 3.S AC | BS | B
A aA | aF
B cC | D
D aD | BD | C
E aA | BSA
F bB | b
Solucin 3.Vaco
21
3 ANLISIS LXICO.
En el anlisis lxico analizamos token a token el archivo fuente. El analizador
lxico se comunica con la tabla de smbolos (TDS) en donde se encuentra la
informacin sobre los tokens, asimismo, tambin se comunica con el mdulo
de errores.
El scanner abre el fichero fuente y convierte los datos a un formato ms
regular, deshaciendo marcos, comprobando los formatos si el lenguaje es de
formato fijo, etc. Posteriormente pasa a analizar los tokens (variables,
instrucciones, etc).
Una mquina reconocedora o autmata es un dispositivo formal que nos
permite identificar un lenguaje en funcin de la aceptacin o no de las
cadenas que lo forman. Esto es, crearemos un autmata que nos reconozca si
una cadena determinada pertenece o no al lenguaje.
Esta mquina reconocedora tendr una cinta de entrada dividida en celdas
con unos smbolos que denotaremos como Te. Tambin tendremos un smbolo
especial que ser el $ que nos indicar el fin de la tira de entrada. A veces
tambin dispondremos de otro alfabeto, denominado Tp, en el caso de
utilizar autmatas con pila.
Vamos a tener movimientos que dan lugar a almacenamientos en memoria o
cambios de estado. Para realizar este trabajo dispondremos de una memoria
con posibilidad de bsqueda y un sistema de control de estados para manejar
la transicin entre los estados.
Denominamos configuracin del autmata al conjunto de elementos que
definen la situacin del autmata en un momento t. Existen dos
configuraciones especiales: inicial y final, un autmata ha reconocido una
cadena cuando pasa del estado inicial a alguno de los estados finales. Aqu
podemos decir que el lenguaje es el conjunto de tiras que reconoce el
autmata.
Hablaremos de dos tipos de autmatas:
i)
22
23
0
1
2
3
4
b
0, 2
1
2, 4
3
-
c
0, 3
1
2
3, 4
-
a,b,c
1
a,b,c
b
c
2
b
a,b,c
i)
ii)
iii)
iv)
L es un conjunto regular.
L se denota por una expresin regular.
L puede ser definido por un AFND.
Cualquier AFND puede ser transformado en un AFD.
A aB ; A a ; A , a T, A, B N
b
b
a
Z
25
El autmata sera:
a
a
b
L(r) L(s)
(r)*
(L(r))*
(r)
s|r
(r | s) | t
r (s t)
rs|rt
sr|tr
rr
(r | )*
r*
Conmutativa |
Asociativa |
Asociativa de la concatenacin
Concatenacin distributiva sobre |
Concatenacin distributiva sobre |
elemento identidad para concatenacin
Idempotencia
L U M = { s / s L s M}
LM = { st /s L y t M}
Adems tenemos que:
L* = Ui=0 Li
L+ = Ui=1 Li
Lgicamente: Li = Li-1 L
* tiene mayor precedencia, luego concatenacin y por ltimo la |. Todas
ellas son asociativas por la izquierda.
26
Para construiramos:
ii)
a Te construiramos:
a
iii)
M(s)
M(t)
27
M(s)
0a
fa
M(t)
0b
fb
fa
M(t)
0b
M(s)
0a
fa
10
28
10
(A con a mueve a B)
(A con b mueve a C)
(B con a mueve a B)
(C con a mueve a B)
(C con b mueve a C)
29
a
B
B
B
B
B
b
C
D
C
E
C
a
a
b
a
b
30
La configuracin del TF viene definida por una tupla (q, t, s), donde q es el
estado actual, t es la tira de caracteres por analizar (t Te*) y s es la tira que
ha salido (s Ts*).
Un movimiento es una transicin de la forma:
(q, a, s) |---- (q, , sz) cuando (q, a) = (q, z)
q, q Q
Te*
s Ts*
Podemos definir el conjunto de traduccin como:
Tr(TF) = {(t, s), t Te*, s Ts* / (q0, t, ) |--*-- (qf, , s), qf F}
Al igual que en el caso de los AF, pueden ser deterministas y no deterministas,
dependiendo de si exste una nica transicin posible o varias ante la misma
entrada y el mismo estado actual.
d
1
b
2
d
5
6
3
31
iv)
v)
vi)
vii)
Columna
1
4
2
3
1
5
4
PreFil
1
3
5
6
7
0
NumFil
2
2
1
1
1
0
END;
ELSE M := 9999;
END;
En nuestro ejemplo, si queremos localizar M[2, 3] haremos:
PreFil [2] = 3, NumFil[2] = 2 Entonces puede ser Valor[3] o Valor[4]
Como columna es 3 entonces M[2, 3] = 3.
3.8.2 Autmata programado.
Otra opcin es hacer un programa para realizar las transiciones, de la
siguiente forma:
estado = 1
WHILE estado 6 DO BEGIN
LeerCarcter
CASE estado OF
1:
IF Car="a" THEN estado = 2
ELSE IF Car="d" THEN estado = 5
...
2:
IF Car="e" THEN estado = 7
...
...
<escala> <entero>
| <signo> <entero>
<signo>
+|-
<dgito
0|1|2|3|4|5|6|7|8|9
Esta gramtica podemos ponerla en forma de gramtica regular, que sera la
siguiente:
33
<nmero> 0 <resto_nmero>
<nmero> 1 <resto_nmero>
...
<nmero> 9 <resto_nmero>
Este tipo de reglas las resumiremos como:
<nmero> dgito <resto_nmero>
(10 reglas)
(10 reglas)
(10 reglas)
(10 reglas)
(2 reglas, + y -)
2 resto_nmero
3 fraccin 4 resto_fraccin
6 entero_exponente
7 resto_entero_exponente
El autmata sera:
$
1
E
5
d
d
s
d
$
6
34
Dgito
2
2
4
4
7
7
7
Signo
$
8
8
6
8
<literal> | <alternativa> |
<secuencia> | <repeticin> | '(' <expresin> ')'
<expresin> '|' <expresin>
<expresin> <expresin>
<expresin> ' * '
'a' | 'b' | 'c' | ... ( 'a' | 'b' | 'c' | ... )*
nowspec
time
date
= month_name day_number
| month_name day_number ',' year_number
| day_of_week | TODAY | TOMORROW
| year_number '-' month_number '-' day_number
increment
decrement
hr24clock
inc_period
day_of_week
month_name
Dgito
T
T
U
U
V
V
V
$
Z
Z
Z
(calculamos nmero)
(calculamos fraccin)
(calculamos exponente)
Valor = num * 10
signo exp - n
36
38
R{2,}
R{2}
"[xyz\"foo"
{NOTION}
\X
| Two R or more
| Exactly two R
| The string "[xyz"foo"
| Expansion of NOTION, that as been defined above in the file
| If X is a "a", "b", "f", "n", "r", "t", or
| "v", this represent the ANSI-C interpretation of \X
\0 | ASCII 0 character
\123 | ASCII character which ASCII code is 123 IN OCTAL
\x2A | ASCII character which ASCII code is 2A in hexadecimal
RS | R followed by S
R|S | R or S
R/S | R, only if followed by S
^R | R, only at the beginning of a line
R$ | R, only at the end of a line
<<EOF>> | End of file
{return NUMBER;}
{ yylval = atoi(yytext);
return NUMBER;
}
3.11.4 Ejemplos.
Ejemplo1. Identificador de nmeros y palabras
digit
letter
delim
ws
[0-9]
[A-Za-z]
[ \t\n]
{delim}+
%%
{ws}
{ /* ignore white space */ }
{digit}+ { printf("%s", yytext); printf(" = number\n"); }
{letter}+ { printf("%s", yytext); printf(" = word\n";) }
%%
main()
{
39
yylex();
}
Ejemplo 4. Calculadora
%{
/*
**
**
**
*/
#define
#define
#define
#define
#define
#define
#define
%}
ws
[ \t]+
%%
{ws}
;
-?[0-9]+
40
printf("%s",yytext);
return (NUM);
}
"+"
"-"
"*"
"/"
"%"
. |
"\ n"
{
ECHO;
return
}
{
ECHO;
return
}
{
ECHO;
return
}
{
ECHO;
return
}
{
ECHO;
return
}
(PLUS);
(MINUS);
(MUL);
(DIV);
(MOD);
{
ECHO;
return (DELIM);
}
%%
/* main.c */
# include <stdio.h>
main()
{
int opd1, opd2, opr;
/* Look for first operand. */
if (yylex() != NUM)
{
printf("missing operand\n");
exit(1);
}
opd1 = atoi(yytext);
/* Check for operator. */
opr = yylex();
/* Bad cases - no operand - either a delimiter for a number. */
if (opr == DELIM)
{
printf("missing operator\n");
exit(1);
}
else if (opr == NUM)
{
if ((opd2=atoi(yytext)) >= 0)
{
printf("missing operator\n");
exit(1);
}
/* Problem case - distinguish operator from operand. */
else
{
opr = MINUS;
opd2 = -opd2;
41
}
}
/* Check for second operand, if not yet found. */
else if (yylex() != NUM)
{
printf("missing operand\n");
exit(1);
}
else /* Must have found operand 2 */
opd2 = atoi(yytext);
switch (opr)
{
case PLUS:
{
printf(" = %d\n",opd1 + opd2);
break;
}
case MINUS:
{
printf(" = %d\n",opd1 - opd2);
break;
}
case MUL:
{
printf(" = %d\n",opd1 * opd2);
break;
}
case DIV:
{
if (opd2 == 0)
{
printf("\nERROR: attempt to divide by zero!\n");
exit(1);
}
else
{
printf(" = %d\n",opd1 / opd2);
break;
}
}
case MOD:
{
if (opd2 == 0)
{
printf("\nERROR: attempt to divide by zero!\n");
exit(1);
}
else
{
printf(" = %d\n",opd1 % opd2);
break;
}
}
}
}
42
SS+T
ST
TT*F
TF
F (S)
Fa
Fb
Parse: 2
Parse: 2 3
F
Parse: 2 3 4
a
43
T
F
Parse: 2 3 4 6
Parse: 2 3 4 6 5
...
T
Parse: 2 3 4 6 5 1
a
Parse: 2 3 4 6 5 1 2 4 6 4 7
44
Parse: 2
Parse: 2 3
Parse: 2 3 5
As sucesivamente hasta llegar al rbol final (con un parse distinto):
S
T
T
Parse: 2 3 5 1 4 7 2 4 6 4 6
a
Adems, tambin tenemos dos posibilidades en cuando a si comenzamos
desde la metanocin o desde la cadena que queremos reconocer. Esto sera:
a) Parsing descendente, si comenzamos por la metanocin.
a) Parsing ascendente, si comenzamos por la palabra a reconocer.
45
ascendente
descendente
Herramienta
YACC
TP
(terica)
precedencia
LL(K)
LR(K)
EDT, AP
(tericas)
simple operador
SLR
LR cannico
LALR
46
aceptado por una de las dos cosas puede serlo por ambas. Los ejemplos los
veremos con este tipo de reconocimiento.
Con esta definicin, la configuracin final ser: (qf, , ), qf F
Ejemplo.- un palndromo.
L = { t c tr / t=(a | b)+}
T = {a, b, c}
Por ejemplo, si t = ab, entonces tr = ba.
Elementos vlidos del lenguaje seran: abcba, abbcbba, ababcbaba, etc
1
2
3
4
5
6
7
8
(a,,a)
(a,z0,az0)
0
(c,,)
(b,z0,bz0)
(b,,b)
f
($,z0,)
(b,b,)
Ejemplo.L = {t tr / t = (a | b)+}
T={a,b}
1
2
3
4
5
6
7
48
8
9
(q2, b, b) = (q2, )
(q2, $, z0) = (qf, )
(a,a,)
(a,a,)
1
(b,z0,bz0)
2
(b,b,)
(b,b,bb)(b,a,ba)
f
($,z0,)
(b,b,)
(q, (, () = (q, )
(q, ), )) = (q, )
(q, +, +) = (q, )
(q, *, *) = (q, )
(q, a+a*b, S) (q, a+a*b, S+T) (q, a+a*b, T+T) (q, a+a*b, F+T)
(q, a+a*b, a+T) (q, +a*b, +T) (q, a*b, T) (q, a*b, T*F)
(q, a*b, F*F) (q, a*b, a*F) (q, *b, *F), (q, b, F) (q, b, b) (q, , )
Esta es una mquina terica, con este tipo de mquinas nunca podremos
resolver problemas como la ambigedad; en el tema siguiente hablaremos de
implementaciones de AP pero con restricciones para solucionar estos
problemas.
4.1.2 Esquemas de traduccin (EDT).
Con este tipo de mquinas podemos definir un anlisis sintctico descendente.
Un esquema de traduccin es una mquina terica que podemos definir de la
siguiente forma:
EDT = (N, Te, Ts, R, S)
N son los no terminales.
Te es el alfabeto de entrada.
Ts es el alfabeto de salida.
S es el axioma.
R son las reglas de la produccin de la forma:
A , con: (N U Te)*, (N U Ts)* y adems N (Ts U Te) =
Lo que hace esta mquina es traducir una tira de caracteres a otro lenguaje,
el esquema podra ser el siguiente:
Ge
Le
EDT
Ls
Gs
50
Reglas de R:
S (S), S
S a, a
S b, b
S S*S, SS*
S S/S, SS/
(q,
(q,
(q,
(q,
(q,
(q,
(q,
, S+T) = (q, S, 1)
, T) = (q, S, 2)
, T*F) = (q, T, 3)
, F) = (q, T, 4)
, (S)) = (q, F, 5)
, a) = (q, F, 6)
, b) = (q, F, 7)
PILA
z0
z0 a
z0 F
z0 T
z0T*
z0T*(
z0T*(a
z0T*(F
...
z0 S
z0
SALIDA
6
64
64
64
64
646
...
64642741532
64642741532
53
0
0
1
1
1
1
0
0
1
1
2
0
0
0
1
3
0
0
0
0
...
S = { (x,y) / x = y } x, y N
Es de equivalencia
x\y
0
1
2
3
...
0
1
0
0
0
1
0
1
0
0
2
0
0
1
0
3
0
0
0
1
...
(OR)
(AND)
R + S = Mij OR Mkp
R x S = Mij AND Mkp
R . S = { (x, y) / z (x R z) (z S y) } denominado producto relativo.
A la hora de realizar la tabla de relaciones de la gramtica se puede hacer a
mano, haciendo todas las posibles derivaciones a partir del axioma de la
54
S
a
A
c
S
a
b
A
B
A
B
A
c
Las relaciones que podemos obtener son las siguientes:
bB
ab
Ba
b<c
Ac
Etc...
Si estn en la misma regla la relacin es , si estn en el nivel superior por la
izquierda y si estn en el nivel superior por la derecha o cualquiera que
cuelgue de ste .
Finalmente, la tabla sera:
55
S
S
a
A
B
c
b
d
PIVOTE
c
Acd
bB
aAa
REDUCCIN
Ac
B Acd
A bB
S aAa
XITO, ACEPTADA
x < y si y slo si A xB P y B + y
x y si y slo si A xy P
x > y si y slo si A CD con C + x y D * y
S
A
y
c > B, c > D, c > d
El ejemplo anterior creemos que har comprender la diferencia entre < y >.
56
A B C D a b c
1 1 0 1 0 0 0
0 1 0 1 0 0 0
0 0 0 0 0 0 1
0 1 0 1 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
Si una vez calculada la matriz PRIMERO la multiplicamos por sigo misma (con
AND, es decir 1+1=1, el denominado producto relativo) tantas veces como
haga falta hasta que no aparezcan ms unos (los que vayan apareciendo los
aadiremos), llegaremos a obtener PRIMERO+.
Algoritmo de Warshall
Nos permite hallar A+ a partir de A; A+ = Ui>0 Ai a partir de la relacin R en
forma de una matriz.
B=A
I=1
REPEAT
IF B(I, J) = 1 THEN
FOR K = 1 TO N DO
IF A(J, K) = 1 THEN A(I, K) = 1
UNTIL para todos los valores de J
57
I=I+1
IF I N THEN GOTO 3 ELSE STOP
Clculo de las matrices (), (<) y (>)
() se calcula por la propia definicin.
(<) = () (PRIMERO+)
(>) = (ULTIMO+)T () (I + PRIMERO+) , donde I es la matriz identidad.
Ejemplo 1.- Calcular las relaciones de precedencia simple para la gramtica:
S aSB |
Bb
Tenemos que eliminar la regla , de forma que la gramtica nos quedara:
S S |
S aSB | aB
Bb
La regla S S | podemos no tenerla en cuenta (y por lo tanto tampoco el
smbolo S), si bien al implementarlo contemplaramos la "sentencia vaca"
como parte del lenguaje. Se indican en negrita y con un asterisco los 1s que
seran 0s si no eliminramos la regla existente en la gramtica.
Vamos a calcular las matrices () y PRIMERO:
S
B
a
b
S B a b
0 1 0 0
0 0 0 0
1 1* 0 0
0 0 0 0
PRIMERO
S
B
a
b
S B a b
0 0 1 0
0 0 0 1
0 0 0 0
0 0 0 0
ULTIMO
S
B
a
b
S B a b
0 1 0 0
0 0 0 1
0 0 0 0
0 0 0 0
Por lo tanto:
0
0
1
0
() =
1
0
1*
0
0
0
0
0
0
0
0
0
0
0
0
0
PRIMERO =
0
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
58
1
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
1
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
1
0
0
ULTIMO+ =
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
(<) =
0
0
1
0
(ULTIMO+)T () =
()
(>) =
0
0
0
0
()
1 0
0 0
1* 0
0 0
0
1
0
1
()
0 0
1 0
0 0
1 0
(PRIMERO+)
0 0 1 0
0 0 0 1
0 0 0 0
0 0 0 0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
1*
0
(I+PRIMERO+)
1 0 1 0
0 1 0 1
0 0 1 0
0 0 0 1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
1
0
1
1
0
1*
0
0
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
59
B a b
<
>
>
* < <*
>
>
S
B
a
b
Si en esta tabla eliminamos los smbolos * y <* (que sera la tabla resultante
si no eliminramos la regla ) no podramos resolver elementos del lenguaje
como podra ser "aabb"; al mirar las precedencias no seramos capaces de
encontrar un pivote y no aceptaramos una palabra que s es del lenguaje. En
cambio con la tabla tal cual aparece podemos reconocer todo el lenguaje
excepto el elemento "cadena vaca", que habra que tratarlo y reconocerlo
especficamente (algo, por otro lado, muy sencillo).
Ejercicio 2.S AB
BA
Aa
S A B a
S 0 0 0 0
A 0 0 1 0
B 0 0 0 0
a 0 0 0 0
PRIMERO S A B a
S
0 1 0 0
A
0 0 0 1
B
0 1 0 0
a
0 0 0 0
ULTIMO S A B a
S
0 0 1 0
A
0 0 0 1
B
0 1 0 0
a
0 0 0 0
Por lo tanto:
0
0
0
0
() =
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
PRIMERO =
1
0
1
0
0
0
0
0
0
1
0
0
1
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
1
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
60
0
0
0
0
0
0
1
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
1
0
0
0
1
0
1
0
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
PRIMERO =
0
0
0
0
1
0
1
0
0
0
0
0
1
1
1
0
ULTIMO =
0
0
0
0
1
0
1
0
0
0
0
0
0
1
0
0
1
0
0
0
1
1
1
0
(<) =
0
0
0
0
()
0 0
0 1
0 0
0 0
0
1
1
1
+ T
(ULTIMO ) () =
(*)
0
0
0
0
0
0
0
1
0
1
0
1
(*)
(>) =
0
0
0
0
0
0
0
0
0
0
0
1
(PRIMERO+)
0 1 0 1
0 0 0 1
0 1 0 1
0 0 0 0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
(I+PRIMERO+)
1 1 0 1
0 1 0 1
0 1 1 1
0 0 0 1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
1
0
0
0
1
0
0
0
0
0
0
0
1
61
S
S
A
B
a
<
<
>
>
>
Ejercicio 3.S CC
C cC
Cd
S C c d
S 0 0 0 0
C 0 1 0 0
c 0 1 0 0
d 0 0 0 0
PRIMERO S C c d
S
0 1 0 0
C
0 0 1 1
c
0 0 0 0
d
0 0 0 0
ULTIMO S C c d
S
0 1 0 0
C
0 1 0 1
c
0 0 0 0
d
0 0 0 0
Por lo tanto:
0
0
0
0
() =
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
PRIMERO =
1
0
0
0
0
1
0
0
0
1
0
0
1
0
0
0
0
1
0
0
0
1
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0
1
0
0
0
0
0
0
0
0
0
0
1
0
0
0
1
0
0
0
1
0
0
0
0
1
0
0
0
1
0
0
0
0
0
0
0
0
0
0
1
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
1
0
0
1
1
0
0
0
0
0
0
0
1
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
1
0
0
62
0
0
0
0
1
1
0
0
0
0
0
0
0
1
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
1
0
0
PRIMERO =
0
0
0
0
1
0
0
0
1
1
0
0
1
1
0
0
ULTIMO =
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
(<) =
0
0
0
0
()
0 0
1 0
1 0
0 0
0
1
0
1
+ T
(ULTIMO ) () =
(*)
(PRIMERO+)
0 1 1 1
0 0 1 1
0 0 0 0
0 0 0 0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
1
1
0
(I+PRIMERO+)
1 1 1 1
0 1 1 1
0 0 1 0
0 0 0 1
(*)
(>) =
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
1
0
1
0
1
1
0
0
1
0
1
0
1
0
1
0
0
0
0
0
0
0
0
0
1
0
1
C
>
>
c
>
<
<
>
d
>
<
<
>
63
64
id
id
+
*
$
+
>
>
>
<
<
<
<
*
>
<
>
<
$
>
>
>
PIVOTE
id
id
id
S*S
S+S
REDUCCIN
S id
S id
S id
S S*S
S S+S
XITO, ACEPTADA
+
>
>
>
>
>
>
>
>
*
<
<
>
>
/
<
<
>
>
<
<
<
<
id
<
<
<
<
(
<
<
<
<
)
>
>
>
>
$
>
>
>
>
65
>
>
<
>
<
id
(
)
$
>
>
<
>
<
>
>
<
>
<
>
>
<
>
<
<
>
<
>
<
<
<
<
<
<
>
>
>
>
>
>
<
Funciones de precedencia
Normalmente no se almacena la tabla de precedencias de operador sino que
se definen unas funciones de precedencia. Utilizando estas funciones
ahorramos memoria pues no es preciso almacenar la tabla. El mtodo se basa
en implementar dos funciones f y g que transformarn smbolos terminales en
enteros que compararemos para mirar su prioridad. Esto es:
a, b T
f(a) < g(b) sii a < b
f(a) > g(b) sii a b
f(a) > g(b) sii a > b
Para la tabla del ejercicio 2, las funciones f y g seran las siguientes:
+
2
1
f
g
2
1
*
4
3
/
4
3
4
5
id
6
5
(
0
5
)
6
0
$
0
0
y
y
y
y
y
y
g(id) = 5
g(+) = 1
g(id) = 5
g(*) = 3
g(id) = 5
g($) = 0
entonces
entonces
entonces
entonces
entonces
entonces
$ < id
id < +
+ < id
id > *
* < id
id > $
Con lo cual:
$<id>+<id>*<id>$
Reduciramos <id> con la regla S id y continuaramos el proceso.
Algoritmo para la construccin de las funciones de precedencia
1. Partimos de la matriz de precedencia.
2. Creamos para un grafo los nodos fa y ga a T incluyendo $.
3. Si tienen igual precedencia los agrupamos.
66
id
4
5
+
2
1
*
4
3
$
0
0
gid
fid
f*
g*
g+
f+
f$
g$
67
Tira de entrada
Programa de
anlisis
Resultado
Pila
E TE
E TE
E +TE
T FT
T FT
T
F id
T *FT
F (E)
PILA
$E
$ET
$ETF
$ETid
$ET
$E
$ET+
$ET
$ETF
$ETid
$ET
$ETF*
$ETF
$ETid
$ET
$E
$
$
ENTRADA
id+id*id$
id+id*id$
id+id*id$
id+id*id$
+id*id$
+id*id$
+id*id$
id*id$
id*id$
id*id$
*id$
*id$
id$
id$
$
$
$
$
Reduccin
E TE
T FT
F id
T
E +TE
T FT
F id
T *FT
F id
T
E
XITO
T FT
T *FT |
F (E) | id
Si calculamos PRIMERO y SIGUIENTE quedara:
E
E
T
T
F
PRIMERO
(, id
+,
(, id
*,
(, id
SIGUIENTE
), $
), $
+, ), $
+, ), $
*, +, ), $
70
Id
E
E
T
T
F
E TE
E TE
E +TE
T FT
T FT
T
T *FT
F id
F (E)
Con la regla E TE
En este caso PRIMERO (TE) = PRIMERO(T) porque no est incluido en este
ltimo. Utilizando la regla (2), {(, id} PRIMERO(T), entonces hemos aadido
E TE en M[E, (] y M[E, id}
Con la regla E +TE
Tambin tenemos que PRIMERO(+TE) = PRIMERO(+) = {+}, entonces, tambin
con la regla (2), en M[E, +] introducimos E +TE.
Con la regla E
Como PRIMERO() = y SIGUIENTE(E) = {), $}, entonces introducimos E
en M[E, )] y M[E, $], aplicando la regla (3).
Y as continuaramos con el resto de las reglas.
Condiciones a cumplir para que una gramtica sea LL(1):
1) Ninguna gramtica ambigua o recursiva por la izquierda puede ser LL(1).
2) Puede demostrarse que una gramtica G es de tipo LL(1) si, y slo si,
cuando A | sean dos producciones distintas de G se cumplan las
siguientes condiciones:
3) Para ningn terminal a tanto como derivan a la vez cadenas que
comiencen con a.
4) A lo sumo una de y pude derivar la cadena vaca.
5) Si * , no deriva ninguna cadena que comience con un terminal en
SIGUIENTE(A).
Ejemplo.- Implemntese un analizador LL(1) de la gramtica:
EE+T|ET|T
TT*F|T/F|F
F id | id [ E ] | ( E )
Ejemplo.- Sea la gramtica:
S{A}
A id = E
E id
Implementar un analizador LL(1).
Ejemplo.71
SS;L
SL
L if expr then S else S fi
L if expr then S fi
L instr
No es LL(1), hay que transformarlo eliminando recursividad por la izquierda y
factorizacin en:
S L S
S ; L S |
L if expr then S X fi
L instr
X else S |
Primero calculamos los conjuntos PRIMERO y SIGUIENTE:
PRIMERO
if expr then, instr
if expr then, instr
;,
, else
S
L
S
X
SIGUIENTE
$, else, fi
;, $, else, fi
$, else, fi
fi,
if expr then
S L S
L if expr then S X
fi
S ; LS
fi
S
X
instr
S L S
L instr
else
S
S
X else S
Reconozcamos if expr then if expr then instr fi else if expr then instr fi fi$:
PILA
ENTRADA
SALIDA
if expr then if expr then instr fi else if
$S
$SL
$Sfi X S then expr if
$S fi X S
$S fi XSL
$S fi XSfi X S then expr if
$S fi XSfi X S
$ S fi X Sfi X S L
$ S fi X Sfi X S instr
$ S fi X Sfi X S
S L S
L instr
72
$ S fi X Sfi X
$ S fi X Sfi
$ S fi X S
$ S fi X
$ S fi S else
$ S fi S
$ S fi S L
$ S fi S fi X S then expr if
$ S fi S fi
$ S fi S fi
$ S fi S fi
$ S fi S fi
$ S fi S fi
$ S fi S fi
$ S fi S
$ S fi
$ S
$
$
instr fi fi$
instr fi fi$
instr fi fi$
fi fi$
fi fi$
fi fi$
fi$
fi$
$
$
$
XS
X SL
X S instr
X S
X
S
X
S
X else S
S L S
L if expr
then S X fi
S L S
L instr
S
X
S
S
XITO
73
Tira de entrada
Sm
Xm
Sm-1
Xm-1
...
Pila
Programa de
anlisis
accin
Resultado
ir_a
La tabla de "accin" nos dir lo que hacer con cada entrada y la tabla "ir_a"
nos indicar las transiciones entre estados. El funcionamiento es:
1) Tomamos Sm de la pila y ai de la tira de entrada.
2) Miramos en accion[Sm, ai] que nos indicar una de las siguientes acciones:
a) Desplazar Sp (Sp es un estado).
b) Reducir A . Miramos ir_a[Sm-r, A] y obtendremos un nuevo estado
al que transitar Sq (r es la longitud de ).
c) Aceptar.
d) Error.
Llamamos configuracin a un par formado por el estado de la pila y la tira de
entrada que estamos analizando.
Supongamos una configuracin inicial: (S0X1S1X2S2 ... XmSm, aiai+1... an$).
Respecto a la notacin, los Si son estados y los Xi son smbolos gramaticales
(terminales y no terminales).
Vamos a ver las diferentes posibilidades:
a) Si tenemos que la accion[Sk, ai] = desplazar Sp, entonces la configuracin
variara de la siguiente forma:
(S0X1S1X2S2 ... XmSmaiSp, ai+1... an$)
b) Sin embargo, si ocurriera que accion[Sk, ai] = reducir A , la
configuracin quedara como:
(S0X1S1X2S2 ... Xm-rSm-rASq, aiai+1... an$)
En donde Sq = ir_a[Sm-r,A] y r es la longitud de .
c) Si accion[Sk, ai] = aceptar entonces significa el fin del anlisis sintctico.
74
(2) E T
(6) F id
(3) T T*F
(4) T F
id
d5
+
d6
r2
r4
(
d4
d7
r4
d5
r2
r4
ACEP.
r2
r4
d4
r6
r6
d5
d5
r6
d7
r3
r3
ACCIN
d11
r1
r3
r5
T
2
F
3
3
10
r6
d4
d4
d6
r1
r3
r3
E
1
r1
r3
r5
IR_A
ENTRADA
id*id+id$
*id+id$
*id+id$
*id+id$
id+id$
+id$
+id$
+id$
+id$
id$
$
$
$
$
Accin
d5
r6 (F id)
r4 (T F)
d7
d5
r6 (F id)
r3 (T T*F)
r2 (E T)
d6
d5
r6 (F id)
r4 (T F)
r1 (E E+T)
ACEPTAR
75
.XYZ
X.YZ
XY.Z
XYZ.
(0) E E
(4) T F
(1) E E+T
(5) F (E)
(2) E T
(6) F id
(3) T T*F
E .E
E .E+T
E .T
T .T*F
T .F
F .(E)
F .id
(1)
(1)
(3)
(3)
(5)
(5)
77
(1) E E+T
(5) F (E)
(2) E T
(6) F id
(3) T T*F
T .T*F
F .id
T .F
F .(E)
I2 = Ir_a(I0, T) =
E T.
T T.*F
T F.
E (.E)
E .E+T
E .T
T .T*F
T .F
F .(E)
F .id
T T*.F
F .(E)
F .id
I8 = Ir_a(I4, E) =
F (E.)
E E.+T
Ir_a(I4, T) = I2
78
Ir_a(I4, F) = I3
Ir_a(I4, () = I4
Ir_a(I4, id) = I5
I9 = Ir_a(I6, T) =
E E+T.
T T.*F
I10 = Ir_a(I7, F) =
T T*F.
Ir_a(I7, () = I4
Ir_a(I7, id) = I5
I11 = Ir_a(I8, )) =
F (E).
Ir_a(I8, +) = I6
I0
I1
I6
I9
I7
F
I3
(
T
id
I4
I5
I2
I7
I10
(
id
I4
I5
I3
)
I4
I8
T
id
F
I5
I11
+
I2
I6
I3
79
iii)
iv)
(1) E E+T
(5) F (E)
(2) E T
(6) F id
(3) T T*F
Veremos como con los terminales hallamos la tabla de accin y con los no
terminales la IR_A:
I0 =
E .E
E .E+T
E .T
T .T*F
T .F
F .(E)
F .id
Adems, como:
Ir_a(I0 ,E) = I1 IR_A[0, E] = 1
Ir_a(I0 ,T) = I2 IR_A[0, T] = 2
Ir_a(I0 ,F) = I3 IR_A[0, F] = 3
E E. I1 accion[1, $] = ACEPTAR
E E.+T I1, Ir_a(I1, +) = I6 accion[1, +] = d6
80
id
d5
+
d6
r2
r4
(
d4
d7
r4
d5
r2
r4
ACEP.
r2
r4
d4
r6
r6
d5
d5
r6
d7
r3
r5
ACCIN
d11
r1
r3
r5
T
2
F
3
3
10
r6
d4
d4
d6
r1
r3
r5
E
1
r1
r3
r5
IR_A
(0) S S
(4) L *E
(2) S E
(3) E L
PRIMERO
*, id
*, id
SIGUIENTE
$
=, $
81
*, id
=, $
I1 = Ir_a(I0, S) =
S S.
S .S
S .L=E
S .E
L .*E
E .L
L .id
S L.=E
E L.
desplazar con =
reducir EL con =
porque = SIG(E)
S E.
I4 = Ir_a(I0, *) =
L *.E
E .L
L .*E
L .id
I5 = Ir_a(I0, id) =
L id.
I6 = Ir_a(I2, =) =
S L=.E
E .L
L .*E
L .id
I7 = Ir_a(I4, E) =
L *E.
I8 = Ir_a(I4, L) =
E L.
Ir_a(I4, *) = I4
Ir_a(I4, id) = I5
I9 = Ir_a(I6, E) =
S L=E.
Ir_a(I6, L) = I8
Ir_a(I6, *) = I4
82
Ir_a(I6, id) = I5
La tabla nos quedara:
ESTADO
0
1
2
3
4
5
6
7
8
9
id
d5
*
d4
d4
r5
d5
S
1
L
2
E
3
ACEP.
r3
r2
d6/r3
d5
r5
d4
r4
r3
ACCIN
r4
r3
r1
IR_A
84
S CC
C cC | d
Calcular los elementos de anlisis por el mtodo LR-cannico.
Primero creamos la gramtica extendida:
S S
S CC
C cC | d
I0 = {cerradura({[S .S, $]})} = 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, $
C
C
C
C
C
C
c.C, c
c.C, d
.cC, c
.cC, d
.d, c
.d, d
85
S .S, $
S .CC, $
C .cC, c|d
C .d, c|d
I0
S S., $
I1
S CC., $
I5
C
c
S C.C, $
C .cC, $
C .d, $
I2
d
c
C d., c|d
I4
C c.C, c|d
C .cC, c|d
C .d, c|d
I3
C c.C, $
C .cC, $
C .d, $
I6
C cC., $
I9
C d., $
I7
C
C cC., c|d
I8
c
d36
D
d47
d36
d36
r3
d47
d47
r3
r2
r2
ACCIN
S
1
C
2
ACEP.
5
89
r3
r1
r2
IR_A
87
S S
S aAd | bBd | aBe | bAe
Ac
Bc
I0 = {cerradura({[S .S, $]})} = S .S, $
S .aAd, $
S .bBd, $
S .aBe, $
S .bAe, $
Ir_a(I0 ,S) = cerradura([S S., $]) =
S S. , $
= I1
S a.Ad, $ = I2
S a.Be, $
A .c, d
B .c, e
S b.Bd, $ = I3
S b.Ae, $
A .c, e
B .c, d
= I6
,d) =
,e) =
,e) =
,d) =
S
S
S
S
aAd., $
aBe., $
bAe., $
bBd., $
= I9
= I10
= I11
= I12
= I13
:
|
<alt 1>
<alt 2>
{ accin semntica 1}
{ accin semntica 2}
89
...
|
;
<alt n>
{ accin semntica n
expr \n
{ printf(%d\n, $1); }
expr
:
|
;
expr + termino
termino
{ $$ = $1 + $3; }
termino
:
|
;
termino * factor
factor
{$$ = $1 * $3; }
factor
:
|
;
(expr )
CIFRA
{ $$ = $2; }
%%
yylex() {
90
int c;
c = getchar();
if (isdigit(c)) {
yylval = c-0;
return CIFRA;
}
return c;
}
91