Ejemplo de gramática (expresiones aritméticas): E := T + E | T

Anuncio
Ejemplo de gramática (expresiones aritméticas):
E := T + E | T - E | T
T := F * T | F / T | F
F ::= i | (E)
FNG:
E ::= iPTME | (ECPTME | iDTME | (ECDTME | iME | (ECME |
iPTSE | (ECPTSE | iDTSE | (ECDTSE | iSE | (ECSE |
iPT | (ECPT | iDT | (ECDT | i | (EC
T ::= iPT | (ECPT | iDT | (ECDT | i | (EC
F ::= i | (EC
M ::= +
S ::= P ::= *
D ::= /
C ::= )
En forma LL(1) queda:
E ::= iV | (ECV
V ::= *TX | /TX | +E | -E | λ
X ::= +E | -E | λ
T ::= iU | (ECU
U ::= *T | /T | λ
F ::= i | (EC
C ::= )
1
Paso automático de la gramática LL(1) al analizador:
caso a) Reglas SIN λ
gramática LL(1), U ::= x X1 X2 ... Xn | y Y1 Y2 ... Ym | ... | z Z1 Z2 ... Zp
caso b) Reglas CON λ
U ::= x X1 X2 ... Xn | ... | z Z1 Z2 ... Zp | λ
int U (char *cadena, int i)
{
if (i<0) return i; /* Pasa errores anteriores */
switch (cadena[i]) {
case x:
i++;
...
i = X1 (cadena, i);
case z:
i = X2 (cadena, i);
i++;
...
i = Z1 (cadena, i);
i = Xn (cadena, i);
i = Z2 (cadena, i);
break;
...
case y:
i = Zp (cadena, i);
i++;
break;
i = Y1 (cadena, i);
/* Fin de cadena va a default */
i = Y2 (cadena, i);
default: return -n; /* Genera error n */
...
}
i = Ym (cadena, i);
return i;
break;
}
...
2
int U (char *cadena, int i)
{
if (i<0) return i; /* Pasa errores anteriores */
switch (cadena[i]) {
case x:
i++;
i = X1 (cadena, i);
i = X2 (cadena, i);
...
i = Xn (cadena, i);
break;
...
case z:
i++;
i = Z1 (cadena, i);
i = Z2 (cadena, i);
...
i = Zp (cadena, i);
break;
}
return i;
}
int E (char *cadena, int i)
{
if (i<0) return i;
switch (cadena[i]) {
case 'i':
i++;
i = V (cadena, i);
break;
case '(':
i++;
i = E (cadena, i);
i = C (cadena, i);
i = V (cadena, i);
break;
default: return -1;
}
return i;
}
int V (char *cadena, int i)
{
if (i<0) return i;
switch (cadena[i]) {
case '*':
case '/':
i++;
i = T (cadena, i);
i = X (cadena, i);
break;
case '+':
case '-':
i++;
i = E (cadena, i);
break;
}
return i;
}
3
int X (char *cadena, int i)
{
if (i<0) return i;
switch (cadena[i]) {
case '+':
case '-':
i++;
i = E (cadena, i);
break;
}
return i;
}
int U (char *cadena, int i)
{
if (i<0) return i;
switch (cadena[i]) {
case '*':
case '/':
i++;
i = T (cadena, i);
break;
}
return i;
}
int T (char *cadena, int i)
{
if (i<0) return i;
switch (cadena[i]) {
case 'i':
i++;
i = U (cadena, i);
break;
case '(':
i++;
i = E (cadena, i);
i = C (cadena, i);
i = U (cadena, i);
break;
default: return -2;
}
return i;
}
int F (char *cadena, int i)
{
if (i<0) return i;
switch (cadena[i]) {
case 'i':
i++;
break;
case '(':
i++;
i = E (cadena, i);
i = C (cadena, i);
break;
default: return -3;
}
return i;
}
4
int C (char *cadena, int i)
{
if (i<0) return i;
switch (cadena[i]) {
case ')':
i++;
break;
default: return -4;
}
return i;
}
Análisis: La cadena x se analiza invocando axioma (x, 0)
En nuestro ejemplo: E (x, 0)
Si devuelve strlen(x), la cadena x es correcta. En caso contrario,
devolverá un número negativo que indica el error detectado.
Ejemplo: análisis de "i+i*i".
E ("i+i*i", 0) = V ("i+i*i", 1) =
= E ("i+i*i", 2) =
= V ("i+i*i", 3) =
= X ("i+i*i", T ("i+i*i", 4)) =
= X ("i+i*i", U ("i+i*i", 5)) =
= X ("i+i*i", 5) =
=5
5
Ejemplo: análisis de "i+i*".
E ("i+i*", 0) = V ("i+i*", 1) =
= E ("i+i*", 2) =
= V ("i+i*", 3) =
= X ("i+i*", T ("i+i*", 4)) =
= -2
6
Descargar