Escolar Documentos
Profissional Documentos
Cultura Documentos
- la accin semntica de A debe retornar un valor cuyo tipo sea el asociado a A - valor de A se puede construir de B,C,D
Parser Recursivos Descendentes: acciones semnticas son los valores retornados por las funciones, o sus efectos colaterales.
Diseo de Compiladores
3. E--> + T E | 5. T --> * F T |
S E E T T FT T F F num T FT T F id T *FT F (E) num S E$ E TE id + S E$ E TE E +TE T FT T T * ( ) S E$ E TE E $
Diseo de Compiladores
Se arregla para que se pueda interpretar ej: id1 * id2 $ E TE F T E T ( F ( ) ) E T ( a) E T ( a*F()) E ...
Diseo de Compiladores
Diseo de Compiladores
Diseo de Compiladores
Pasadas en un compilador
Compiladores de 1 pasada : todo el compilador se genera en las acciones semnticas. ms rpido, menos memoria en caso computador lento. pueden condicionar definicin de lenguajes, por ej: procedimientos forward de Pascal. Compiladores ms modernos, muchas pasadas (5-15) ms modular, menos limitaciones Entre las pasadas, el compilador genera representaciones intermedias, si usa k pasadas, entonces genera k-1 representaciones intermedias.
Diseo de Compiladores
E T F id
+ T F id
T * F id
Cada no terminal lo asociamos con una estructura que representa un nodo del rbol :
typedef struct T_sent_ *T_sent typedef struct T_exp_ *T_exp typedef struct T_listaexp_ *T_listaexp typedef struct char *string typedef enum { Kmas,Kmenos,Kdiv,Kpor } T_binop
Prog: sent { $$ = $1 } Gramtica 2da. parte sent : sent PTOYCOMA sent { $$ = C_Compuesta($1,$3) ;} | ID ASSIGN exp { $$ = C_Asignacion($1,$3);} | PRINT ( exps ) { $$ = C_Print($3); } ; exps : exp | exps COMA exp ; exp : ID | INT | exp DIV exp | exp POR exp | exp MAS exp | exp MENOS exp | ' ( ' exp ' ) ' | sent COMA exp ; { $$ = C_ListaExp($1,NULL); } { $$ = C_ListaExp($1); } { $$ = C_IdExp($1); } { $$ = C_NumExp($1); } { $$ = C_OpExp($1,DIV,$3); } { $$ = C_OpExp($1,POR,$3); } { $$ = C_OpExp($1,MAS,$3); } { $$ = C_OpExp($1,MENOS,$3); } { $$ = $2;} { $$ = C_SeqExp($1, $3) ; }
Diseo de Compiladores
Chequeo de Tipos
Funciones: - determinar el tipo de todas las expresiones - verificar valores y variables se usan correctamente - resolver ambiguedades mediante transformaciones al programa, ej: conversiones de tipos Info de declaraciones se almacena en la tabla de smbolos Al referenciar un nombre se consulta la tabla de smbolos y se valida los tipos. Chequeo esttico: tipos se chequean en tiempo de compilacin Chequeo dinmico: se genera cdigo para chequear los tipos en tiempo de ejecucin
Ejemplo: var table : array[ 0.255] i : int table [ i ] , i debe estar entre 0255
Diseo de Compiladores
Diseo de Compiladores
Punteros: Si T es un tipo, POINTER(T) es un tipo que denota un puntero a un objeto de tipo T. Funcin: Si D es un dominio de tipo D y R codominio de tipo R, f: D R es un producto que denota tipo de argumentos.
function f ( a, b : integer ) : ^real integer x integer pointer(real)
Diseo de Compiladores
Constructores Productos: Si T1...Tn son tipos, T1 x...x Tn es el producto cartesiano que representa un tipo producto. Records: - Se usan nombres para acceder a los elementos Si Ti x Ni es el tipo y el nombre del elemento i entonces (T1 x N1 ) x (T2 x N2 ) .... x(Tn x Nn ) representa un tipo record
TYPE fila = RECORD posicion: INTEGER; palabra : ARRAY 10 OF CHAR; END ( posicion x INTEGER) x ( palabra x ARRAY(0...9) of CHAR)
Funciones: D
R
Diseo de Compiladores
- construir los tipos - dar altas en tabla de smbolos - calcular direcciones, ej: offsets
Scope: procedimientos delimitan scopes, al ingresar a un procedimiento, se incrementa el nivel, al salir se decrementa
Decl_Procedure -> Cab_Proc ; Secuencia_Decl Cuerpo ID entro_scope salgo_scope
Diseo de Compiladores
struct product
Record 20
exp
struct type
Integer 4
Array 10 10
Byte 1
Pointer 4
node
Diseo de Compiladores
POINTER TO b
Pointer 4
luego que terminamos de scannear una procedure, verificamos que no queden referencias no resueltas y que el tipo sea array o record
Diseo de Compiladores
3 KVar offset
3 KType
3 KConst 3.1416
Integer 4
Pointer 4
Record 20
Real 4
Diseo de Compiladores
: procedure ParamsFormales { $1 ->type = $2; $$ = $1;} : PROCEDURE ID { $$ = insert($2); $$->KIND = KProcedure; entro_scope ( ) ; }
cuerpo
: BEGIN secuencia_sentencias END { dejo_scope ( ) } Verifico el nombre de procedure coincida en cabezal y fin
Declaraciones en Oberon
Declaracin de variables
DeclVariable : | ID : type { Simbolo p = insert($1);} p->kind = KVar; p->type = $3; $$ = $3; } ID , Declvariable { Simbolo p = insert($1);} p->kind = KVar; p->type = $3; $$ = $3; }
Declaracin de tipos
type : ID
| | | ;
{ Simbolo p = lookup($1);} if ( p && p->kind == kType ) $$=p->type; else . } ArrayType PointerType RecordType
Diseo de Compiladores
Declaraciones de Records
Construyo una lista de productos (T1 x N1 ) x (T2 x N2 ) .... x(Tn x Nn ) Calculo el largo del registro luego de construir el producto
RecordType : RECORD Lista_Sec_Campos END { Product p; $$ = type(Record,0); $$ ->u.fields = $2 ; for ( p = $2; p; p = p->link ) $$->size += p->type->size; $$->size=roundup($$->size,align($$)); }
Lista_Sec_Campos : Lista_Sec_Campos ; Campos {$$=fields($1,$3);} | Campos { $$ = $1; } Campos : ID : type { $$ = product($1, $3); } | ID , Campos { $$ = product($1, $3->type); $$->link = $3; }
Declaraciones de Arrays
Arrays multi-dimensional:
ArrayType : ARRAY Array ; Array
arrays n, m of type
{ $$ = $2 }
: expr OF type { $$ = type(Array, $1->u.ivalor*$3->size); $$->u.len = $1->u.ivalor;$$->type=$3; } | expr , Array { $$ = type(Array, $1->u.ivalor*$3->size); $$->u.len = $1->u.ivalue ;$$->type=$3; } ;
Diseo de Compiladores
Declaracin de Punteros
PointerType : POINTER TO ArrayType { $$ = type(Pointer,4); $$ ->type = $3 ;} | POINTER TO RecordType { $$ = type(Pointer,4); $$ ->type = $3 ;} | POINTER TO ID { simbolo p= lookup($3) if (p && (p->type->op == ARRAY || p->type->op==RECORD) { $$ = type(Pointer,4) $$->type = p->type else error } ;
Diseo de Compiladores
if E then S { if E.type = boolean then S.type : = S1.type else S.type : = type_error } while E do S { if E.type = boolean then S.type : = S1.type else S.type : = type_error } S;S { if 1.type = void and S2.type = void then S.type = void else S.type : = type_error }
Diseo de Compiladores
{ if E1.type = integer and E2.type = integer then E.type = integer else E.type = type_error } array(I,T) x integer --> T { if E1.type = array( I, T ) and E2.type = integer then E.type = T pointer(T) --> T else E.type = type_error } { if E1.type = pointer( T ) then E.type = T else E.type : = type_error }
Diseo de Compiladores
E --> E [ E ]
E --> E ^
Equivalencia estructural entre expresiones T1 y T2 son equivalentes sii estn compuestas por los mismos constructores en el mismo momento Equivalencia por nombre entre expresiones T1 y T2 son equivalentes sii T1 y T2 tiene los mismos nombres de tipos Ej : type link = * celda por nombre var next : link ; estructural last: * celda ;
variable next last nombre del tipo link T tipo de la expr pointer(celda) pointer(celda)
Diseo de Compiladores
Conversin de Tipos
Conversiones implcitas: ocurren como resultado de aplicar reglas semnticas al lenguaje ej : x + i x es real, i es entero, se produce una conversin implcita del valor entero al real durante la adicin. Conversiones explcitas: el programador debe especificar la conversin ej: casts en C, ord y chr en Pascal y Oberon - Conversiones complican el chequeo de tipos al traducir
E --> E + E { case (E1.type, E2.type) in (integer,integer): E.type = integer (integer,real) , (real,integer), (real,real): E.type = real else E.type = type_error }
Diseo de Compiladores