TECNOLÓGICO NACIONAL DE MÉXICO INSTITUTO TECNOLÓGICO DE ACAPULCO “Educación Tecnológica con Compromiso Social” Carrera: Ingeniería en Sistemas Computacionales Asignatura: Lenguajes y Autómatas II
Reporte de actividades de aprendia!e " pr#cticas Unidad : !eneración de código intermedio""
Co$petencia espec%&ica a desarro''ar #ise$a mediante el uso de reglas sem%nticas dirigidas por sinta&is' un anali(ador sem%ntico para un compilador"
Pro&esor( Sil)estre *edolla Solano Integrantes del e+uipo: ,
Acapulco' !uerrero' 3&"' 0 de Septiem4re del .,0"
1ndice Contenido
Introd*cci2n.......................................................................................3 Actividad 34........................................................................................4 Detectar Errores Se$#nticos4..................................................................4 E!e$p'os De La Actividad Uno4 ..............................................................7 Actividad 54......................................................................................23 Dise6ar 7 Se'eccionar In&or$aci2n So)re La Constr*cci2n De Un Ana'iador Se$#ntico4.......................................................................................23 E!e$p'os De La Actividad Dos.............................................................28 Actividad 84...................................................................................... 46 Reconocer E' Mane!o De Tipos En Las E9presiones 7 E' Uso De Operadores4......46 Actividad :4......................................................................................54 Esta)'ecer Las Re-'as Para La Conversi2n De Tipos ;Castin-< En E9presiones4...54 Conversiones I$p'%citas.................................................................... 56 Conversiones E9p'%citas.................................................................... 56 E9cepciones De Las Conversiones De Tipos En Tie$po De E!ec*ci2n............ 58 Actividad =4...................................................................................... 59 A-re-ar Acciones Se$#nticas A La Estr*ct*ra De La Gra$#tica4.....................59 Actividad >4...................................................................................... 70 Manip*'ar La Ta)'a De Conversi2n De S%$)o'os 7 De Errores 7 Direcciones4...... 70 Actividad ?4......................................................................................65 Inte-rar E@*ipos De Tra)a!o Para La Constr*cci2n De Un Ana'iador Se$#ntico4. 65 Actividad 4...................................................................................... 81 Prop*esta De Pro"ecto Para E' Ana'iador LB9ico 7 Sint#ctico4....................... 81 Conc'*siones.................................................................................... 82 Bibliografía.................................................................................... 83
Actividad 34 Aplicar los tipos de notación para la conversión de expres iones: Infija, prefija y posfija
2.3 Los Esquema esquemasde degeneración generación son las estrategias o acciones que se deberán realizarse y tomarse en cuenta en el momento de generar código intermedio.
2
.
Los esquemas de generación dependen de cada lenguaje. Tomaremos algunos esquemas de generación del lenguaje C. Variables y constantes Las ariables y constantes deben separarse de tal manera que queden las e!presiones una por una de manera simple. "or ejemplo int a#b#c$ se descompone a int a$ int b$ intc$ respectiamente. E!presiones En esta %unción recibe una cadena que representa una l&nea de código intermedio y toma las medidas oportunas para que ese código se utilice. Estas medidas pueden ser escribir la l&nea en un %ic'ero adecuado# almacenar la instrucción en una lista que despu(s se pasará a otros módulos# o cualquier otra que necesitemos en nuestro compilador. E!presiones aritm(ticas )on aquella donde los operadores que interienen en ella son num(ricos# el resultado es un n*mero y los operadores son aritm(ticos. Los operadores aritm(ticos más com*nmente utilizados son+ ,#- # # / y 0. Comenzamos el estudio por las e!presiones aritm(ticas. Lo que tendremos que 'acer es crear por cada tipo de nodo un m(todo que genere el código para calcular la e!presión y lo emita. Ese código dejará el resultado en un registro# cuyo nombre deolerá el m(todo como resultado. "ara reserar estos registros temporales# utilizaremos una %unción# resera. En principio bastar 1a con que esta %unción deuela un registro distinto cada ez que se la llame. Cada nodo generará el código de la siguiente manera+ "or cada uno de sus operandos# llamara al m(todo correspondiente para que se eal*e la sub e!presión. )i es necesario# reserara un registro para guardar su resultado. Emitirá las instrucciones necesarias para realizar el cálculo a partir de los operandos.
nstrucciones de asignación La sinta!is general de la instrucción de asignación es+ nombredelaariable 4 alor El alor a la derec'a del signo igual puede ser una constante# otra ariable
3
o una e!presión que combine constantes y ariables# pero siempre la ariable y su alor deben ser del mismo tipo de dato. Ejemplos+ edad0 4 5 area6 4 72.3 nombre8 4 9"edro:
nstrucciones de asignación compuesta
Las instrucciones de asignación compuesta realizan primero una operación en una e!presión antes de asignarla a un elemento de programación. En el siguiente ejemplo se muestra uno de estos operadores# ,4# que incrementa el alor de la ariable del lado izquierdo del operador con el alor de la e!presión de la derec'a. ;na instrucción de asignación asigna el alor de una e!presión a una ariable. En general# si la ariable que se a a asignar es una propiedad# la propiedad debe ser de lectura y escritura o de sólo escritura$ en caso contrario# se produce un error de compilación. )i la ariable es una ariable de sólo lectura# la asignación debe producirse en un constructor )'ared o un constructor de instancia apropiado para el tipo de la ariable$ en caso contrario# se producirá un error de compilación. nstrucciones de control Esta %orma de programación sólo permite resoler problemas sencillos. "ara resoler problemas más complejos# nos puede interesar que dependiendo de los alores de los datos# se ejecuten unas instrucciones u otras. Las instrucciones condicionales nos an a permitir representar (ste tipo de comportamiento. )entencias < y )=TC>. En otros casos# nos encontraremos con la necesidad de repetir una instrucción o instrucciones un n*mero determinado de eces. En (stos casos utilizaremos instrucciones de control iteratias o repetitias ?ciclos@. )entencias =>LE# AB-=>LE y
Actividad 1 4
package infixpostfix4; import java.util.Scanner; import java.util.Stack; public class InfixPostfix4 { public static void main(String[ args! { ""#ntrada de datos S$stem.out.println(%&#scribe una expresi'n algebraica %!; Scanner leer ) ne* Scanner(S$stem.in!; ""+epurar la expresion algebraica String expr ) depurar(leer.next,ine(!!; String[ arra$Infix ) expr.split(% %!; ""+eclaraci'n de Stack < String > Stack < String > para operadores Stack < String >
las pilas E = new Stack < String > (); ""Pila entrada P = new Stack < String > (); ""Pila temporal S = new Stack < String > (); ""Pila salida
""-adir la arra$ a la Pila de entrada (#! for (int i ) arra$Infix.lengt/ 0 1; i 2) 3; i00! { #.pus/(arra$Infix[i!;
tr$ { ""-lgoritmo Infijo a Postfijo while (!E.isEmpty()) { switch (pref(E.peek())){ case 1 P.psh(E.p"p()); #reak; case $ case % while(pref(P.peek()) >= pref(E.peek())) { S.psh(P.p"p()); & P.psh(E.p"p()); #reak; case ' while(!P.peek().eals(()) { S.psh(P.p"p()); & P.p"p(); E.p"p(); #reak;
5
*efalt S.psh(E.p"p()); & &
""#liminacion de 5impure6as7 en la expresiones algebraicas String infix ) expr.replace(% %8 %%!; String postfix ) S.toString(!.replace-ll(%[9999[8%8 %%!; "":ostrar resultados S$stem.out.println(%#xpresion Infija % infix!; S$stem.out.println(%#xpresion Postfija % postfix!; catc/(#xception ex!{ S$stem.out.println(%#rror en la expresi'n algebraica%!; S$stem.err.println(ex!; ""+epurar expresi'n algebraica private static String depurar(String s! { s ) s.replace-ll(%99s%8 %%!; ""#limina espacios en blanco s ) %(% s %!%; String simbols ) %0&"(!%; String str ) %%; ""+eja espacios entre operadores for i ) 3; i < s.lengt/(!; i! { if (int (simbols.contains(%% s.c/ar-t(i!!! { str ) % % s.c/ar-t(i! % %; else str ) s.c/ar-t(i!; return str.replace-ll(%99s%8 % %!.trim(!; ""=erar>uia de los operadores private static int pref(String op! { int prf ) ??; if (op.e>uals(%@%!! prf ) A; if (op.e>uals(%&%! BB op.e>uals(%"%!! prf ) 4; if (op.e>uals(%%! BB op.e>uals(%0%!! prf ) C; if (op.e>uals(%!%!! prf ) D; if (op.e>uals(%(%!! prf ) 1; return prf;
6
Actividad 54 Dise6ar " se'eccionar in&or$aci2n so)re 'a constr*cci2n de *n ana'iador se$#ntico4 Atri)*tos " Gra$#ticas con Atri)*tos
7
In5ormalmente' se llamar% atributos de un s&mbolo de la gramática a toda in5ormación a$adida en el %r4ol de deri)ación por el anali(ador sem%ntico' asociada a los sím4olos de los nodos anotados" Un componente importante de las gram%ticas de atri4utos es el algoritmo de c%lculo de los )alores" Ejemplos de atri4utos: o o o
Tipo de una )aria4le 6alor de una e&presión U4icación en memoria de una )aria4le
o o
Código de unsigni5icati)os procedimiento 78meroo4jeto de dígitos en un n8mero
Una gram%tica de atri4utos es una gram%tica independiente del conte&to en la cual a sus sím4olos terminales y no terminales se les dota de unos atri4utos y a sus producciones de unas 5unciones de e)aluación que 'acen que dic9os atri4utos se propaguen a tra)s de la gram%tica" Su 5in es conocer un determinado )alor de un atri4uto en cual+uier parte del %r4ol de deri)ación y tomar la decisión oportuna" Un atri4uto es una propiedad asociada a una estructura sint%ctica" Si una estructura sint%ctica representada por el sím4olo gramatical ; tiene asociado un atri4uto a lo representaremos por ;"a <7om4re sím4olo" 7om4re atri4uto= Ejemplo: numero >? numero digito @ digito a=
numero>? digito
numero")alor digito")alor 4= digito")alor
numero >? numero digito numero,")alor numero")alor B ,.
Las 5unciones sem%nticas relacionan los )alores de los atri4utos de5inidos so4re la gram%tica atri4uida y )an asociadas a producciones de la gram%tica atri4uida"
#e5inición 5ormal Una gram%tica de atri4utos est% 5ormada por una tripleta !A D!IC' A' F ! G gram%tica independiente del conte&to
8
A G atri4utos asociados a los sím4olos terminales y no terminales G 5unción de e)aluación' 5unción asociada a producción +ue determina como o4tener unos atri4utos en 5unción de otros dentro de la misma producción
a es un atri4uto asociado al sím4olo no terminal A y o4tiene su )alor en 5unción de los atri4utos: a asociado a ;,' 4 asociado a ; 'Hy ( asociado a ;m < es un atri4uto o4tenido en 5unción de la parte derec9a de la producción=
a es un atri4uto asociado al sím4olo ;, y o4tiene su )alor en 5unción de los atri4utos: a asociado a A' 4 asociado a ;
A'-orit$os para C#'c*'o de Atri)*tos Al igual +ue e&isten 9erramientas +ue construyen anali(adores sint%cticos a partir de gram%ticas li4res de conte&to' tam4in e&isten 9erramientas autom%ticas +ue generan e)aluadores de gram%ticas atri4uidas o' en la mayor parte de los casos' de5iniciones dirigidas por sinta&is" En muc9as ocasiones' las 9erramientas de 9
desarrollo de procesadores de lenguaje o5recen la posi4ilidad de especi5icar' de un modo imperati)o en lugar de declarati)o' las reglas sem%nticas de las de5iniciones dirigidas por sinta&is atri4uidas en una 8nica pasada
Una rutina sem%ntica no de4e utili(ar atri4utos sinteti(ados de un sím4olo gramatical +ue est a la derec9a de ella" G Un atri4uto sinteti(ado para el no terminal de la i(+uierda sólo se puede calcular posteriormente a los atri4utos de los +ue depende" La rutina sem%ntica +ue calcula estos atri4utos se suele colocar al 5inal del lado derec9o de la producción"
La Ta)'a de S%$)o'os Un compilador utili(a una ta4la de sím4olos para lle)ar un registro de la in5ormación so4re %m4ito y el enlace los nom4res" Se5uente" e&amina de sím4olos cada )e(el+ue se encuentra un de nom4re en el te&to Si la seta4la descu4re un nom4re nue)o o nue)a in5ormación so4re un nom4re ya e&istente' se producen cam4ios en la ta4la" Un mecanismo de ta4la de sím4olos de4e permitir a$adir entradas nue)as y encontrar las entradas e&istentes e5icientemente" Los dos mecanismos para ta4las de sím4olos presentadas en esta sección son listas lioeal"es y ta4las de dispersión" Cada es+uema se e)al8a 4as%ndose en el tiempo necesario para a$adir n entradas y reali(ar e consultas" Una lista lineal es lo m%s 5%cil de implantar' pero su rendimiento es po4re cuando e y n s )uel)en m%s grandes" Los es+uemas de dispersión proporcionan un mayor rendimiento con un es5uer(o algo mayor de programación y gasto de espacio" Am4os mecanismos pueden adaptarse r%pidamente para 5uncionar con la regla del anidamiento m%s cercano" Es 8til +ue un compilador pueda aumentar din%micamente' la ta4la de sím4olos durante la compilación" Si la ta4la de sím4olos tiene tama$o 5ijo al escri4ir el compilador' entonces el tama$o de4e ser lo su5icient emente grande como para al4ergar cual+uier programa 5uente" Es muy pro4a4le +ue dic9o tama$o sea demasiado grande para la mayoría de los programas e inadecuado para algunos"
Entradas de 'a ta)'a de s%$)o'os Cada entrada de la ta4la de sím4olos corresponde a la declaración de un nom4re" El 5ormato de las entradas no tiene +ue ser uni5orme por+ue la in5ormaci ón de un nom4re depende del uso de dic9o nom4 re" Cada entrada se puede implantar como un registro +ue conste de una secuencia de pala4ras consecuti)as de memoria" Qara mantener uni5ormes los registros de la ta4la de sím4olos' es con)eniente guardar una parte de la in5ormación de un nom4re 5uera de la entrada de la ta4la' almacenando en el registro sólo un apuntador a esta in5ormación" 7o toda la in5ormación se introduce en la ta4la de sím4olos a la )e(" Las pala4ras cla)e se introducen' si acaso' al inicio" El anali(ador l&ico 4usca secuencias de letras y dígit os en la ta4la de sím4olos para determinar si se 9a encontrado una pala4ra cla)e reser)ada o un 11
nom4re" Con este en5o+ue' las pala4ras cla)e de4en estar en la ta4la de sím4olos antes de +ue comience el an%lisis l&ico" En ocasiones' si el anali(ador l&ico reconoce las pala4ras cla)e reser)adas' entonces no necesitan aparecer en la ta4la de sím4olos" Si el lenguaje no con)ierte en reser)adas las pala4ras cla)e' entonces es indispensa4le +ue las pala4ras cla)e se introdu(can en la ta4la de sím4olos ad)irtiendo su posi4le uso como pala4ras cla)e"
Caracteres dentro de *n no$)re E&iste una distinción entre el componente l&ico id para un identi5icador o nom4re' el le&emadel 5ormado porLas la cadena componen el nom4re' y los atri4utos nom4re" cadenasdedecaracteres caracteres+ue pueden ser di5íciles de manejar' así +ue los compiladores utili(an a menudo alguna representación de longitud 5ija del nom4re en lugar del le&ema" El le&ema es necesario cuando se esta4lece por primera )e( una entrada a la ta4la de sím4olos y cuando se 4usca un le&ema encontrado en los datos de entrada para determinar si es un nom4re +ue ya 9a aparecido" Una representación 9a4itual de un nom4re es un apuntador a una entrada en la ta4la de sím4olos para l" Si 9ay un límite superior pe+ue$o para la longitud de un nom4re' entonces los caracteres del nom4re pueden almacenarse en la entrada de la ta4la de sím4olos' como se muestra en la 5igura
E!e$p'os de 'a actividad dos pacage toens import ja)a"util"B 12