Lección 3: Análisis Semántico - unizar.eswebdiis.unizar.es/~neira/12048/12048 analisis...
Transcript of Lección 3: Análisis Semántico - unizar.eswebdiis.unizar.es/~neira/12048/12048 analisis...
112048 - J. Neira – Universidad de Zaragoza
Lección 3: Análisis Semántico
1. Expresiones y Asignación2. Estructuras de Control3. Procesamiento de Declaraciones4. Procedimientos y Funciones5. Perspectiva
Lecturas: Cooper, capítulo 4Scott, capítulo 4Aho, capítulo 8Fischer, capítulos 10, 11 , 12 , 13, 14Holub, capítulo 6Bennett, capítulo 4, 10
212048 - J. Neira – Universidad de Zaragoza
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)?
312048 - J. Neira – Universidad de Zaragoza
Operadores• Precedencia: prioridad de
los operadores; determina qué operadores obtienen sus operandos primero
• Se altera con paréntesis
5 + 5 * 6 / 10
((5 + 5) * 6) / 10
*
/
+
5 6
10
5
Mayor precedencia
5 + ((5 * 6 )/ 10)equivalente a: +
*
/
5 5
6
10
Menor
precedencia
Mayor
precedencia
ADA:logical_operator ::= and | or | xorrelational_operator ::= = | /= | < | <= | > | >= binary_adding_operator ::= + | - | & unary_adding_operator ::= + | -multiplying_operator ::= * | / | mod | remhighest_precedence_operator ::= ** | abs | not
412048 - J. Neira – Universidad de Zaragoza
Operadores• Asociatividad: determina
el orden de evaluación de operadores de igual prece-dencia
• De izquierda a derecha:
• De derecha a izquierda
• Algunos NO son asociativos:
x + 3 - y + 5 (x + 3) - y + 5 ((x + 3) - y) + 5 (((x + 3) - y) + 5)
x = y += z -= 4x = y += (z -= 4)
x = (y += (z -= 4)) (x = y += (z -= 4))
+
-
+
x 3
y
5
-=
+=
=
4z
y
x
A**B**CADA:
A**(B**C)(A**B)**C
512048 - J. Neira – Universidad de Zaragoza
Operadores• Orden de evaluación: de-
termina qué operandos se evalúan primero
• En algunos casos NO estádefinido
i = f() && g();
func2(++i, x[i]); • Ejercicio:
[]
,
i x
++
i
&&
=
i
f() g()
x > 9 && y != 3 x == 5 || y != 3 ! x > 14 ! (x > 9 && y != 23) x <= 1 && y == 6 || z < 4c >= 'a' && c <= 'z' c >= 'A' || c <= 'Z' c != d && c != '\n' 5 && y != 8 || 0 x >= y >= z
int x = 11; int y = 6; int z = 1; char c = 'k'; char d = 'y';
1100111111
Operator Name Associativity Operators
Primary left to right () [ ] . ->Unary 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 ,
C:
Mayor precedencia
¿?
612048 - J. Neira – Universidad de Zaragoza
Comprobación de expresiones con YACC
• Se utilizan atributos sinte-tizados
• El atributo será el tipo de la expresión
• 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
expr | expr '+' expr...
| expr tAND expr...
| expr tMAY expr...
| '(' expr ')‘...
| tIDENTIFICADOR...
| tCONSTENTERA;
+
-51 24
>
-51 24
resultado entero
resultado entero
resultado booleano
resultado booleano
712048 - J. Neira – Universidad de Zaragoza
Comprobación de expresiones con YACC
• Constantes e identificadores:%{typedef enum {
DESCONOCIDO, ENTERO, BOOLEANO, CHAR, CADENA} TIPO_VARIABLE;
%}%union {
TIPO_VARIABLE tipo;SIMBOLO *simbolo;
}%type <tipo> expresion%type <simbolo> tIDENTIFICADOR%%expresion : ...
| tCONSTENTERA{ $$ = ENTERO;
}| tIDENTIFICADOR{
$$ = DESCONOCIDO;if ($1 == NULL)
error_semantico(”identificador desconocido.”);...
registro de atributos
declaración de atributo por símbolo
atributo LHSsintetizado
atributo
RHS
812048 - 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.");
...}
;
912048 - J. Neira – Universidad de Zaragoza
YACC: comprobación de expresiones• ¡Es ambigua!
• No se ha especificado la precedencia ni asociati-vidad de los operadores
shift tCONSTENTERA 2reduce tCONSTENTERA -> expr exprshift * expr *shift tCONSTENTERA expr * 3reduce tCONSTENTERA -> expr expr * expr
reduce expr * expr -> expr expr
shift + expr * expr +
2*3+42*3+4
2*(3+4)2*(3+4)(2*3)+4(2*3)+4
ó ó
1012048 - J. Neira – Universidad de Zaragoza
menor precedencia
mayor precedencia “alteración” de
la precedencia
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
;
1112048 - J. Neira – Universidad de Zaragoza
expresion : expresion ’+’ mulexp| expresion ’-’ mulexp| mulexp
;
mulexp : primaria ’*’ mulexp| primaria ’/’ mulexp| primaria
;primaria : ’-’ primaria
| ’(’ expresion ’)’| tCONSTENTERA
;
Asociatividad: solución implícita• Se re-escribe la gramática para definirla implícitamente
de izquierda a derecha
de derecha a izquierda(¡normalmente es al revés!)
1212048 - J. Neira – Universidad de Zaragoza
Precedencia y Asociatividad: solución explícita
• YACC permite definir am-bas cosas explícitamente
• %left indica la asociatividad de los operadores (también existe %right).
• El orden de las declaraciones de-termina la precedencia de los operadores.
• A cada producción se le asocia la precedencia del token más a la derecha.
• Los conflictos shift/reduce se resuelven utilizando la prece-dencia.
• Parser pequeño y eficiente.
%left ’+’ ’-’%left ’*’ ’/’...%nonassoc UMINUS%%expr : expr ’+’ expr
...| expr tAND expr
...| ’(’ expr ’)’| ’-’ expr %prec UMINUS| tCONSTENTERA
...;
Precedencia:de menora mayor
expr ’+’ expr ’*’
¿preced(’*’) > preced(’+’)?•si, shift ’*’•no, reduce expr ’+’ expr -> expr
1312048 - J. Neira – Universidad de Zaragoza
Precedencia
• Si el * tuviese mayor prece-dencia que el +:
• Si el + tuviese mayor pre-cedencia que el *:
2*3+42*3+4
Reading (2)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReading ('*')Shifting ('*')Reading (3)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReducing expr '*' expr -> exprReading ('+')Shifting ('+')Reading (4)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReducing expr '+' expr -> expr
Reading (2)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReading ('*')Shifting ('*‘)Reading (3)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReading ('+')Shifting ('+')Reading (4)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReducing expr '+' expr -> exprReducing expr '*' expr -> expr
1010 1414
1412048 - J. Neira – Universidad de Zaragoza
33 -5-5
Asociatividad
• Asociatividad por la izquierda:
• Asociatividad por la derecha:
2-3+42-3+4
Reading (2)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReading ('-')Shifting ('-')Reading (3)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReducing expr '-' expr -> exprReading ('+')Shifting ('+')Reading (4)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReducing expr '+' expr -> expr
Reading (2)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReading ('-')Shifting ('-')Reading (3)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReading ('+')Shifting ('+‘)Reading a (4)Shifting (tCONSTENTERA)Reducing tCONSTENTERA -> exprReducing expr '+' expr -> exprReducing expr '-' expr -> expr
1512048 - J. Neira – Universidad de Zaragoza
¿$3?¿NULL?
Asignación%union{
struct { char *nombre;SIMBOLO *simbolo;
} identificador;}%type <identificador> tIDENTIFICADOR
i := j + 42;
asignacion:tIDENTIFICADOR{
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)&&($1.simbolo->variable != $4))
error_semantico ("tipos incompatibles");}
;
lex debe buscarlo en la tabla
1612048 - J. Neira – Universidad de Zaragoza
Mejor...• $$ se refiere al atributo sinteti-
zado, sólo en la última acción de la producción.
• Acciones intermedias: $$ atributo asociado con la acción.
• Esto permite transmitir informa-ción entre acciones
asignacion:tIDENTIFICADOR{
$<ok>$ = FALSE;if ...else $<ok>$ = TRUE;
}tOPAS expresion{
if ($<ok>2 &&($1 != DESCONOCIDO) && ($4 != DESCONOCIDO)&&($1.simbolo->variable != $4))error_semantico ("tipos incompatibles");
$$ ...}
;
%union{...int ok;...
}
1712048 - J. Neira – Universidad de Zaragoza
Asignación a vectores• Los atributos también pueden utilizarse para contar elementos.
entero v[10];...
v := [10,-5,4,i,j+1];
asignacion_vector:tIDENTIFICADOR{...}tOPAS ’[’ lista_expresiones ’]’{...
if ($1.simbolo->dimension < $5)error_semantico ("cantidad incorrecta");
};lista_expresiones :
expresion{$$ = 1;}
| lista_expresiones ’,’ expresion{$$ = $1 + 1;}
%union{int cantidad;
}%type <cantidad> lista_expresiones
1812048 - J. Neira – Universidad de Zaragoza
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.");
}tENTlista_instruccionesresto_selecciontFSI
;mientras_que: tMQ expresion
...lista_instruccionestFMQ
;
1912048 - J. Neira – Universidad de Zaragoza
Estructuras de Control• Instrucciones tipo break y continue
a := 10;
mq a > 0...si a = 0
continuar fsi...
fmq
%{int bucle = 0;%}
%%...continuar :
{if (!bucle)
error_semantico("Solo dentro de bucles.");
};mientras_que :
tMQ expresion{
bucle = TRUE; }lista_instrucciones {
bucle = FALSE; }tFMQ
; ¿Problemas?¿Problemas?
2012048 - J. Neira – Universidad de Zaragoza
Estructuras de Control
%{int bucle = 0;%}%%...continuar :
{if (bucle > 0)
;else
error_semantico ("Solo dentro de bucles.");
};mientras_que:
tMQ expresion{++bucle;}lista_instrucciones {--bucle;}tFMQ
;
a := 10;
mq a > 0...mq b > 0...fmqsi a = 0
continuar fsi...
fmq
¡Puede haberbucles anidados!
Mejor contar los bucles:
2112048 - J. Neira – Universidad de Zaragoza
3. Declaración de Variables• Declaraciones tipo C: El tipo está definido al procesar los identi-
ficadores.int i, j, k;float x, y, z, w;
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{ ... }
%union{int tipo;
}%type <tipo> tipo_variables
2212048 - J. Neira – Universidad de Zaragoza
Atributos heredadosdeclaracion : 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?, ...);elseerror_semantico ("id duplicado.");
}| identificadores ‘,’ tIDENTIFICADOR{ ... }
Atributo del símbolo almace-nado en la pila antes de
identificadores
Atributo del símbolo almace-nado en la pila antes de
identificadores
leer : tLEER ’(’ identificadores ’)’;
Ahora antes de identificadores aparece también ‘(‘.
Ahora antes de identificadores aparece también ‘(‘.
$0, $-1,...
OJO:
2312048 - J. Neira – Universidad de Zaragoza
Bloques{%int nivel;%}...void abrir_bloque (){nivel++;...
}void cerrar_bloque (){...nivel--;
}
identificadores: tIDENTIFICADOR{if (($1.simbolo == NULL) ||
($1.simbolo->nivel != nivel))introducir_variable (tabsim, $1.nombre,
$<tipo>0, nivel, ...);else error_semantico ("id duplicado.");
}
declaracion_accion:cabecera_accion ';'declaracion_variablesdeclaracion_accionesbloque_sentencias{...cerrar_bloque();
};cabecera_accion:
tACCION tIDENTIFICADOR{...abrir_bloque();}parametros_formales
;
El bloque se abre después de procesarel identificador y antes de los parámetros
2412048 - J. Neira – Universidad de Zaragoza
Declaración de Variables• Declaraciones tipo ADA: El tipo NO está definido al procesar los
identificadores.I, J, K : Integer;X, Y, Z, W : Float;
declaracion: identificadores ’:’ tipo_variables ’;’
{ declaracion_variables ($1, $3);
}...;tipo_variables : ...;identificadores : tIDENTIFICADOR
{ $$ = crear_lista ($1); }| identificadores ’,’ tIDENTIFICADOR
{ $$ = anadir ($1, $3); }
Es necesario usar listas de ids.Es necesario
usar listas de ids.
%union{LISTA lista;
}%type <lista> identificadores
G1G1
2512048 - J. Neira – Universidad de Zaragoza
Alternativa• Modificación de la gramática • ¡Cambia el orden de inserción!
declaracion : tIDENTIFICADORresto_declaracion{...}
;
resto_declaracion : ',' tIDENTIFICADORresto_declaracion
{$$ = $3;...
}| ':' tipo_variables{
$$ = $2;}
G2G2
Evita el manejo delistas de nombres.
Evita el manejo delistas de nombres.
%union{int tipo;
}%type <tipo> resto_declaracion
i, j, k : Integer;
3 2 1
321 G1G1
G2G2
2612048 - J. Neira – Universidad de Zaragoza
¿es relevante el orden en la declaración?• En Pascal, el orden NO es
relevante
• NO hay información semántica en el orden de declaración.
• En C, ADA ¡el orden si puede ser relevante!
• SI hay información semán-tica en el orden de declara-ción (la secuencialidad de los inicializadores).
var i, j, k : integer;x, y, z, w : real;
var w, y, z, x : real;k, i, j : integer;
int a = pop(),b = pop();
...push(a-b);
int b = pop(),a = pop();
...push(a-b);
2712048 - J. Neira – Universidad de Zaragoza
Ventajas sintácticas
• C:
• ADA:
char* i, j, k;
i, j, k : access character;
2812048 - J. Neira – Universidad de Zaragoza
4. Procedimientos y Funciones
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
beginq (j);r (’a’)
end
Declaraciones:Almacenar la declaración en la tabla (incluyendo los parámetros).
Invocaciones:Verificar que la cantidad, tipo y clase de los argumentos sea correcta.
2912048 - J. Neira – Universidad de Zaragoza
Declaraciones
accion p(val entero i, j; ref booleano k, l, m;val caracter n, o)
%union {.... struct {SIMBOLO *simbolo; char *nombre;} ident;LISTA *lista;
.....}%type <ident> tIDENTIFICADOR%type <lista> parametros_formales%%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_accionesbloque_instrucciones
3012048 - J. Neira – Universidad de Zaragoza
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; }
| lista_parametros ';' parametros{
concatenar (&($1), $3);$$ = $1;
};
Acción por defectoAcción por defecto
3112048 - J. Neira – Universidad de Zaragoza
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 */
3212048 - J. Neira – Universidad de Zaragoza
5. Perspectiva• Sobrecarga de Operadores
• Interpretaciones posibles de ‘/’:
• Acción semántica:
function ”/” (i, j : integer) return rational is ...
Put(i/j);
integer / integer -> integerinteger / integer -> rational
expresion : expresion ’/’ expresion{ if (($1.tipo == ENTERO) &&
($3.tipo == ENTERO))???????????????????
};
¡hay dosposibilidades!
¡hay dosposibilidades!
3312048 - J. Neira – Universidad de Zaragoza
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.
procedure Quadriatic (A, B, C : in float .........Quadratic(B=>M, C=>N, A=>L, .....);
Orden nominal Orden nominal
procedure Quadriatic (A : in float := 0.......Quadratic (B=>M, C=>N, .....);
Valores por defecto Valores por defecto
orden diferenteorden diferente
A no apareceA no aparece
El lenguaje se enriquece pero la complejidad del compilador aumenta.
El lenguaje se enriquece pero la complejidad del compilador aumenta.
3412048 - J. Neira – Universidad de Zaragoza
¿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++;
}
3512048 - J. Neira – Universidad de Zaragoza
= .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:
• Precedencia del ++ mal definida: *y++ equivale a *(y++)
while (*s1++ = *s2++);
3612048 - J. Neira – Universidad de Zaragoza
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)++;
}}
3712048 - J. Neira – Universidad de Zaragoza
Precedencia y asociatividad
• NO equivale a: if ((x & mask) == 0)
• NO equivale a: if ((x < y) && (y < z))
• hi << 4 + low?• x == y == z?
if (x & mask == 0)
if (x & (mask == 0) )
if (x < y < z)
if (((x < y) && (1 < z)) || (0 < z))
3812048 - J. Neira – Universidad de Zaragoza
Legibilidad
int x;int y;int z;…x = y---z--;
3912048 - J. Neira – Universidad de Zaragoza
Quiere decir:
x : integer;y : integer;z : integer;
x := y - z;y := y - 1;z := z - 1;
4012048 - J. Neira – Universidad de Zaragoza
Comentario acerca de x = y---z--; • Un programador cuidadoso escribiria:
• Sigue siendo preferible:
• Es más fácil de entender
x = y-- - z--;
x = y - z;y--;z--;
4112048 - J. Neira – Universidad de Zaragoza
Ejercicio• Asignación múltiple
• Verificar que la cantidad y los tipos son correctos.
entero i;booleano b;caracter c;i, b, c := caraent(c),
i > 0, entacar(caraent(c) + 1);
asignacion_multiple : identificadores tOPAS expresiones
;
identificadores : tIDENTIFICADOR| identificadores ’,’ tIDENTIFICADOR
;
expresiones : expresion| expresiones ’,’ expresion
;
4212048 - J. Neira – Universidad de Zaragoza
Ejercicio• Inicializadores
• 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
;
entero i = 2, j = i + 4, k;booleano b = FALSE, d = i > j;
4312048 - J. Neira – Universidad de Zaragoza
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(”...”);
};