expr | expr `+` expr - Universidad de Zaragoza

Anuncio
Lección 3: Análisis Semántico
1.
2.
3.
4.
5.
Expresiones y Asignación
Estructuras de Control
Procesamiento de Declaraciones
Procedimientos y Funciones
Perspectiva
Lecturas:
Cooper, capítulo 4
Scott, capítulo 4
Aho, capítulo 8
Fischer, capítulos 10, 11 , 12 , 13, 14
Holub, capítulo 6
Bennett, capítulo 4, 10
12048 - J. Neira – Universidad de Zaragoza
1
1. Expresiones y Asignación
¿ 5+2*4 ?
¿ 5-2-4 ?
¿ a = b = c (en C)?
¿ a ** b ** c (en ADA)?
¿ a < b < c (en C)?
¿ a > 0 and b > 0 (en PASCAL)?
12048 - J. Neira – Universidad de Zaragoza
2
Operadores
• Precedencia: prioridad de
los operadores; determina
qué operadores obtienen
sus operandos primero
+
5 + 5 * 6 / 10
• Se altera con paréntesis
((5 + 5) * 6) / 10
/
or
Men encia
ed
prec
10
*
5
/
6
+
equivalente a:
5 + ((5 * 6 )/ 10)
*
M
prec ayor
ede
ncia
10
5
Mayor
precedencia
ADA:
5
6
logical_operator
::=
relational_operator
::=
binary_adding_operator
::=
unary_adding_operator
::=
multiplying_operator
::=
highest_precedence_operator ::=
12048 - J. Neira – Universidad de Zaragoza
5
and | or | xor
= | /= | < | <= | > | >=
+ | - | &
+ | * | / | mod | rem
** | abs | not
3
Operadores
• Asociatividad: determina
el orden de evaluación de
operadores de igual precedencia
• De izquierda a derecha:
x + 3 - y + 5
(x + 3) - y + 5
((x + 3) - y) + 5
(((x + 3) - y) + 5)
• De derecha a izquierda
x = y += z -= 4
x = y += (z -= 4)
x = (y += (z -= 4))
(x = y += (z -= 4))
=
x
+=
y
-=
+
5
-
3
12048 - J. Neira – Universidad de Zaragoza
4
• Algunos NO son
asociativos: ADA:
y
+
x
z
A**B**C
(A**B)**C
A**(B**C)
4
Operadores
Operator Name
=
i
&&
i = f() && g();
f()
g()
• En algunos casos NO está
definido
1
1
0
,
0
1
++
1
[]
1
1
i
1
i
x
1
12048 - J. Neira – Universidad de Zaragoza
func2(++i, x[i]);
¿?
Mayor precedencia
• Orden de evaluación: determina qué operandos se
evalúan primero
x
x
!
!
x
c
c
c
5
x
C:
Associativity Operators
Primary
Unary
left to right
right to left
Multiplicative
left to right
*
/
Additive
left to right
+
-
Bitwise Shift
left to right
<<
Relational
left to right
<
()
++
[ ] . ->
-- + %
>>
>
Equality
left to right
==
Bitwise AND
left to right
&
Bitwise Exclusive OR
left to right
^
Bitwise Inclusive OR
left to right
|
Logical AND
left to right
&&
Logical OR
left to right
||
Conditional
right to left
? :
Assignment
right to left
=
Comma
left to right
,
<=
>=
!=
+=
-=
*=
/=
<<=
>>=
int x = 11;
int y = 6;
> 9 && y != 3 int z = 1;
==
5 || y != 3 char c = 'k';
• Ejercicio:
char d = 'y';
x > 14
(x > 9 && y != 23)
<= 1 && y == 6 || z < 4
>= 'a' && c <= 'z'
>= 'A' || c <= 'Z'
!= d && c != '\n'
&& y != 8 || 0
>= y >= z
5
(
http://libre.act-europe.fr/Software_Matters
12048 - J. Neira – Universidad de Zaragoza
6
¿es correcto este programa?
/* Si *y es cero, x > 0, asignar a *k el mayor entero.
* Si *y es cero, x <= 0, no cambiar *k.
* Si *y no es cero, asignar a *k x dividido por *y e incrementar *y en 1.
*/
#include <limits.h>
void check_divide (int *k, int x, int *y)
if (*y = 0)
if (x > 0)
*k = INT_MAX;
else
*k = x / *y;
*y++;
}
12048 - J. Neira – Universidad de Zaragoza
{
7
= .vs. ==
• La elección de “=“ para la asignación, y de “==“
para la igualdad fue muy desacertada.
• No todos los compiladores advierten del uso de ‘=‘
en condiciones.
• Es difícil, C++ fomenta su uso:
while
(*s1++ = *s2++);
• Precedencia del ++ mal definida: *y++ equivale a
*(y++)
12048 - J. Neira – Universidad de Zaragoza
8
La versión correcta sería:
#include <limits.h>
void check_divide (int *k, int x, int *y)
if (*y == 0) {
if ( x > 0)
*k = INT_MAX;
}
else {
*k = x / *y;
(*y)++;
}
}
12048 - J. Neira – Universidad de Zaragoza
{
9
Precedencia y asociatividad
if (x & mask == 0)
• NO equivale a: if ((x & mask) == 0)
if (x & (mask == 0) )
if (x < y < z)
• NO equivale a: if ((x < y) && (y < z))
if (((x < y) && (1 < z)) || (0 < z))
• hi << 4 + low?
• x == y == z?
12048 - J. Neira – Universidad de Zaragoza
10
Legibilidad
int x;
int y;
int z;
…
x = y---z--;
12048 - J. Neira – Universidad de Zaragoza
11
Quiere decir:
x : integer;
y : integer;
z : integer;
x := y - z;
y := y - 1;
z := z - 1;
12048 - J. Neira – Universidad de Zaragoza
12
Comentario acerca de
x = y---z--;
• Un programador cuidadoso escribiria:
x = y-- - z--;
• Sigue siendo preferible:
x = y - z;
y--;
z--;
• Es más fácil de entender
12048 - J. Neira – Universidad de Zaragoza
13
)
http://libre.act-europe.fr/Software_Matters
12048 - J. Neira – Universidad de Zaragoza
14
Comprobación de expresiones con
YACC
expr
...
...
...
...
...
;
|
|
|
|
|
|
expr '+' expr
expr tAND expr
expr tMAY expr
'(' expr ')‘
tIDENTIFICADOR
tCONSTENTERA
• Se utilizan atributos sintetizados
• El atributo será el tipo de la
expresión
resultado
resultado
entero
entero
resultado
resultado
booleano
booleano
+
>
-51
24
-51
24
12048 - J. Neira – Universidad de Zaragoza
• La producción se valida a
partir de los atributos del
RHS ($n)
• El atributo del LHS ($$) se
genera a partir de los
atributos del RHS
15
Comprobación de expresiones con
YACC
• Constantes e identificadores:
%{
typedef enum {
DESCONOCIDO, ENTERO, BOOLEANO, CHAR, CADENA
} TIPO_VARIABLE;
%}
%union {
TIPO_VARIABLE tipo;
registro de atributos
SIMBOLO *simbolo;
}
%type <tipo> expresion
declaración de
%type <simbolo> tIDENTIFICADOR
atributo por símbolo
%%
expresion : ...
| tCONSTENTERA
{
$$ = ENTERO;
}
| tIDENTIFICADOR
{
atributo LHS
$$ = DESCONOCIDO;
sintetizado
if ($1 == NULL)
to
error_semantico(”identificador desconocido.”);
u
b
i
r
at HS ...
16
12048R- J. Neira – Universidad de Zaragoza
Comprobación de expresiones con
YACC
expresion : expresion ’+’ expresion
{
$$ = ENTERO;
if (($1 != ENTERO) && ($1 != DESCONOCIDO))
error_semantico(”Op 1 debe ser entero.");
else if (($3 != ENTERO) && ($3 != DESCONOCIDO))
error_semantico(”Op 2 debe ser entero.");
}
| expresion tAND expresion
...
| expresion ‘=‘ expresion
{
$$ = BOOLEANO;
if (($1 != DESCONOCIDO) && ($3 != DESCONOCIDO)
&& ($1 != $3))
error_semantico(”Ops deben ser iguales.");
...
}
;
12048 - J. Neira – Universidad de Zaragoza
17
YACC: comprobación de expresiones
• ¡Es ambigua!
2*3+4
2*3+4
(2*3)+4
2*(3+4)
2*(3+4)
(2*3)+4
shift tCONSTENTERA
2
reduce tCONSTENTERA -> expr expr
shift *
expr *
shift tCONSTENTERA
expr * 3
reduce tCONSTENTERA -> expr expr * expr
ó
ó
reduce expr * expr -> expr
expr
shift +
expr * expr +
• No se ha especificado la precedencia ni asociatividad de los operadores
12048 - J. Neira – Universidad de Zaragoza
18
Precedencia: solución implícita
• Se re-escribe la gramática para definirla implícitamente
expresion : expresion ’+’ expresion
| expresion ’-’ expresion
| mulexp
;
mulexp : mulexp ’*’ mulexp
| mulexp ’/’ mulexp
| primaria
;
primaria : ’-’ primaria
| ’(’ expresion ’)’
| tCONSTENTERA
;
mayor
precedencia
menor
12048 - J. Neira – Universidad de Zaragoza
precedencia
“alteración” de
la precedencia
19
Asociatividad: solución implícita
• Se re-escribe la gramática para definirla implícitamente
expresion : expresion ’+’ mulexp
| expresion ’-’ mulexp
| mulexp
;
mulexp :
|
|
;
primaria
primaria ’*’ mulexp
primaria ’/’ mulexp
primaria
: ’-’ primaria
| ’(’ expresion ’)’
| tCONSTENTERA
;
de derecha a izquierda
(¡normalmente es al revés!)
12048 - J. Neira – Universidad de Zaragoza
de izquierda
a derecha
20
Precedencia y Asociatividad:
solución explícita
• YACC permite definir ambas cosas explícitamente
• %left indica la asociatividad de
los operadores (también existe
%right).
• El orden de las declaraciones de%left ’+’ ’-’
Precedencia:
termina la precedencia de los
%left ’*’ ’/’
de menor
operadores.
a mayor
...
• A cada producción se le asocia la
%nonassoc UMINUS
precedencia del token más a la
%%
derecha.
expr : expr ’+’ expr
• Los conflictos shift/reduce se
...
resuelven utilizando la prece| expr tAND expr
dencia.
...
| ’(’ expr ’)’
expr ’+’ expr ’*’
| ’-’ expr %prec UMINUS
| tCONSTENTERA
¿preced(’*’) > preced(’+’)?
...
•si, shift ’*’
•no, reduce expr ’+’ expr -> expr
;
• Parser pequeño y eficiente.
12048 - J. Neira – Universidad de Zaragoza
21
Precedencia
2*3+4
2*3+4
• Si el * tuviese mayor prece- • Si el + tuviese mayor predencia que el +:
cedencia que el *:
Reading (2)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reading ('*')
Shifting ('*')
Reading (3)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reducing expr '*' expr ->
Reading ('+')
Shifting ('+')
Reading (4)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reducing expr '+' expr ->
expr
expr
expr
expr
expr
10
10
12048 - J. Neira – Universidad de Zaragoza
Reading (2)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reading ('*')
Shifting ('*‘)
Reading (3)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reading ('+')
Shifting ('+')
Reading (4)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reducing expr '+' expr ->
Reducing expr '*' expr ->
expr
expr
expr
expr
expr
14
14
22
Asociatividad
2-3+4
2-3+4
• Asociatividad por la
izquierda:
• Asociatividad por la
derecha:
Reading (2)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reading ('-')
Shifting ('-')
Reading (3)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reducing expr '-' expr ->
Reading ('+')
Shifting ('+')
Reading (4)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reducing expr '+' expr ->
Reading (2)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reading ('-')
Shifting ('-')
Reading (3)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reading ('+')
Shifting ('+‘)
Reading a (4)
Shifting (tCONSTENTERA)
Reducing tCONSTENTERA ->
Reducing expr '+' expr ->
Reducing expr '-' expr ->
expr
expr
expr
expr
expr
33
12048 - J. Neira – Universidad de Zaragoza
expr
expr
expr
expr
expr
-5
-5
23
Asignación
i := j + 42;
%union{
struct { char
*nombre;
SIMBOLO *simbolo;
} identificador;
}
%type <identificador> tIDENTIFICADOR
asignacion:
tIDENTIFICADOR
lex debe buscarlo en la tabla
{
if ($1.simbolo == NULL)
error_semantico ("id desconocido");
else if (($1.simbolo->tipo != VARIABLE) &&
($1.simbolo->tipo != PARAMETRO))
error_semantico ("id debe ser variable
o parametro.");
}
tOPAS expresion
{
if (($1 != DESCONOCIDO) && ($4 != DESCONOCIDO)&&
¿NULL? ($1.simbolo->variable != $4)) ¿$3?
error_semantico ("tipos incompatibles");
}
;
12048 - J. Neira – Universidad de Zaragoza
24
Mejor...
• $$ se refiere al atributo sinteti• Esto permite transmitir información entre acciones
zado, sólo en la última acción
de la producción.
• Acciones intermedias: $$ atributo
asociado con la acción.
asignacion:
%union{
tIDENTIFICADOR
...
{
int ok;
$<ok>$ = FALSE;
...
if ...
}
else $<ok>$ = TRUE;
}
tOPAS expresion
{
if ($<ok>2 &&
($1 != DESCONOCIDO) && ($4 != DESCONOCIDO)&&
($1.simbolo->variable != $4))
error_semantico ("tipos incompatibles");
$$ ...
}
; 12048 - J. Neira – Universidad de Zaragoza
25
Asignación a vectores
• Los atributos también pueden utilizarse para contar elementos.
%union{
int cantidad;
}
v := [10,-5,4,i,j+1]; %type <cantidad> lista_expresiones
entero v[10];
...
asignacion_vector:
tIDENTIFICADOR
{...}
tOPAS ’[’ lista_expresiones ’]’
{...
if ($1.simbolo->dimension < $5)
error_semantico ("cantidad incorrecta");
}
;
lista_expresiones :
expresion
{$$ = 1;}
|
lista_expresiones ’,’ expresion
{$$ = $1 + 1;}
12048 - J. Neira – Universidad de Zaragoza
26
2. Estructuras de control
• Sentencias: las acciones efectúan las comprobaciones
• No se sintetiza ningún atributo
seleccion: tSI expresion
{
if (($2 != BOOLEANO) && ($2 != DESCONOCIDO))
error_semantico(
"seleccion: condicion invalida.");
}
tENT
lista_instrucciones
resto_seleccion
tFSI
;
mientras_que: tMQ expresion
...
lista_instrucciones
tFMQ
;
12048 - J. Neira – Universidad de Zaragoza
27
Estructuras de Control
• Instrucciones tipo break y continue
%{
int bucle = 0;
%}
a := 10;
%%
...
continuar :
{
if (!bucle)
error_semantico(
"Solo dentro de bucles.");
}
;
mientras_que :
tMQ expresion
{
bucle = TRUE;
}
lista_instrucciones
{
bucle = FALSE;
}
tFMQ
¿Problemas?
¿Problemas? 28
; Zaragoza
J. Neira – Universidad de
mq a > 0
...
si a = 0
continuar
fsi
...
fmq
12048 -
Estructuras de Control
¡Puede haber
bucles anidados!
a := 10;
mq a > 0
...
mq b > 0
...
fmq
si a = 0
continuar
fsi
...
fmq
Mejor contar los bucles:
%{
int bucle = 0;
%}
%%
...
continuar :
{
if (bucle > 0)
;
else
error_semantico (
"Solo dentro de bucles.");
}
;
mientras_que:
tMQ expresion
{++bucle;}
lista_instrucciones
{--bucle;}
tFMQ
;
12048 - J. Neira – Universidad de Zaragoza
29
3. Declaración de Variables
• Declaraciones tipo C: El tipo está definido al procesar los identificadores.
%union{
int tipo;
int
i, j, k;
}
float x, y, z, w;
%type <tipo> tipo_variables
declaracion : tipo_variables identificadores ’;’
;
tipo_variables
: tENTERO
{ $$ = ENTERO;
}
| tCARACTER { $$ = CHAR;
}
| tBOOLEANO { $$ = BOOLEANO; }
;
identificadores
: tIDENTIFICADOR
{
if ($1.simbolo == NULL)
introducir_variable (tabsim, $1.nombre,
¿tipo?, ¿nivel?...);
else
error_semantico ("id duplicado.");
}
| identificadores ‘,’ tIDENTIFICADOR
{ ... }
12048 - J. Neira – Universidad de Zaragoza
30
Atributos heredados
declaracion : tipo_variables identificadores ’;’
;
tipo_variables
: tENTERO
{ $$ = ENTERO;
}
| tCARACTER { $$ = CHAR;
}
| tBOOLEANO { $$ = BOOLEANO; }
;
identificadores
: tIDENTIFICADOR
{
if ($1.simbolo == NULL)
introducir_variable (tabsim, $1.nombre,
$<tipo>0, ¿nivel?, ...);
else
error_semantico ("id duplicado.");
Atributo
Atributodel
delsímbolo
símboloalmacealmace}
nado
en
la
pila
antes
en la pila antesde
de
| identificadores nado
‘,’ tIDENTIFICADOR
identificadores
$0, $-1,...
identificadores
{ ... }
leer : tLEER ’(’ identificadores ’)’
OJO: ;
Ahora
Ahoraantes
antesde
deidentificadores
identificadores
aparece
aparecetambién
también‘(‘.
‘(‘.
12048 - J. Neira – Universidad de Zaragoza
31
Bloques
{%
int nivel;
%}
...
void abrir_bloque ()
{
nivel++;
...
}
void cerrar_bloque ()
{
...
nivel--;
}
declaracion_accion:
cabecera_accion ';'
declaracion_variables
declaracion_acciones
bloque_sentencias
{
...
cerrar_bloque();
}
;
cabecera_accion:
tACCION tIDENTIFICADOR
{
...
El bloque se abre después de procesar
abrir_bloque();
el identificador y antes de los parámetros }
parametros_formales
identificadores
;
: tIDENTIFICADOR
{
if (($1.simbolo == NULL) ||
($1.simbolo->nivel != nivel))
introducir_variable (tabsim, $1.nombre,
$<tipo>0, nivel, ...);
else
error_semantico ("id duplicado.");
}
12048 - J. Neira – Universidad de Zaragoza
32
Declaración de Variables
• Declaraciones tipo ADA: El tipo NO está definido al procesar los
%union{
identificadores.
LISTA lista;
I, J, K : Integer;
}
%type <lista> identificadores
X, Y, Z, W : Float;
declaracion
: identificadores ’:’ tipo_variables ’;’
G1
G1
{
declaracion_variables ($1, $3);
}
...
;
tipo_variables : ...
;
identificadores : tIDENTIFICADOR
{ $$ = crear_lista ($1); }
Es
necesario
Es necesario
usar
usarlistas
listasde
deids.
ids. | identificadores ’,’ tIDENTIFICADOR
{ $$ = anadir ($1, $3); }
12048 - J. Neira – Universidad de Zaragoza
33
Alternativa
• Modificación de la gramática
• ¡Cambia el orden de inserción!
%union{
int tipo;
1
2
3
G1
G1
}
%type <tipo> resto_declaracion
declaracion : tIDENTIFICADOR
resto_declaracion
G2
{...
G2
}
;
i, j, k : Integer;
3
2
1
G2
G2
resto_declaracion : ',' tIDENTIFICADOR
resto_declaracion
{
$$ = $3;...
}
Evita
| ':' tipo_variables
Evitaelelmanejo
manejode
de
listas
{
listasde
denombres.
nombres.
$$ = $2;
}
12048 - J. Neira – Universidad de Zaragoza
34
¿es relevante el orden en la
declaración?
• En Pascal, el orden NO es
relevante
var
var
• En C, ADA ¡el orden si
puede ser relevante!
i, j, k : integer;
x, y, z, w : real;
int a = pop(),
b = pop();
...
push(a-b);
w, y, z, x : real;
k, i, j : integer;
int b = pop(),
a = pop();
...
push(a-b);
• NO hay información
semántica en el orden de
declaración.
12048 - J. Neira – Universidad de Zaragoza
• SI hay información semántica en el orden de declaración (la secuencialidad de
los inicializadores).
35
Ventajas sintácticas
• C:
char*
i, j, k;
• ADA:
i, j, k : access character;
12048 - J. Neira – Universidad de Zaragoza
36
4. Procedimientos y Funciones
Declaraciones:
Almacenar la declaración en la tabla (incluyendo los parámetros).
procedure q (i : integer; var t : boolean);
var j : integer;
f : boolean;
procedure r (var j : integer);
var i : integer;
begin
q (i, t, 2);
r (j+1)
end
begin
q (j);
r (’a’)
end
Invocaciones:
Verificar que la cantidad, tipo y clase de los argumentos sea correcta.
12048 - J. Neira – Universidad de Zaragoza
37
Declaraciones
%union {....
struct {SIMBOLO *simbolo; char *nombre;}
LISTA *lista;
.....}
accion p(
%type <ident> tIDENTIFICADOR
val entero
%type <lista> parametros_formales
ref booleano
%%
val caracter
accion : tACCION tIDENTIFICADOR
{
$<simbolo>$ = NULL;
if (($2.simbolo == NULL) ||
($2.simbolo->nivel != nivel))
$<simbolo>$ = introducir_accion
(tabsim, $2.nombre,
....
}
parametros_formales
{
if ($<simbolo>3 != NULL)
$<simbolo>3->parametros = $4;
}
';' declaracion_variables
declaracion_acciones
bloque_instrucciones
12048 - J. Neira – Universidad de Zaragoza
ident;
i, j;
k, l, m;
n, o)
...);
38
Declaraciones
• Es necesario almacenar el símbolo correspondiente a cada parámetro,
su dirección asignada, y el orden en que ha sido declarado (necesario
para verificar invocaciones).
%type <lista> parametros lista_parametros
%%
parametros_formales : '(' lista_parametros ')'
{
$$ = $2;
}
| {
crear_vacia (&($$));
}
;
lista_parametros : parametros
{
$$ = $1; Acción por defecto
}
| lista_parametros ';' parametros
{
concatenar (&($1), $3);
$$ = $1;
}
;
12048 - J. Neira – Universidad de Zaragoza
39
Invocaciones
• Cada argumento debe compararse por orden de aparición con la
correspondiente declaración del parámetro.
– Los tipos deben coincidir
– Los argumentos a parámetros por referencia sólo pueden ser variables.
invocacion_accion : tIDENTIFICADOR
| tIDENTIFICADOR ’(’ argumentos ’)’
;
argumentos : expresion
{
LISTA pars;
SIMBOLO *p;
pars = (*($<identificador.simbolo>-1)).parametros;
if (longitud_lista (pars) < 1)
error ("Accion no tiene parametros.");
p = observar (pars, 1);
if ((*p).tipo != $1.tipo)
..... /*verificaciones */
$$ = 1;
}
| argumentos ',' expresion
....... /* algo parecido para $1 + 1 */
12048 - J. Neira – Universidad de Zaragoza
40
5. Perspectiva
• Sobrecarga de Operadores
function ”/” (i, j : integer) return rational is ...
Put(i/j);
• Interpretaciones posibles de ‘/’:
integer / integer ->
integer / integer ->
integer
rational
• Acción semántica:
expresion : expresion ’/’ expresion
{
if (($1.tipo == ENTERO) &&
($3.tipo == ENTERO))
???????????????????
}
;
¡hay
¡haydos
dos
posibilidades!
posibilidades!
12048 - J. Neira – Universidad de Zaragoza
41
5. Perspectiva
• Paso de parámetros:
el orden posicional y parámetros por valor/referencia es UNO de los
posibles mecanismos de paso de parámetros.
Orden
Ordennominal
nominal
procedure Quadriatic (A, B, C : in float ......
...
Quadratic(B=>M, C=>N, A=>L, .....);
orden
ordendiferente
diferente
Valores
Valorespor
pordefecto
defecto
procedure Quadriatic (A : in float := 0....
...
Quadratic (B=>M, C=>N, .....);
AAno
noaparece
aparece
12048 -
El
Ellenguaje
lenguajese
seenriquece
enriquecepero
perola
la
complejidad
del
compilador
aumenta.
complejidad
del
compilador
aumenta.
J. Neira – Universidad de Zaragoza
42
Ejercicio
• Asignación múltiple
entero i;
booleano b;
caracter c;
i, b, c := caraent(c),
i > 0,
entacar(caraent(c) + 1);
• Verificar que la cantidad y los tipos son correctos.
asignacion_multiple :
identificadores tOPAS expresiones
;
identificadores : tIDENTIFICADOR
| identificadores ’,’ tIDENTIFICADOR
;
expresiones : expresion
| expresiones ’,’ expresion
;
12048 - J. Neira – Universidad de Zaragoza
43
Ejercicio
• Inicializadores
entero i = 2, j = i + 4, k;
booleano b = FALSE, d = i > j;
• Verificar que el tipo del inicializador coincida con el de la
variable.
declaracion : tipo_variables declaradores ’;’
;
tipo_variables
: tENTERO
| tCARACTER
| tBOOLEANO
;
declaradores
: declarador
| declaradores ’,’ declarador
;
declarador : tIDENTIFICADOR
| tIDENTIFICADOR ’=’ expresion
;
12048 - J. Neira – Universidad de Zaragoza
44
Inicializadores
%union{
int tipo;
}
%type <tipo> tipo_variables
declaracion : tipo_variables declaradores
;
tipo_variables
: tENTERO
{ $$ = ENTERO; }
| tCARACTER { $$ = CHAR;
}
| tBOOLEANO { $$ = BOOLEANO;}
;
declaradores
: declarador
| declaradores ',' { $<tipo>$ = $<tipo>0; } declarador
;
declarador : tIDENTIFICADOR
| tIDENTIFICADOR '=‘ expresion
{if ($3 != $<tipo>0)
error_semantico(”...”);
}
;
12048 - J. Neira – Universidad de Zaragoza
45
Descargar