SlideShare una empresa de Scribd logo
1 de 213
CURSO: PROGRAMACION DE SISTEMAS Dr. Ramón Zatarain Cabada
ELEMENTOS DEL CURSO ,[object Object],[object Object],[object Object],[object Object],[object Object]
Unidad I  Introducción a la Programación de Sistemas
1.1 ¿Qué es y que estudia la P. de S. ? ,[object Object],[object Object]
1.2 Herramientas desarrolladas con la P de S ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
1.3 Lenguajes ,[object Object],[object Object]
1.4 Traductor y su Estructura ,[object Object],[object Object],[object Object]
1.5 Generador de Código para Compiladores (Compilador de Compiladores) ,[object Object]
Unidad II Introducción al Diseño de Lenguajes de Programación
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Unidad III  Análisis de Léxico
3.1 Introducción a los Autómatas Finitos y Expresiones Regulares ,[object Object]
3.2 Analizador de Léxico . ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Analizador de Léxico (cont.) ,[object Object]
3.3 Manejo de “Buffers” ,[object Object],[object Object]
3.4 Creación de la Tabla de Símbolos. ,[object Object],[object Object]
Ejemplo ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
3.5 Manejo de Errores de Léxico ,[object Object],[object Object],[object Object],[object Object]
3.6 Generadores de Código Léxico ,[object Object],[object Object],[object Object]
Ejemplo: Javacc ,[object Object],[object Object],[object Object]
(cont.) Miparser.jj javacc Miparser.jj Miparser.java ParseException.java TokenMgrError.java otros archivos java javac Miparser.java Miparser.class java Miparser <inputfile mensajes USO DE JAVACC
(cont.) PARSER_BEGIN(PS1) class PS1 {} PARSER_END(PS1) /* Para la expresión regular de la derecha lo de la izquierda será retornado */ TOKEN: {   <IF: &quot;if&quot;> |<#DIGIT: [&quot;0&quot;-&quot;9&quot;]> |<ID: [&quot;a&quot;-&quot;z&quot;] ([&quot;a&quot;-&quot;z&quot;]|<DIGIT>)*> |<NUM: (<DIGIT>)+> |<REAL: ((<DIGIT>)+ &quot;.&quot; (<DIGIT>)*) | ((<DIGIT>)* &quot;.&quot; (<DIGIT>)+)> } SKIP: {   <&quot;--&quot; ([&quot;a&quot; - &quot;z&quot;])* (&quot;&quot; | &quot;&quot; | &quot;&quot;)> |&quot; &quot; |&quot;&quot; |&quot;&quot; |&quot;&quot; } void Start(): {} { (<IF> | <ID> | <NUM> | <REAL>)* } EJEMPLO DE ESPECIFICACION PARA GENERAR UN SCANNER
Unidad IV Análisis de Sintáxis
4.1 Introducción a las gramáticas Libres de Contexto y Árboles de derivación  ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object]
(cont.) S Id := E E + E id E + E id id S Id := E E + E E + E id Id id
(cont.) E E - E E - E 3 1 2 E E - E 1 E - E 2 3
4.2 Diagramas de Sintaxis ,[object Object],[object Object]
4.3 Precedencia de Operadores ,[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],X + ?Y   + ?U ?V   *   +
4.4 Analizador Sintáctico ,[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
4.4.1 Analizador descendente (LL). ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Programa del Parser Final int if = 1, then = 2, else = 3, begin = 4, end = 5, print = 6, semi = 7,  num = 8, EQ = 9  int tok = get token ( );  void advance ( ) { tok = get token ( ); }  void eat ( int t) { if ( tok == 1) advance ( ); else error ( ); }  void S ( ) { switch ( tok ) {  case If: eat ( if ); E ( ); eat ( then ); S ( );  eat ( else ); S ( ); break;  case begin: eat ( begin ); S ( ); L ( ); break;  case print: eat ( print ); E ( ); break;  default: error;   }} void L ( ) { switch ( tok ) {  case end: eat ( end ); break;  case semi: eat ( semi ); S ( ); L ( ); break;  default: error ( );  }} void E ( ) { eat ( num ); eat ( EQ ); eat ( num ); }
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Eliminación de Recursión por la izquierda ,[object Object],[object Object],[object Object],[object Object],Producciones como  E    E + T   contienen recursión por la izquierda. Parsers descendentes no pueden manejar recursión por la izquierda en una gramática. Para eliminar este tipo de recursión utilizamos la siguiente transformación:
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object]
Factorización por la izquierda ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
4.4.2 Analizador ascendente(LR y LALR). ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object]
Algoritmo de Parsing LR (aho,Sethi y Ullman) Tomar el primer token de w$  /* w es la cadena */ Repeat forever begin Sea s el estado en el tope de la pila y a el token actual; if  acción[s,a] = shift s’  then begin push a’ primero y sedpués s’ al tope de la pila; obten el siguiente token de la cadena de entrada else if  acción[s,a] = reduce A->B  then begin pop 2*|B| símbolos fuera de la pila; Sea s’ ahora el estado en el tope de la pila; Push A y después goto[s’,A] al tope de la pila; Imprime la producción A->B end else if  acción[s,a] = accept  then return else  error() end
Ejemplo: Parser LR(K) S4   s7   g2 s3    a S4   s7   g5   s6 r1  r1   r1 S20  s10 s8   g11 s9 S4   s7   g12   TABLA DE PARSING 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 id  num  print    ;  ,  +  :=  (  )  $  S  E  L S20  s10   g15  g14 r5  r5  r5  r5  r5 r2  r2  s16  r2  s3  s18  r3  r3  r3   s19  s13   r8   r8 S20  s10  s8   g17 r6  r6  s16   r6  r6 S20  s10 s8   g21 S20  s10 s8   g23 r4  r4  r4   r4  r4   s22 r7  r7  r7   r7  r7   r9  s16    r9
Ejemplo (cont.): PILA ENTRADA   ACCION ,[object Object],1  id4  := 7;B:=c+(d:=5+6,d)$  shift 1  id4 := 6  7;B:=c+(d:=5+6,d)$  shift 1  id4 := 6  num10  ;B:=c+(d:=5+6,d)$  reduce    E->num ,[object Object],[object Object],. . . . . . . $  accept 1  S2 . . . . . . . . . . . . . .
Parsing LALR ,[object Object],[object Object],[object Object],[object Object],[object Object]
  4.5 Administración de tablas de símbolos. ,[object Object],[object Object],[object Object]
4.6 Manejo de errores sintácticos y su recuperación. ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object]
Ejemplo: void S ( ) { switch ( tok ) {  case If: eat ( if ); E ( ); eat ( then ); S ( );  eat ( else ); S ( ); break;  case begin: eat ( begin ); S ( ); L ( ); break;  case print: eat ( print ); E ( ); break;  default:  print(“se esperaba if, begin o print”);   }} Un problema que puede ocurrir al insertar un token faltante es que el programa caiga en un ciclo infinito, por eso a veces es preferible y mas seguro borrar el token, ya que el ciclo terminará cuando el EOF sea encontrado. Esta técnica trabaja muy cercanamente con la tabla de parsing (cuando el parser se implementa con tablas).  En un parser del tipo LR o LALR, la tabla de parsing tiene 4 acciones: shift, reduce, accept y error (entrada nula). Cuando el parser encuentra una acción  error , se para el proceso de análisis y se reporta la falla.
4.7 Generadores de código para analizadores sintácticos ,[object Object],[object Object],[object Object],[object Object]
Ejemplo: gramática para estatutos “begin”, “if” y “print” PARSER_BEGIN(MiniParser) public class MiniParser { public static void main(String[] args) { MiniParser parser; try { // RGC: added line   if( args.length == 0 )  parser = new MiniParser(System.in); // RGC: added lines   else parser= new MiniParser ( new java.io.FileInputStream( args[0] ) ); } // RGC: End   parser.Program(); } catch (ParseException e) {   System.out.println(e.getMessage()); } //RGC: added lines   catch( Exception e ) {   System.out.println(e.getMessage()); }  //RGC :End } } PARSER_END(MiniParser) SKIP : { &quot; &quot; | &quot;&quot; | &quot;&quot; | &quot;&quot; }
(cont. Ejemplo) TOKEN : { <INT: &quot;INT&quot;> | <IF: &quot;if&quot;> | <THEN: &quot;then&quot;> | <ELSE: &quot;else&quot;> | <BEGIN: &quot;begin&quot;> | <PRINT: &quot;print&quot;> | <END: &quot;end&quot;> | <SEMI: &quot;;&quot;> | <EQUAL: &quot;=&quot;> | <ID: ([&quot;a&quot;-&quot;z&quot;]|[&quot;A&quot;-&quot;Z&quot;]) ([&quot;a&quot;-&quot;z&quot;]|[&quot;A&quot;-&quot;Z&quot;]|[&quot;0&quot;-&quot;9&quot;])* > } void Program() : {} {  S()  <EOF> } void S() : {} {  <BEGIN> S() L() | <PRINT> E() | LOOKAHEAD(12)  &quot;if&quot; E() &quot;then&quot; S() &quot;else&quot; S() | &quot;if&quot; E() &quot;then&quot; S()  } void L() : {} { <END> | <SEMI> S() L() } void E() : {} { <ID> <EQUAL> <ID> }
Unidad V Análisis Semántico
5.1 Analizador semántico ,[object Object],[object Object],[object Object],[object Object]
5.2 Verificación de tipos en expresiones. ,[object Object],[object Object],[object Object]
5.3 Conversión de tipos. ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],5.4 Acciones agregadas en  un Analizador  sintáctico descendente (top-down).
(cont.) ,[object Object],[object Object],[object Object]
Recursivo-descendente ,[object Object],[object Object],[object Object]
(cont.) S    E$ E    T E’ E’    + T E’ E’    - T E’ E’      T    F T’ T’    * F T’ T’    / F T’ T’      F    id F    num F    (E) Los tokens  ID  y  NUM  deben ahora acarrear valores de tipo  string  e  int , respectivamente. Asumiremos que existe una tabla “lookup” que mapea identificadores a enteros. El tipo asociado con E, T, F, etc., es int, y la acción semántica es fácil de implementar.
Interprete class Token2 { int kind; Object val; Token2(int k, Object v) {   kind=k;   val=v; } } final int EOF=0, ID=1, NUM=2, PLUS=3,  MINUS=4,LPAREN=5, RPAREN=6, TIMES=7; int lookup(String id) {  …. } int F_follow[] = {PLUS,TIMES,RPAREN,EOF}; int F() {switch(tok.kind) { case ID:  int i=lookup((String)(tok.val));advance()return i ; case NUM:  int i=((integer)(tok.val)).intVal(); advance(); return i ; case LPAREN: eat(LPAREN); int i=E(); eatOrSkipTo(RPAREN,F_follow); return i ; case EOF: default: print(&quot;1 esperaba ID,NUM, o parent izq&quot;); //skipto(F_follow); return 0; }} int T_follow[]= {PLUS,RPAREN,EOF}; int T() {switch(tok.kind) { case ID: case NUM: case LPAREN:  return Tprime(F()); default: print(&quot;2 esperaba ID, NUM o parent izq&quot;); //skipto(T_follow); return 0; }} int Tprime(int a) {switch (tok.kind) { case TIMES: eat(TIMES);  return Tprime(a*F()); case PLUS: case RPAREN: case EOF:  return a ; default: print(&quot;3 esperaba ID, NUM o parent izq&quot;); //skipto(T_follow); return 0; }} void eatOrSkipTo(int expected, int[] stop) { if (tok.kind==expected) eat(expected); else {print(&quot;4 esperaba ID, NUM o parent izq&quot;); //skipto(stop);} } Acciones semánticas
Parser Automáticamente generado ,[object Object],[object Object],void Start(): { int i; } { i=Exp() <EOF>  {System.Out.println(i);} } Int Exp(): { int a,i; } { a=Term() ( “+” i=Term()  {a=a+i;} | “-”  i=Term()  {a=a-i;} )* {  return a;  } } Int Term(): { int a,i; } { a=factor() ( “*” i=Factor()  { a=a*i;} | “/”  i=Factor()  {a=a/i;} )* {  return a; } } Int Factor(): { Token t; int i; } { t=<IDENTIFIER>  { return lookup(t.image); } | t=<INTEGER_LITERAL>  {return Integer.parseInt(t.image); } | “(“ i=Exp() “)”  {return i; } }
Árboles de Parsing Abstractos ,[object Object],[object Object],[object Object],If-then-else B S1 S2 En un árbol sintáctico, los operadores y las palabras claves (reservadas) no aparecen como hojas, sino que están asociadas con el nodo interior que sería el padre de esas hojas en el arbol de parsing. Est-if If  Exp  (  Exp  )  Est Árbol De parsing Árbol sintáctico
(cont.) ,[object Object],Cuyo árbol sintáctico abstracto sería: + * 8 2 4   L E + T T * F  F F 4 8 2
Ejemplo: ,[object Object],[object Object],[object Object],[object Object],[object Object]
Árboles de Sintaxis en Java ,[object Object]
Programa de clases para Exp public abstract class ExpCh4 { public abstract int eval(); } class PlusExp extends ExpCh4 { private ExpCh4 e1,e2; public PlusExp(ExpCh4 a1, ExpCh4 a2)   {e1=a1; e2=a2;} public int eval() { return e1.eval()+e2.eval(); } } class MinusExp extends ExpCh4 { private ExpCh4 e1,e2; public MinusExp(ExpCh4 a1, ExpCh4 a2)   {e1=a1; e2=a2;} public int eval() { return e1.eval()-e2.eval(); } } class TimesExp extends ExpCh4 { private ExpCh4 e1,e2; public TimesExp(ExpCh4 a1, ExpCh4 a2)   {e1=a1; e2=a2;} public int eval() { return e1.eval()*e2.eval(); } } class DivideExp extends ExpCh4 { private ExpCh4 e1,e2; public DivideExp(ExpCh4 a1, ExpCh4 a2)   {e1=a1; e2=a2;} public int eval() { return e1.eval()/e2.eval(); } } class Identifier extends ExpCh4 { private String f0; public Identifier(String n0) {f0=n0;} public int eval() { return (7);  //return lookup(f0); } } class IntegerLiteral extends ExpCh4 { private String f0; public IntegerLiteral(String n0) {f0=n0;} public int eval() { return (4);    //return Integer.parseInt(f0); } }
(cont.) ,[object Object],S    E$ E    T E ’ E’    + T E’ E’    - T E’ E’      T    F T’ T’    * F T’ T’    / F T’ T’      F    id F    num F    (E) ,[object Object]
Gramática con acciones semánticas para árboles sintácticos PARSER_BEGIN(InterSinTree) class InterSinTree {} PARSER_END(InterSinTree) TOKEN: {   <#DIGIT: [&quot;0&quot;-&quot;9&quot;]> |<ID: [&quot;a&quot;-&quot;z&quot;] ([&quot;a&quot;-&quot;z&quot;]|<DIGIT>)*> |<INTEGER_LITERAL: (<DIGIT>)+> } SKIP: {   <&quot;--&quot; ([&quot;a&quot; - &quot;z&quot;])* (&quot;&quot; | &quot;&quot; | &quot;&quot;)> |&quot; &quot; |&quot;&quot; |&quot;&quot; |&quot;&quot; } ExpCh4 Start(): { ExpCh4 e; } { e=Exp() <EOF>  {System.out.println(e.eval()); return e; } } ExpCh4 Exp(): { ExpCh4 e1,e2; } { e1=Term()   (&quot;+&quot; e2=Term() { e1=new PlusExp(e1,e2);}   |&quot;-&quot; e2=Term() { e1=new MinusExp(e1,e2);}   )*   { return e1;} } ExpCh4 Term(): { ExpCh4 e1,e2; } { e1=Factor()   (&quot;*&quot; e2=Factor() { e1=new TimesExp(e1,e2);}   |&quot;/&quot; e2=Factor() { e1=new DivideExp(e1,e2);}   )*   { return e1;} } ExpCh4 Factor() : { Token t; ExpCh4 e; } { (t=<ID> {return new Identifier(t.image); } |   t=<INTEGER_LITERAL> {return new IntegerLiteral(t.image); } |   &quot;(&quot; e=Exp() &quot;)&quot; {return e; }) }
VISITADORES ,[object Object]
(cont.) ,[object Object]
Sintáxis Abstracta para MiniJava ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Package syntaxtree; Program (MainClass m, ClassDeclList cl) MainClass (Identifier i1, Identifier i2, Statement s) Abstract class ClassDecl ClassDeclSimple (Identifier i, VarDeclList vl, MethodDeclList ml) ClassDeclExtends (Identifier i, identifier j, VarDeclList vl, MethodDeclList ml) VarDecl (Type t, Identifier i) MethodDecl (Type t, Identifier i, FormalList fl, VarDeclList vl, StatementList, Exp e) Formal (Type t, Identifier i) Abstract class Type IntArrayType () BooleanType () IntegerType () IdentifierType (String s) Abstract class Statement Block (StatementList sl) If (Exp e, Statement s1, Statement s2) While (Exp e, Statement s) Print (Exp e) Assign (Identifier i, Exp e) ArrayAssign (Identifier i, Exp e1, Exp e2)
(cont. figura) Abstract class Exp And (Exp e1, Exp e2) LessTha n(Exp e1, Exp e2) Plus (Exp e1, Exp e2) Minu s(Exp e1, Exp e2) Times (Exp e1, Exp e2) ArrayLoockup (Exp e1, Exp e2) ArrayLength (Exp e) Call (Exp e, Identifier i, ExpList el) IntegerLiteral (int i) True () False () IdentifierExp (String s) This () NewArray (Exp e) NewObject (Identifier i) Not (Exp e) Identifier (String s) List classes ClassDeclList () ExpList () FormalList () MethodDeclList () StatementList () VarDeclList ()
Arbol Sintáctico ,[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Visitador MiniJava
(cont. Arbol Sintáctico) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
5.5 Pila semántica en un analizador sintáctico ascendente (bottom-up). ,[object Object],[object Object],[object Object],[object Object]
5.6 Administración de la tabla de símbolos ,[object Object],[object Object],[object Object]
(cont.) ,[object Object]
Ejemplo: ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Suponer que compilamos esta clase en el ambiente  z0 . Las declaraciones de campo en línea 2 nos da la tabla  z1  igual a  z0  + {a  int,b  int,c  int}. Los identificadores en línea 4 pueden encontrarse (look up) en ambiente  z1 . En línea 5, la tabla o ambiente  z2 = z1 +{j  int} es creada; y en línea 6,  z3 = z2 +{a  string} es creada.
Implementación de la Tabla ,[object Object]
Múltiple Tablas de Símbolos ,[object Object],Structure M = struct structure E = struct val a= 5; end structure N = struct val b=10 val a=E.a+b end structure D = struct val d=E.a+N.a end end Package M; class E { static int a=5; } Class N { static int b=10; static int a=E.a+b; } Class D { static int d=E.a+N.a; }
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object]
TABLAS DE SIMBOLOS EN LENGUAJES IMPERATIVOS ,[object Object],[object Object]
(cont.) ,[object Object]
SIMBOLOS ,[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object]
Chequeo de Tipos en MiniJava ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],Class B { C f; int [ ] j; int q; public int start(int p, int q) { int ret;  int a; /* ……  */ return ret; } public boolean stop(int p) { /*  ….. */ return false; } } Class C { /* ….*/ } B C FIELDS f C j int [ ] q int METHODS start int stop bool PARAMS p int q int LOCALS ret int a int PARAMS p int LOCALS ……
(cont.) ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object]
Método Visitador Class ErrorMsg { boolean anyErrors; void complain (String msg) { anyErrors = true; System.out.println(msg); } } // Type t; // Identifier i; Public void visit(VarDecl n) { Type t = n.t.accept(this); String id= n.i.toString(); if (currMethod ==null) { if (!currClass.addVar(id,t)) error.complain(id + “is already defined in “ + currClass.getId()); } else if (!currentMethod.addVar(id,t)) error.Complain(id + “is already defined in “ + currClass.getId( ) + “.” + currMethod.getId( ));
(cont.) ,[object Object],[object Object],[object Object],[object Object]
Método Visitador para expresiones Plus // Exp e1, e2; Public Type visit(Plus n) { if (! (n.e1.accept(this) instanceOf IntegerType) ) error.complain(“Left side of LessThan must be of type integer”); if (! (n.e2.accept(this) instanceOf IntegerType) ) error.complain(“Right side of LessThan must be of type integer”); return new IntegerType( ); }
5.7 Manejo de errores semánticos. ,[object Object],[object Object],[object Object],[object Object],[object Object]
REGISTROS DE ACTIVACION ,[object Object],[object Object]
(cont.) ,[object Object],Int f(int x) { int y= x+x; if (y<10) return f(y); else  return y-1; Una nueva instancia de  x  es creada (e inicializada por el llamador de “f”) cada vez que “f” es llamada. Debido a que existen llamadas recursivas, muchas de esas  x  existen simultáneamente. Similarmente, una nueva instancia de y es creada cada vez que el cuerpo f es iniciado.
(cont.) ,[object Object]
MARCOS DE PILA ,[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object]
Ejemplo: Un marco de pila Argumentos de entrada Apuntador Del marco Argumentos De salida Apuntador De pila Argumento  n … … Argumento 1 Liga estática Argumento m … … Argumento 1 Liga estática Variables  locales Dirección retorno Temporales Registros salvados Marco actual Marco anterior Marco siguiente Direcciones de Memoria mas altas
Marco de Pila ,[object Object],[object Object],[object Object],[object Object],[object Object]
El Apuntador de Marco (FP) ,[object Object],[object Object],[object Object],[object Object]
Registros ,[object Object],[object Object],[object Object]
Pase de Parámetros ,[object Object],[object Object]
Direcciones de Retorno ,[object Object],[object Object],[object Object]
Registros vs. Memoria ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Ligas Estáticas (Static Links) ,[object Object],[object Object]
Programa de funciones Anidadas Type tree= {key: string, left: tree, right: tree} Function prettyprint(tree:tree): string= let var output := “ “ function write(s:string) = output :=concat(output,s) function show(n:int, t:tree) = let function indent(s:string)= (for i:= 1 to n do write(“ “); output:=concat(output,s);write(“ “); in if t=nil then indent(“.”) else (indent(t.key); show(n+1,t.left);   show(n+1,t.right)) end in show(0,tree); output end
Ligas Estáticas (cont.) ,[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Unidad VI Generación de Código Intermedio
6.1 Lenguajes intermedios. ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object]
6.2 Notaciones. ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
6.3 Representación de código intermedio. ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Notación Polaca ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Código P ,[object Object],[object Object],[object Object],[object Object]
Ejemplo: ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Triples y Cuadruplos (Código de 3 Direcciones) ,[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Java Bytecodes ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object]
(cont.) ,[object Object],[object Object],[object Object],[object Object]
La Máquina Virtual de Java  (JVM) ,[object Object]
Árboles de Ensamblador ,[object Object],[object Object],[object Object]
Implementación de variables ,[object Object],[object Object],[object Object],[object Object]
Por ejemplo, la función: Int foo() { int a; int b; /* body of foo */ } FP SP Tendría el registro de activación Existen dos apuntadores. FP que apunta al inicio del RA actual y SP que apunta a la primera localidad vacía. El valor retornado de una función es puesto en un registro especial en lugar de la pila. Cuando una función es llamada los valores de los parámetros de entrada son puestos en la pila, y cuando la función retorna un valor, el valor es almacenado en el registro de resultado. Registros  salvados b a
(cont.) ,[object Object],[object Object]
Formato completo de RA FP SP Previous Activation Record Current Activation Record Saved Registers Local Variables Input Parameter 1 Input Parameter 2 … Input Parameter n
Considere el siguiente programa: void foo(int a, int b); void foo(int c, int d); void main() { int u; int v;  /* Label A */ bar(1,2); } void bar(int a, int b) { int w; int x; foo(3,4); } void foo(int c, int d) { int y; int z; /* Label B */ }
En  label A  de el programa, la pila de RA se miraría de la forma siguiente FP SP Activation Record for main La variable local  u  puede accesarse examinando la localidad de memoria apuntada por FP. La variable  v  puede accesarse examinando (FP-wordsize). Algo para aclarar es que la pila crece de direcciones altas a bajas. Saved Registers v u
En etiqueta B los RA se mirarían así: FP SP Activation Record for main Activation Record for bar Activation Record for foo Saved Registers z y c d Saved Registers x w a b Saved Registers v u
(cont.) ,[object Object],[object Object]
Ensamblador Abstracto ,[object Object],[object Object],[object Object],[object Object],[object Object]
(cont.) ,[object Object],Constant(3) Constant(5) El ensamblador abstracto en este caso no contiene instrucciones  explícitas para asignar los parámetros actuales a la pila. Cuando se tradusca el ensamblador abstracto de una callExpression a ensamblador real, se incluye el código para hacer la copia de los parámetros actuales a la pila. CallExpresion(“foo”) Constant(4)
[object Object],[object Object],Casi nunca se manejan direcciones absolutas sino que estas son relativas al FP.  Por ejemplo para referirse a la localidad de memoria de una variable local con un desplazamiento (oofset) de 4 del FP es representado con el árbol: Memory Constant(1006) Memory Operator(-) Register(FP) Constant(4)
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Ejemplos: (asumiremos que wordsize=4 y que un entero se guarda en una palabra) void foo(int a, int b) { int x; int y; boolean z; x = 1; y = a * b; y++; bar(y, x + 1, a); x = function(y+1, 3); if (x > 2) z = true; else  z = false; }
X=1; Move Memory Constant(1) Register(FP)
y = a * b; Move Memory Operator (-) Register(FP) Constant(4) Operator(*) Memory Memory Operator (+) Operator (+) Register(FP) Constant(4) Register(FP) Constant(8)
Y++; Move Memory Operator (-) Constant(4) Operator(+) Memory Constant(1) Operator (-) Register(FP) Constant(4) Register(FP)
bar(y,x+1,a); CallStatement(“bar”) Memory Operator (-) Constant(4) Register(FP) Operator (+) Memory Constant(1) Register(FP) Memory Operator (+) Constant(4) Register(FP)
x=function(y+1,3); Move Memory Register(FP) Callexpression(“function”) Constant(3) Constant(1) Operator(+) Memory Operator(-) Register(FP) Constant(4)
if (x > 2) z = true; else z = false; Sequential ConditionalJump(“iftrue”) Operator(>) Memory Constant(2) Sequential Sequential Sequential Sequential Label(“ifend”) Jump(“ifend”) Label(“iftrue”) Move Move Constant(0) Memory Operator(-) Register(FP) Constant(8) Constant(1) Memory Operator(-) Register(FP) Constant(8) Register(FP)
Creación de Ensamblador Abstracto ,[object Object],[object Object],[object Object],void foo() { int x; int y;  /* Body of foo */ }  Memory Register(FP) Memory Operator(-) Register(FP) Constant(4)
[object Object],[object Object],void foo arrayallocation() { int x; int A[]; int B[]; A = new int [5]; B = new int [5]; /* Body of function */ }
La variable local x es almacenada en la pila, igual que la dirección base del arreglo A y del arreglo B. Stack Heap x A B FP SP A[0] A[1] A[2] A[3] A[4] B[0] B[1] B[2] B[3] B[4] Saved Registers
¿Cómo debemos representar el arreglo A[3] Register(FP) Memory Operator(-) Memory Operator(*) Operator(-) Constant(WORDSIZE) Constant(WORDSIZE) Constant(3)
¿ Y A[x] ? Memory Operator(-) Memory Operator(*) Operator(-) Register(FP) Constant(WORDSIZE) Constant(WORDSIZE) Memory Register(FP)
¿ Y para A[B[2]] ? Memory Operator(-) Memory Operator(*) Operator(-) Register(FP) Constant(WORDSIZE) Constant(WORDSIZE) Memory Operator(-) Memory Operator(-) Register(FP) Constant(2*WORDSIZE) Operator(*) Constant(WORDSIZE) Constant(2)
Arreglos Multidimensionales se manejan de manera similar. Ejemplo: void twoDarray { int i; int c [ ] [ ] ; C = new int [3] [ ] ; for (i=0; i<3; i++) C[i] = new int[2] ; /* Body of function */ }
El RA y el Heap se ven así: Stack Heap C[0] C[1] C[2] C[0] [0] C[0] [1] C[1] [0] C[1] [1] C[2] [0] C[2] [1] i C FP SP Saved Registers
La variable C sería representada así: Memory Operator(-) Register(FP) Constant(WORDSIZE)
La variable C[2] así: Memory Operator(-) Memory Operator(*) Operator(-) Register(FP) Constant(WORDSIZE) Constant(WORDSIZE) Constant(2)
La variable c[2] [1]  Memory Operator(-) Memory Operator(*) Operator(-) Memory Operator(*) Constant(WORDSIZE) Constant(1) Operator(-) Register(FP) Constant(WORDSIZE) Constant(2) Constant(WORDSIZE)
Variables Instanciadas Son muy similares a las variables arreglo. La única diferencia es que en las variables arreglo, el desplazamiento para el índice necesita ser calculado, mientras que en las variables instanciadas, el desplazamiento es conocido en tiempo de compilación. Ejemplo: class simpleClass { int x; int y; int A[ ]; } void main() { simpleClass(); s = new simpleClass(); s.A = new int[3] /* Body of main */ }
¿Cuál es el árbol de ensamblador para s.y ? Memory Register(FP) Él árbol de  s : Para obtener  y  de  s : Memory Memory Operator(-) Constant(WORDSIZE) Register(FP)
El árbol de la variable s.x: Memory Memory Register(FP) El árbol para  .A[3]: Memory Operator(-) Memory Operator(*) Operator(-) Memory Constant(2*WORDSIZE) Constant(WORDSIZE) Constant(3) Register(FP)
Estatutos ,[object Object],[object Object],[object Object],Move <variable> <expression>
Ejemplo: Void main() { int x; int y;  y = x + 4; }  Move Memory Operator(+) Operator(-) Constant(4) Memory Register(FP) Register(FP) Constant(4)
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Y se representa con el árbol: Sequential ConditionalJump(“iftrue”) <test> Sequential  Sequential Sequential Sequential Label(“ifend”) Jump(“ifend”) Label(“iftrue”) <statement1> <statement2>
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object],for (<initialize>;<test>;<increment>) <estatement> es equivalent a: <initialize> while (<test>) { <statement> <increment> } Entonces queda como: <initialize> goto FORTEST FORSTART: <statement> FORTEST: <if (<test>) goto FORSTART
[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],El código ensamblador queda así: <Etiqueta de inicio de el método> <Código para asignar o meter el registro de activación> <cuerpo de la función> <Etiqueta del fin de método> <Código para sacar el registro de activación> <return>
Creación de Árboles de Ensamblador Abstracto (AAT) en Java ,[object Object],[object Object],[object Object]
Etiquetas Se necesitan tanto para las llamadas a métodos como para los “if” y los ciclos “while” y “for”. La siguiente clase nos genera etiquetas únicas (ifEnd001,ifEnd02,etc.) y etiquetas específicas (llamadas a métodos). import  java.util.Hashtable;   class Label { protected String label; private static HashTable labelhash; Integer last; Int next; public Label(String s) { if (labelhash == null) { labelhash = new HashTable(199); } last  = (Integer) labelhash.find(s); If (last == null) { next = 1; labelhash.insert(s, new Integer(1)); label = s + 1; }  else { next = last.intValue() + 1; labelhash.delete(s); labelhash.insert(s, new Integer(next)); label = s + next; } } public static Label AbsLabel(String s) { Label abslab = new Label(); abslab.label = s; return abslab; } public String toString() { return label; }
Interfase para Construir Árboles de Ensamblador Abstracto import java.util.Vector; public interface AATBuildTree { public AATSatement functionDefinition(AATStatemen body, int framesize, Label start, Label end); public AATSatement ifStatement(AATExpression test, AATStatement ifbody, AATStatement elsebody); public AATEexpression allocate(AATExpression size); public AATStatement whileStatement(AATExpression test, AATStatement increment, AATStatemen body); public AATStatement emptyStatement( ) ; public AATStatement callStatement(Vector actuals, Label name); public AATStatement assignmentStatement(AATExpression lhs, AATExpressionrhs); public AATStatement sequentialStatement(AATStatement first, AATStatement second); public AATExpression baseVariable(int offset); public AATExpression arrayVariable(AATExpresion base, AATExpression index, int elementSiza); public AATExpression classVariable(AATExpression(AATExpression base, int, offset); public AATExpression constantExpression(int, value); public AATExpression operatorExpression(AATExpression left, AATExpression rigth, int operator); public AATExpression callExpression(Vector actuals, Label name); public AATStatement returnStatement(AATExpression value, Label functioned); }
EJEMPLOS: void foo(int a) { int b; int c; if (a > 2) b = 2; else c = a+ 1; }  Sea  bt  una instancia de una clase que implementa la interfase AATBuildTree, y sea  4  el tamaño de la palabra de la máquina. El árbol de ensamblador abstracto para la expresión (a > 2) en la función  foo  podría crearse con: AATExpression e1; e1 = bt.operatorExpression(bt.baseVariable(4), bt.constantExpression/(2), AATOperator.GREATER_THAN);
Igual, el ensamblador abstracto para el estatuto  b = 2;  y  c = a + 1 , puede crearse con: AATEstatement  s1, s2; s1 = bt.assignmentStatemen(bt.baseVariable(0), bt.constantExpression(2)); s2 = bt.assignment(bt.BaseVariable(-4), bt.operatorExpression(bt.baseVariable(4), bt.constantExpression(1), AATOperator.PLUS)); Finalmente, dadas las definiciones anteriores, el ensamblador abstracto para el estatuto  if (a > 2) b = 2 else c = a + 1;  puede crearse con: AATstatement  s3; s3 = bt.ifStatement(e1,s1,s2);
[object Object],[object Object],[object Object],Algunas de las funciones para construír árboles de ensamblador abstracto pueden explicarse mejor:
Modificaciones al Analizador Semántico ,[object Object],[object Object]
Ejemplo: Para analizar un AST: Integer_Literal(3) El analizador semántico actualmente retorna  IntegerType .  Para analizar el AST: + Integer_Literal(3)  Integer_Literal(4) El analizador semántico llama al método accept para cada subárbol – constant(3) y constant(4), se asegura que ambos sean enteros, y retorne un entero. Después de modificar el  analizador semántico para producir AATs, cunado se analiza el AST: Integer_Literal(3) El analizador retornará dos valores: Integer_Type y bt.constantExpression(3).
Cuando se analiza el AST: + Integer_Literal(3)  Integer_Literal(4) Primero se llama el método  accept  de los subárboles, se asegura que los tipos sean enteros y entonces construye una expresión operador basado en los valores de los subárboles (usando una llamada al método  operatorExpression  en la interfase  AATBuildTree ).
VIII Generación de Código ,[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object]
Código Ensamblador Objeto Usaremos un subconjunto del ensamblador para MIPS if  rs  ≥ 0, jump to the label <target> Bgez rs, <target> if rs < 0, jump to the label <target>  bltz rs, <target>  if rs  ≠  rt, jump to the label <target>  bne rs, rt, <target>  if rs == rt, jump to the label <target>  beq rs, rt, <target>  if rs < rt, rd = 1, else rd = 0 slt rd, rs, rt  Jump to the address stored in register rs. Used in conjunction with jal to return from function and procedure calls jr rs  jump and link. Put the address of the next instruction in the return register, and then jump  to the address <target>. Used for function and procedure calls. jal <target>  Jump to the assembly label <target>. j <target>  Move contents of the special register LOW into the register rd. mflo rd Dive contents of register rs by register rt, put the quotient in register LO and the remainder in register HI div rs, rt  Multiply contents of register rs by register rt, put the low order bits in register LO and the high bits in register HI mult rs, rt  Add the constant value <val> to register rs, put result in register rt. addi rt, rs, <val>  Subtract contents of register rt from rs, put result in register rd. sub rd, rs, rt  Add contents of register rs and rt, put result in register rd. add rd, rs, rt  Add the constant value <offset> to the register base to get an address. Store the contents of rt into this address. M[base + <offset>] = rt sw rt, <offset> (base) Add the constant value <offset> to the register base to get an address. Load the contents of this address into the register rt. Rt = M[base + <offset>]  Description lw rt, <offset> (base) Instruction
Register  that we will use for code generation General Purpose Register $t3 $t3 General Purpose Register $t2 $t2 General Purpose Register $t1 $t1 Accumulator Register – Used for expressioncalculation $t0 $ACC Zero register – This register always has the value 0 $zero $zero Result Register – Holds the return address for the current function  $ra $return Result Register – Holds the return value for functions $v0 $result Expression Stack Pointer – The next expression stack holds temporary values for expression avaluations $esp $ESP  Stack Pointer – Used for the activation record stack $sp $SP  Frame pointer – points to the top of the current activation record Description  $fp  SPIM Name $FP Mnemonic Name
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Tiling  Simple
Ejemplos: Tiling Simple para Árboles de Expresiones . El código asociado con el tile colocará el valor de la expresión en el tope de la pila de expresiones. Expresiones de Constantes Considere el siguiente árbol: Constant(5) El código asociado con este tile necesita poner un 5 en el tope de la pila de expresiones.  addi $t1, $zero, 5 % Load the constant value 5 into the register $t1 sw  $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer En general, el tile para cualquier valor constante x es: addi $t1, $zero, x % Load the constant value into x the register $t1 sw  $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer
Operaciones de Aritmética Binaria + Constant(3) Constant(4) En lugar de tratar de cubrir todo el árbol con un tile, usaremos tres. La constante 4 y 5 pueden cubrirse cada una con un tile de constante, y usaremos un tile “ +”  para cubrir la suma. + Constant(3) Constant(4)
¿Cómo debe ser el código para +?  Recordemos que emitimos código en post-order (subárbol izquierdo, subárbol derecho y luego raíz).  Podemos asumir que los valores de los operandos de la izquierda y la derecha de el + ya están en la pila cuando el código de el tile + es emitido. Ntonces, todo lo que necesitamos es hacer es sacar (pop off) esos valores , hacer la suma y meter (push) el resultado de regreso a la pila. El código para el tile + es: lw  $t1, 8(ESP) % Load the first operand into temporary $t1  lw  $t2, 4(ESP) % Load the second operand into temporary $t2 add $t1, $t1, $t2 % Do the addition. Storing result in $t1 sw  $t1, 8(ESP) % Store the result on the expression stack add $ESP, $ESP, 4 % Update the expression stack pointer
y el código para toda la expresión es: addi $t1, $zero, 3 % Load the constant value 3 into the register $t1  sw  $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer addi $t1, $zero, 4 % Load the constant value into 4 the register $t1 sw  $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 %Update the expression stack pointer lw  $t1, 8($ESP) % Load the first operand into temporary $t1 lw  $t2, 4($ESP) % Load the second operand into temporary $t2 add  $t1, $t1, $t2 % Do the addtion, storing result in $t1 sw  $t1, 8(ESP) % Update the expression stack pointer
Registros Considere el árbol de expresión Register(FP) Esto ocupa un tile.  sw  $FP,  0($ESP) addi  $ESP, ESP, -4   Combinando otros tiles discutidos antes, el árbol - Register(FP) Constant(8) Puede ser los tiles:  - Register(FP) Constant(8)
Produciendo el árbol sw  $FP, 0($ESP) % Store frame pointer on the top of the expression stack  addi $ESP, $ESP, -4 % Update the expression stack pointer  addi $t1, $zero, 8 % Load the constant value 8 into the register $t1 sw  $t1, 0($esp) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4  % Update the expression stack pointer lw  $t1, 8($ESP) % Load the first operand into temporary $t1
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist
Curso prog sist

Más contenido relacionado

La actualidad más candente

Compiladores y analizador léxico
Compiladores y analizador léxicoCompiladores y analizador léxico
Compiladores y analizador léxicokatherine133
 
Cap4
Cap4Cap4
Cap4CJAO
 
DiseñO De Compilador
DiseñO De CompiladorDiseñO De Compilador
DiseñO De CompiladorBigbossH
 
Cap1 compiladores
Cap1 compiladoresCap1 compiladores
Cap1 compiladoresCJAO
 
Análisis léxico y análisis sintáctico
Análisis léxico y análisis sintácticoAnálisis léxico y análisis sintáctico
Análisis léxico y análisis sintácticoangiepao1717
 
Analizador Sintáctico
Analizador SintácticoAnalizador Sintáctico
Analizador SintácticoPablo Guerra
 
Clase3 guia1-introduccion-compiladores-conceptos
Clase3 guia1-introduccion-compiladores-conceptosClase3 guia1-introduccion-compiladores-conceptos
Clase3 guia1-introduccion-compiladores-conceptosInfomania pro
 
Automatas y compiladores analisis sintactico
Automatas y compiladores analisis sintacticoAutomatas y compiladores analisis sintactico
Automatas y compiladores analisis sintacticoGermania Rodriguez
 
Introducción a Compiladores
Introducción a  CompiladoresIntroducción a  Compiladores
Introducción a CompiladoresLeopoldo Capa
 
Clase6 conceptos del analisis lexico
Clase6 conceptos del analisis lexicoClase6 conceptos del analisis lexico
Clase6 conceptos del analisis lexicoInfomania pro
 
Analizador sintactico
Analizador sintacticoAnalizador sintactico
Analizador sintacticoalexisdario
 
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS Infomania pro
 
Estructura de un compilador 2
Estructura de un compilador 2Estructura de un compilador 2
Estructura de un compilador 2perlallamas
 
Clase6 ejemplo analisis lexico dev cpp
Clase6 ejemplo analisis lexico dev cppClase6 ejemplo analisis lexico dev cpp
Clase6 ejemplo analisis lexico dev cppInfomania pro
 
Proceso de Compilacion
Proceso de CompilacionProceso de Compilacion
Proceso de Compilacionguest9a91e2
 
Analizador Sintactico
Analizador SintacticoAnalizador Sintactico
Analizador SintacticoBayo Chicaiza
 
Clase analisis lexico
Clase analisis lexicoClase analisis lexico
Clase analisis lexicoInfomania pro
 

La actualidad más candente (20)

Compiladores y analizador léxico
Compiladores y analizador léxicoCompiladores y analizador léxico
Compiladores y analizador léxico
 
Cap4
Cap4Cap4
Cap4
 
DiseñO De Compilador
DiseñO De CompiladorDiseñO De Compilador
DiseñO De Compilador
 
Cap1 compiladores
Cap1 compiladoresCap1 compiladores
Cap1 compiladores
 
Análisis léxico y análisis sintáctico
Análisis léxico y análisis sintácticoAnálisis léxico y análisis sintáctico
Análisis léxico y análisis sintáctico
 
Compiladores
CompiladoresCompiladores
Compiladores
 
Analizador Sintáctico
Analizador SintácticoAnalizador Sintáctico
Analizador Sintáctico
 
Clase3 guia1-introduccion-compiladores-conceptos
Clase3 guia1-introduccion-compiladores-conceptosClase3 guia1-introduccion-compiladores-conceptos
Clase3 guia1-introduccion-compiladores-conceptos
 
Automatas y compiladores analisis sintactico
Automatas y compiladores analisis sintacticoAutomatas y compiladores analisis sintactico
Automatas y compiladores analisis sintactico
 
Introducción a Compiladores
Introducción a  CompiladoresIntroducción a  Compiladores
Introducción a Compiladores
 
Clase6 conceptos del analisis lexico
Clase6 conceptos del analisis lexicoClase6 conceptos del analisis lexico
Clase6 conceptos del analisis lexico
 
Analizador sintactico
Analizador sintacticoAnalizador sintactico
Analizador sintactico
 
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
 
Estructura de un compilador 2
Estructura de un compilador 2Estructura de un compilador 2
Estructura de un compilador 2
 
Clase6 ejemplo analisis lexico dev cpp
Clase6 ejemplo analisis lexico dev cppClase6 ejemplo analisis lexico dev cpp
Clase6 ejemplo analisis lexico dev cpp
 
Proceso de Compilacion
Proceso de CompilacionProceso de Compilacion
Proceso de Compilacion
 
Compilador
CompiladorCompilador
Compilador
 
Analizador Sintactico
Analizador SintacticoAnalizador Sintactico
Analizador Sintactico
 
Clase analisis lexico
Clase analisis lexicoClase analisis lexico
Clase analisis lexico
 
TALLER FLEX Y BISON
TALLER FLEX Y BISONTALLER FLEX Y BISON
TALLER FLEX Y BISON
 

Similar a Curso prog sist

Compiladores unidad1
Compiladores unidad1Compiladores unidad1
Compiladores unidad1X3025990
 
Taller 21 de junio
Taller 21 de junioTaller 21 de junio
Taller 21 de junioAlex Ortiz
 
Introducción A Compiladores
Introducción A Compiladores Introducción A Compiladores
Introducción A Compiladores Nestor Traña
 
Taller flex y bison
Taller flex y bisonTaller flex y bison
Taller flex y bisondanilopuente
 
Compiladores Ex..ppt
Compiladores Ex..pptCompiladores Ex..ppt
Compiladores Ex..pptMarko Zapata
 
Grupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes iGrupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes iRossana Sosa
 
Compiladores - Flex y Bison
Compiladores - Flex y BisonCompiladores - Flex y Bison
Compiladores - Flex y BisonSteven Tabango
 
Cap3 compiladores
Cap3 compiladoresCap3 compiladores
Cap3 compiladoresCJAO
 
Manual de Compiladores Léxico y Sintáctico.pdf
Manual de Compiladores Léxico y Sintáctico.pdfManual de Compiladores Léxico y Sintáctico.pdf
Manual de Compiladores Léxico y Sintáctico.pdfDavidErnestoT
 
Lenguajes de programación parte i.4
Lenguajes de programación parte i.4Lenguajes de programación parte i.4
Lenguajes de programación parte i.4Marquina, Santiago
 
Evolucion de los compiladores1
Evolucion de los compiladores1Evolucion de los compiladores1
Evolucion de los compiladores1udalrico
 
Unidad 3 ensambladores
Unidad 3 ensambladoresUnidad 3 ensambladores
Unidad 3 ensambladoresGustavo Davila
 
Conceptos Básicos acerca de Procesadores de Lenguajes
Conceptos Básicos acerca de Procesadores de LenguajesConceptos Básicos acerca de Procesadores de Lenguajes
Conceptos Básicos acerca de Procesadores de LenguajesGrace Laguna
 

Similar a Curso prog sist (20)

Compiladores unidad1
Compiladores unidad1Compiladores unidad1
Compiladores unidad1
 
investigacion.pdf
investigacion.pdfinvestigacion.pdf
investigacion.pdf
 
investigacion 4.4 y 4.5.pdf
investigacion 4.4 y 4.5.pdfinvestigacion 4.4 y 4.5.pdf
investigacion 4.4 y 4.5.pdf
 
Unidad1 2 Lenguajes y automatas
Unidad1 2  Lenguajes y automatasUnidad1 2  Lenguajes y automatas
Unidad1 2 Lenguajes y automatas
 
Taller 21 de junio
Taller 21 de junioTaller 21 de junio
Taller 21 de junio
 
Introducción A Compiladores
Introducción A Compiladores Introducción A Compiladores
Introducción A Compiladores
 
Taller flex y bison
Taller flex y bisonTaller flex y bison
Taller flex y bison
 
Compiladores Ex..ppt
Compiladores Ex..pptCompiladores Ex..ppt
Compiladores Ex..ppt
 
Introduccion
IntroduccionIntroduccion
Introduccion
 
Grupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes iGrupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes i
 
Compiladores - Flex y Bison
Compiladores - Flex y BisonCompiladores - Flex y Bison
Compiladores - Flex y Bison
 
Cap3 compiladores
Cap3 compiladoresCap3 compiladores
Cap3 compiladores
 
Compiladores (1) pedro vasques
Compiladores (1) pedro vasquesCompiladores (1) pedro vasques
Compiladores (1) pedro vasques
 
TABLA DE SIMBOLOS
TABLA DE SIMBOLOSTABLA DE SIMBOLOS
TABLA DE SIMBOLOS
 
Manual de Compiladores Léxico y Sintáctico.pdf
Manual de Compiladores Léxico y Sintáctico.pdfManual de Compiladores Léxico y Sintáctico.pdf
Manual de Compiladores Léxico y Sintáctico.pdf
 
Lenguajes de programación parte i.4
Lenguajes de programación parte i.4Lenguajes de programación parte i.4
Lenguajes de programación parte i.4
 
Evolucion de los compiladores1
Evolucion de los compiladores1Evolucion de los compiladores1
Evolucion de los compiladores1
 
lexico.pptx
lexico.pptxlexico.pptx
lexico.pptx
 
Unidad 3 ensambladores
Unidad 3 ensambladoresUnidad 3 ensambladores
Unidad 3 ensambladores
 
Conceptos Básicos acerca de Procesadores de Lenguajes
Conceptos Básicos acerca de Procesadores de LenguajesConceptos Básicos acerca de Procesadores de Lenguajes
Conceptos Básicos acerca de Procesadores de Lenguajes
 

Curso prog sist

  • 1. CURSO: PROGRAMACION DE SISTEMAS Dr. Ramón Zatarain Cabada
  • 2.
  • 3. Unidad I Introducción a la Programación de Sistemas
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9. Unidad II Introducción al Diseño de Lenguajes de Programación
  • 10.
  • 11. Unidad III Análisis de Léxico
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21. (cont.) Miparser.jj javacc Miparser.jj Miparser.java ParseException.java TokenMgrError.java otros archivos java javac Miparser.java Miparser.class java Miparser <inputfile mensajes USO DE JAVACC
  • 22. (cont.) PARSER_BEGIN(PS1) class PS1 {} PARSER_END(PS1) /* Para la expresión regular de la derecha lo de la izquierda será retornado */ TOKEN: { <IF: &quot;if&quot;> |<#DIGIT: [&quot;0&quot;-&quot;9&quot;]> |<ID: [&quot;a&quot;-&quot;z&quot;] ([&quot;a&quot;-&quot;z&quot;]|<DIGIT>)*> |<NUM: (<DIGIT>)+> |<REAL: ((<DIGIT>)+ &quot;.&quot; (<DIGIT>)*) | ((<DIGIT>)* &quot;.&quot; (<DIGIT>)+)> } SKIP: { <&quot;--&quot; ([&quot;a&quot; - &quot;z&quot;])* (&quot;&quot; | &quot;&quot; | &quot;&quot;)> |&quot; &quot; |&quot;&quot; |&quot;&quot; |&quot;&quot; } void Start(): {} { (<IF> | <ID> | <NUM> | <REAL>)* } EJEMPLO DE ESPECIFICACION PARA GENERAR UN SCANNER
  • 23. Unidad IV Análisis de Sintáxis
  • 24.
  • 25.
  • 26. (cont.) S Id := E E + E id E + E id id S Id := E E + E E + E id Id id
  • 27. (cont.) E E - E E - E 3 1 2 E E - E 1 E - E 2 3
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35. Programa del Parser Final int if = 1, then = 2, else = 3, begin = 4, end = 5, print = 6, semi = 7, num = 8, EQ = 9 int tok = get token ( ); void advance ( ) { tok = get token ( ); } void eat ( int t) { if ( tok == 1) advance ( ); else error ( ); } void S ( ) { switch ( tok ) { case If: eat ( if ); E ( ); eat ( then ); S ( ); eat ( else ); S ( ); break; case begin: eat ( begin ); S ( ); L ( ); break; case print: eat ( print ); E ( ); break; default: error; }} void L ( ) { switch ( tok ) { case end: eat ( end ); break; case semi: eat ( semi ); S ( ); L ( ); break; default: error ( ); }} void E ( ) { eat ( num ); eat ( EQ ); eat ( num ); }
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43. Algoritmo de Parsing LR (aho,Sethi y Ullman) Tomar el primer token de w$ /* w es la cadena */ Repeat forever begin Sea s el estado en el tope de la pila y a el token actual; if acción[s,a] = shift s’ then begin push a’ primero y sedpués s’ al tope de la pila; obten el siguiente token de la cadena de entrada else if acción[s,a] = reduce A->B then begin pop 2*|B| símbolos fuera de la pila; Sea s’ ahora el estado en el tope de la pila; Push A y después goto[s’,A] al tope de la pila; Imprime la producción A->B end else if acción[s,a] = accept then return else error() end
  • 44. Ejemplo: Parser LR(K) S4 s7 g2 s3 a S4 s7 g5 s6 r1 r1 r1 S20 s10 s8 g11 s9 S4 s7 g12 TABLA DE PARSING 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 id num print ; , + := ( ) $ S E L S20 s10 g15 g14 r5 r5 r5 r5 r5 r2 r2 s16 r2 s3 s18 r3 r3 r3 s19 s13 r8 r8 S20 s10 s8 g17 r6 r6 s16 r6 r6 S20 s10 s8 g21 S20 s10 s8 g23 r4 r4 r4 r4 r4 s22 r7 r7 r7 r7 r7 r9 s16 r9
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50. Ejemplo: void S ( ) { switch ( tok ) { case If: eat ( if ); E ( ); eat ( then ); S ( ); eat ( else ); S ( ); break; case begin: eat ( begin ); S ( ); L ( ); break; case print: eat ( print ); E ( ); break; default: print(“se esperaba if, begin o print”); }} Un problema que puede ocurrir al insertar un token faltante es que el programa caiga en un ciclo infinito, por eso a veces es preferible y mas seguro borrar el token, ya que el ciclo terminará cuando el EOF sea encontrado. Esta técnica trabaja muy cercanamente con la tabla de parsing (cuando el parser se implementa con tablas). En un parser del tipo LR o LALR, la tabla de parsing tiene 4 acciones: shift, reduce, accept y error (entrada nula). Cuando el parser encuentra una acción error , se para el proceso de análisis y se reporta la falla.
  • 51.
  • 52. Ejemplo: gramática para estatutos “begin”, “if” y “print” PARSER_BEGIN(MiniParser) public class MiniParser { public static void main(String[] args) { MiniParser parser; try { // RGC: added line if( args.length == 0 ) parser = new MiniParser(System.in); // RGC: added lines else parser= new MiniParser ( new java.io.FileInputStream( args[0] ) ); } // RGC: End parser.Program(); } catch (ParseException e) { System.out.println(e.getMessage()); } //RGC: added lines catch( Exception e ) { System.out.println(e.getMessage()); } //RGC :End } } PARSER_END(MiniParser) SKIP : { &quot; &quot; | &quot;&quot; | &quot;&quot; | &quot;&quot; }
  • 53. (cont. Ejemplo) TOKEN : { <INT: &quot;INT&quot;> | <IF: &quot;if&quot;> | <THEN: &quot;then&quot;> | <ELSE: &quot;else&quot;> | <BEGIN: &quot;begin&quot;> | <PRINT: &quot;print&quot;> | <END: &quot;end&quot;> | <SEMI: &quot;;&quot;> | <EQUAL: &quot;=&quot;> | <ID: ([&quot;a&quot;-&quot;z&quot;]|[&quot;A&quot;-&quot;Z&quot;]) ([&quot;a&quot;-&quot;z&quot;]|[&quot;A&quot;-&quot;Z&quot;]|[&quot;0&quot;-&quot;9&quot;])* > } void Program() : {} { S() <EOF> } void S() : {} { <BEGIN> S() L() | <PRINT> E() | LOOKAHEAD(12) &quot;if&quot; E() &quot;then&quot; S() &quot;else&quot; S() | &quot;if&quot; E() &quot;then&quot; S() } void L() : {} { <END> | <SEMI> S() L() } void E() : {} { <ID> <EQUAL> <ID> }
  • 54. Unidad V Análisis Semántico
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61. (cont.) S  E$ E  T E’ E’  + T E’ E’  - T E’ E’   T  F T’ T’  * F T’ T’  / F T’ T’   F  id F  num F  (E) Los tokens ID y NUM deben ahora acarrear valores de tipo string e int , respectivamente. Asumiremos que existe una tabla “lookup” que mapea identificadores a enteros. El tipo asociado con E, T, F, etc., es int, y la acción semántica es fácil de implementar.
  • 62. Interprete class Token2 { int kind; Object val; Token2(int k, Object v) { kind=k; val=v; } } final int EOF=0, ID=1, NUM=2, PLUS=3, MINUS=4,LPAREN=5, RPAREN=6, TIMES=7; int lookup(String id) { …. } int F_follow[] = {PLUS,TIMES,RPAREN,EOF}; int F() {switch(tok.kind) { case ID: int i=lookup((String)(tok.val));advance()return i ; case NUM: int i=((integer)(tok.val)).intVal(); advance(); return i ; case LPAREN: eat(LPAREN); int i=E(); eatOrSkipTo(RPAREN,F_follow); return i ; case EOF: default: print(&quot;1 esperaba ID,NUM, o parent izq&quot;); //skipto(F_follow); return 0; }} int T_follow[]= {PLUS,RPAREN,EOF}; int T() {switch(tok.kind) { case ID: case NUM: case LPAREN: return Tprime(F()); default: print(&quot;2 esperaba ID, NUM o parent izq&quot;); //skipto(T_follow); return 0; }} int Tprime(int a) {switch (tok.kind) { case TIMES: eat(TIMES); return Tprime(a*F()); case PLUS: case RPAREN: case EOF: return a ; default: print(&quot;3 esperaba ID, NUM o parent izq&quot;); //skipto(T_follow); return 0; }} void eatOrSkipTo(int expected, int[] stop) { if (tok.kind==expected) eat(expected); else {print(&quot;4 esperaba ID, NUM o parent izq&quot;); //skipto(stop);} } Acciones semánticas
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68. Programa de clases para Exp public abstract class ExpCh4 { public abstract int eval(); } class PlusExp extends ExpCh4 { private ExpCh4 e1,e2; public PlusExp(ExpCh4 a1, ExpCh4 a2) {e1=a1; e2=a2;} public int eval() { return e1.eval()+e2.eval(); } } class MinusExp extends ExpCh4 { private ExpCh4 e1,e2; public MinusExp(ExpCh4 a1, ExpCh4 a2) {e1=a1; e2=a2;} public int eval() { return e1.eval()-e2.eval(); } } class TimesExp extends ExpCh4 { private ExpCh4 e1,e2; public TimesExp(ExpCh4 a1, ExpCh4 a2) {e1=a1; e2=a2;} public int eval() { return e1.eval()*e2.eval(); } } class DivideExp extends ExpCh4 { private ExpCh4 e1,e2; public DivideExp(ExpCh4 a1, ExpCh4 a2) {e1=a1; e2=a2;} public int eval() { return e1.eval()/e2.eval(); } } class Identifier extends ExpCh4 { private String f0; public Identifier(String n0) {f0=n0;} public int eval() { return (7); //return lookup(f0); } } class IntegerLiteral extends ExpCh4 { private String f0; public IntegerLiteral(String n0) {f0=n0;} public int eval() { return (4); //return Integer.parseInt(f0); } }
  • 69.
  • 70. Gramática con acciones semánticas para árboles sintácticos PARSER_BEGIN(InterSinTree) class InterSinTree {} PARSER_END(InterSinTree) TOKEN: { <#DIGIT: [&quot;0&quot;-&quot;9&quot;]> |<ID: [&quot;a&quot;-&quot;z&quot;] ([&quot;a&quot;-&quot;z&quot;]|<DIGIT>)*> |<INTEGER_LITERAL: (<DIGIT>)+> } SKIP: { <&quot;--&quot; ([&quot;a&quot; - &quot;z&quot;])* (&quot;&quot; | &quot;&quot; | &quot;&quot;)> |&quot; &quot; |&quot;&quot; |&quot;&quot; |&quot;&quot; } ExpCh4 Start(): { ExpCh4 e; } { e=Exp() <EOF> {System.out.println(e.eval()); return e; } } ExpCh4 Exp(): { ExpCh4 e1,e2; } { e1=Term() (&quot;+&quot; e2=Term() { e1=new PlusExp(e1,e2);} |&quot;-&quot; e2=Term() { e1=new MinusExp(e1,e2);} )* { return e1;} } ExpCh4 Term(): { ExpCh4 e1,e2; } { e1=Factor() (&quot;*&quot; e2=Factor() { e1=new TimesExp(e1,e2);} |&quot;/&quot; e2=Factor() { e1=new DivideExp(e1,e2);} )* { return e1;} } ExpCh4 Factor() : { Token t; ExpCh4 e; } { (t=<ID> {return new Identifier(t.image); } | t=<INTEGER_LITERAL> {return new IntegerLiteral(t.image); } | &quot;(&quot; e=Exp() &quot;)&quot; {return e; }) }
  • 71.
  • 72.
  • 73.
  • 74. Package syntaxtree; Program (MainClass m, ClassDeclList cl) MainClass (Identifier i1, Identifier i2, Statement s) Abstract class ClassDecl ClassDeclSimple (Identifier i, VarDeclList vl, MethodDeclList ml) ClassDeclExtends (Identifier i, identifier j, VarDeclList vl, MethodDeclList ml) VarDecl (Type t, Identifier i) MethodDecl (Type t, Identifier i, FormalList fl, VarDeclList vl, StatementList, Exp e) Formal (Type t, Identifier i) Abstract class Type IntArrayType () BooleanType () IntegerType () IdentifierType (String s) Abstract class Statement Block (StatementList sl) If (Exp e, Statement s1, Statement s2) While (Exp e, Statement s) Print (Exp e) Assign (Identifier i, Exp e) ArrayAssign (Identifier i, Exp e1, Exp e2)
  • 75. (cont. figura) Abstract class Exp And (Exp e1, Exp e2) LessTha n(Exp e1, Exp e2) Plus (Exp e1, Exp e2) Minu s(Exp e1, Exp e2) Times (Exp e1, Exp e2) ArrayLoockup (Exp e1, Exp e2) ArrayLength (Exp e) Call (Exp e, Identifier i, ExpList el) IntegerLiteral (int i) True () False () IdentifierExp (String s) This () NewArray (Exp e) NewObject (Identifier i) Not (Exp e) Identifier (String s) List classes ClassDeclList () ExpList () FormalList () MethodDeclList () StatementList () VarDeclList ()
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96. Método Visitador Class ErrorMsg { boolean anyErrors; void complain (String msg) { anyErrors = true; System.out.println(msg); } } // Type t; // Identifier i; Public void visit(VarDecl n) { Type t = n.t.accept(this); String id= n.i.toString(); if (currMethod ==null) { if (!currClass.addVar(id,t)) error.complain(id + “is already defined in “ + currClass.getId()); } else if (!currentMethod.addVar(id,t)) error.Complain(id + “is already defined in “ + currClass.getId( ) + “.” + currMethod.getId( ));
  • 97.
  • 98. Método Visitador para expresiones Plus // Exp e1, e2; Public Type visit(Plus n) { if (! (n.e1.accept(this) instanceOf IntegerType) ) error.complain(“Left side of LessThan must be of type integer”); if (! (n.e2.accept(this) instanceOf IntegerType) ) error.complain(“Right side of LessThan must be of type integer”); return new IntegerType( ); }
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105. Ejemplo: Un marco de pila Argumentos de entrada Apuntador Del marco Argumentos De salida Apuntador De pila Argumento n … … Argumento 1 Liga estática Argumento m … … Argumento 1 Liga estática Variables locales Dirección retorno Temporales Registros salvados Marco actual Marco anterior Marco siguiente Direcciones de Memoria mas altas
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113. Programa de funciones Anidadas Type tree= {key: string, left: tree, right: tree} Function prettyprint(tree:tree): string= let var output := “ “ function write(s:string) = output :=concat(output,s) function show(n:int, t:tree) = let function indent(s:string)= (for i:= 1 to n do write(“ “); output:=concat(output,s);write(“ “); in if t=nil then indent(“.”) else (indent(t.key); show(n+1,t.left); show(n+1,t.right)) end in show(0,tree); output end
  • 114.
  • 115.
  • 116. Unidad VI Generación de Código Intermedio
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135. Por ejemplo, la función: Int foo() { int a; int b; /* body of foo */ } FP SP Tendría el registro de activación Existen dos apuntadores. FP que apunta al inicio del RA actual y SP que apunta a la primera localidad vacía. El valor retornado de una función es puesto en un registro especial en lugar de la pila. Cuando una función es llamada los valores de los parámetros de entrada son puestos en la pila, y cuando la función retorna un valor, el valor es almacenado en el registro de resultado. Registros salvados b a
  • 136.
  • 137. Formato completo de RA FP SP Previous Activation Record Current Activation Record Saved Registers Local Variables Input Parameter 1 Input Parameter 2 … Input Parameter n
  • 138. Considere el siguiente programa: void foo(int a, int b); void foo(int c, int d); void main() { int u; int v; /* Label A */ bar(1,2); } void bar(int a, int b) { int w; int x; foo(3,4); } void foo(int c, int d) { int y; int z; /* Label B */ }
  • 139. En label A de el programa, la pila de RA se miraría de la forma siguiente FP SP Activation Record for main La variable local u puede accesarse examinando la localidad de memoria apuntada por FP. La variable v puede accesarse examinando (FP-wordsize). Algo para aclarar es que la pila crece de direcciones altas a bajas. Saved Registers v u
  • 140. En etiqueta B los RA se mirarían así: FP SP Activation Record for main Activation Record for bar Activation Record for foo Saved Registers z y c d Saved Registers x w a b Saved Registers v u
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146. Ejemplos: (asumiremos que wordsize=4 y que un entero se guarda en una palabra) void foo(int a, int b) { int x; int y; boolean z; x = 1; y = a * b; y++; bar(y, x + 1, a); x = function(y+1, 3); if (x > 2) z = true; else z = false; }
  • 147. X=1; Move Memory Constant(1) Register(FP)
  • 148. y = a * b; Move Memory Operator (-) Register(FP) Constant(4) Operator(*) Memory Memory Operator (+) Operator (+) Register(FP) Constant(4) Register(FP) Constant(8)
  • 149. Y++; Move Memory Operator (-) Constant(4) Operator(+) Memory Constant(1) Operator (-) Register(FP) Constant(4) Register(FP)
  • 150. bar(y,x+1,a); CallStatement(“bar”) Memory Operator (-) Constant(4) Register(FP) Operator (+) Memory Constant(1) Register(FP) Memory Operator (+) Constant(4) Register(FP)
  • 151. x=function(y+1,3); Move Memory Register(FP) Callexpression(“function”) Constant(3) Constant(1) Operator(+) Memory Operator(-) Register(FP) Constant(4)
  • 152. if (x > 2) z = true; else z = false; Sequential ConditionalJump(“iftrue”) Operator(>) Memory Constant(2) Sequential Sequential Sequential Sequential Label(“ifend”) Jump(“ifend”) Label(“iftrue”) Move Move Constant(0) Memory Operator(-) Register(FP) Constant(8) Constant(1) Memory Operator(-) Register(FP) Constant(8) Register(FP)
  • 153.
  • 154.
  • 155. La variable local x es almacenada en la pila, igual que la dirección base del arreglo A y del arreglo B. Stack Heap x A B FP SP A[0] A[1] A[2] A[3] A[4] B[0] B[1] B[2] B[3] B[4] Saved Registers
  • 156. ¿Cómo debemos representar el arreglo A[3] Register(FP) Memory Operator(-) Memory Operator(*) Operator(-) Constant(WORDSIZE) Constant(WORDSIZE) Constant(3)
  • 157. ¿ Y A[x] ? Memory Operator(-) Memory Operator(*) Operator(-) Register(FP) Constant(WORDSIZE) Constant(WORDSIZE) Memory Register(FP)
  • 158. ¿ Y para A[B[2]] ? Memory Operator(-) Memory Operator(*) Operator(-) Register(FP) Constant(WORDSIZE) Constant(WORDSIZE) Memory Operator(-) Memory Operator(-) Register(FP) Constant(2*WORDSIZE) Operator(*) Constant(WORDSIZE) Constant(2)
  • 159. Arreglos Multidimensionales se manejan de manera similar. Ejemplo: void twoDarray { int i; int c [ ] [ ] ; C = new int [3] [ ] ; for (i=0; i<3; i++) C[i] = new int[2] ; /* Body of function */ }
  • 160. El RA y el Heap se ven así: Stack Heap C[0] C[1] C[2] C[0] [0] C[0] [1] C[1] [0] C[1] [1] C[2] [0] C[2] [1] i C FP SP Saved Registers
  • 161. La variable C sería representada así: Memory Operator(-) Register(FP) Constant(WORDSIZE)
  • 162. La variable C[2] así: Memory Operator(-) Memory Operator(*) Operator(-) Register(FP) Constant(WORDSIZE) Constant(WORDSIZE) Constant(2)
  • 163. La variable c[2] [1] Memory Operator(-) Memory Operator(*) Operator(-) Memory Operator(*) Constant(WORDSIZE) Constant(1) Operator(-) Register(FP) Constant(WORDSIZE) Constant(2) Constant(WORDSIZE)
  • 164. Variables Instanciadas Son muy similares a las variables arreglo. La única diferencia es que en las variables arreglo, el desplazamiento para el índice necesita ser calculado, mientras que en las variables instanciadas, el desplazamiento es conocido en tiempo de compilación. Ejemplo: class simpleClass { int x; int y; int A[ ]; } void main() { simpleClass(); s = new simpleClass(); s.A = new int[3] /* Body of main */ }
  • 165. ¿Cuál es el árbol de ensamblador para s.y ? Memory Register(FP) Él árbol de s : Para obtener y de s : Memory Memory Operator(-) Constant(WORDSIZE) Register(FP)
  • 166. El árbol de la variable s.x: Memory Memory Register(FP) El árbol para .A[3]: Memory Operator(-) Memory Operator(*) Operator(-) Memory Constant(2*WORDSIZE) Constant(WORDSIZE) Constant(3) Register(FP)
  • 167.
  • 168. Ejemplo: Void main() { int x; int y; y = x + 4; } Move Memory Operator(+) Operator(-) Constant(4) Memory Register(FP) Register(FP) Constant(4)
  • 169.
  • 170. Y se representa con el árbol: Sequential ConditionalJump(“iftrue”) <test> Sequential Sequential Sequential Sequential Label(“ifend”) Jump(“ifend”) Label(“iftrue”) <statement1> <statement2>
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176. Etiquetas Se necesitan tanto para las llamadas a métodos como para los “if” y los ciclos “while” y “for”. La siguiente clase nos genera etiquetas únicas (ifEnd001,ifEnd02,etc.) y etiquetas específicas (llamadas a métodos). import java.util.Hashtable; class Label { protected String label; private static HashTable labelhash; Integer last; Int next; public Label(String s) { if (labelhash == null) { labelhash = new HashTable(199); } last = (Integer) labelhash.find(s); If (last == null) { next = 1; labelhash.insert(s, new Integer(1)); label = s + 1; } else { next = last.intValue() + 1; labelhash.delete(s); labelhash.insert(s, new Integer(next)); label = s + next; } } public static Label AbsLabel(String s) { Label abslab = new Label(); abslab.label = s; return abslab; } public String toString() { return label; }
  • 177. Interfase para Construir Árboles de Ensamblador Abstracto import java.util.Vector; public interface AATBuildTree { public AATSatement functionDefinition(AATStatemen body, int framesize, Label start, Label end); public AATSatement ifStatement(AATExpression test, AATStatement ifbody, AATStatement elsebody); public AATEexpression allocate(AATExpression size); public AATStatement whileStatement(AATExpression test, AATStatement increment, AATStatemen body); public AATStatement emptyStatement( ) ; public AATStatement callStatement(Vector actuals, Label name); public AATStatement assignmentStatement(AATExpression lhs, AATExpressionrhs); public AATStatement sequentialStatement(AATStatement first, AATStatement second); public AATExpression baseVariable(int offset); public AATExpression arrayVariable(AATExpresion base, AATExpression index, int elementSiza); public AATExpression classVariable(AATExpression(AATExpression base, int, offset); public AATExpression constantExpression(int, value); public AATExpression operatorExpression(AATExpression left, AATExpression rigth, int operator); public AATExpression callExpression(Vector actuals, Label name); public AATStatement returnStatement(AATExpression value, Label functioned); }
  • 178. EJEMPLOS: void foo(int a) { int b; int c; if (a > 2) b = 2; else c = a+ 1; } Sea bt una instancia de una clase que implementa la interfase AATBuildTree, y sea 4 el tamaño de la palabra de la máquina. El árbol de ensamblador abstracto para la expresión (a > 2) en la función foo podría crearse con: AATExpression e1; e1 = bt.operatorExpression(bt.baseVariable(4), bt.constantExpression/(2), AATOperator.GREATER_THAN);
  • 179. Igual, el ensamblador abstracto para el estatuto b = 2; y c = a + 1 , puede crearse con: AATEstatement s1, s2; s1 = bt.assignmentStatemen(bt.baseVariable(0), bt.constantExpression(2)); s2 = bt.assignment(bt.BaseVariable(-4), bt.operatorExpression(bt.baseVariable(4), bt.constantExpression(1), AATOperator.PLUS)); Finalmente, dadas las definiciones anteriores, el ensamblador abstracto para el estatuto if (a > 2) b = 2 else c = a + 1; puede crearse con: AATstatement s3; s3 = bt.ifStatement(e1,s1,s2);
  • 180.
  • 181.
  • 182. Ejemplo: Para analizar un AST: Integer_Literal(3) El analizador semántico actualmente retorna IntegerType . Para analizar el AST: + Integer_Literal(3) Integer_Literal(4) El analizador semántico llama al método accept para cada subárbol – constant(3) y constant(4), se asegura que ambos sean enteros, y retorne un entero. Después de modificar el analizador semántico para producir AATs, cunado se analiza el AST: Integer_Literal(3) El analizador retornará dos valores: Integer_Type y bt.constantExpression(3).
  • 183. Cuando se analiza el AST: + Integer_Literal(3) Integer_Literal(4) Primero se llama el método accept de los subárboles, se asegura que los tipos sean enteros y entonces construye una expresión operador basado en los valores de los subárboles (usando una llamada al método operatorExpression en la interfase AATBuildTree ).
  • 184.
  • 185.
  • 186. Código Ensamblador Objeto Usaremos un subconjunto del ensamblador para MIPS if rs ≥ 0, jump to the label <target> Bgez rs, <target> if rs < 0, jump to the label <target> bltz rs, <target> if rs ≠ rt, jump to the label <target> bne rs, rt, <target> if rs == rt, jump to the label <target> beq rs, rt, <target> if rs < rt, rd = 1, else rd = 0 slt rd, rs, rt Jump to the address stored in register rs. Used in conjunction with jal to return from function and procedure calls jr rs jump and link. Put the address of the next instruction in the return register, and then jump to the address <target>. Used for function and procedure calls. jal <target> Jump to the assembly label <target>. j <target> Move contents of the special register LOW into the register rd. mflo rd Dive contents of register rs by register rt, put the quotient in register LO and the remainder in register HI div rs, rt Multiply contents of register rs by register rt, put the low order bits in register LO and the high bits in register HI mult rs, rt Add the constant value <val> to register rs, put result in register rt. addi rt, rs, <val> Subtract contents of register rt from rs, put result in register rd. sub rd, rs, rt Add contents of register rs and rt, put result in register rd. add rd, rs, rt Add the constant value <offset> to the register base to get an address. Store the contents of rt into this address. M[base + <offset>] = rt sw rt, <offset> (base) Add the constant value <offset> to the register base to get an address. Load the contents of this address into the register rt. Rt = M[base + <offset>] Description lw rt, <offset> (base) Instruction
  • 187. Register that we will use for code generation General Purpose Register $t3 $t3 General Purpose Register $t2 $t2 General Purpose Register $t1 $t1 Accumulator Register – Used for expressioncalculation $t0 $ACC Zero register – This register always has the value 0 $zero $zero Result Register – Holds the return address for the current function $ra $return Result Register – Holds the return value for functions $v0 $result Expression Stack Pointer – The next expression stack holds temporary values for expression avaluations $esp $ESP Stack Pointer – Used for the activation record stack $sp $SP Frame pointer – points to the top of the current activation record Description $fp SPIM Name $FP Mnemonic Name
  • 188.
  • 189. Ejemplos: Tiling Simple para Árboles de Expresiones . El código asociado con el tile colocará el valor de la expresión en el tope de la pila de expresiones. Expresiones de Constantes Considere el siguiente árbol: Constant(5) El código asociado con este tile necesita poner un 5 en el tope de la pila de expresiones. addi $t1, $zero, 5 % Load the constant value 5 into the register $t1 sw $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer En general, el tile para cualquier valor constante x es: addi $t1, $zero, x % Load the constant value into x the register $t1 sw $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer
  • 190. Operaciones de Aritmética Binaria + Constant(3) Constant(4) En lugar de tratar de cubrir todo el árbol con un tile, usaremos tres. La constante 4 y 5 pueden cubrirse cada una con un tile de constante, y usaremos un tile “ +” para cubrir la suma. + Constant(3) Constant(4)
  • 191. ¿Cómo debe ser el código para +? Recordemos que emitimos código en post-order (subárbol izquierdo, subárbol derecho y luego raíz). Podemos asumir que los valores de los operandos de la izquierda y la derecha de el + ya están en la pila cuando el código de el tile + es emitido. Ntonces, todo lo que necesitamos es hacer es sacar (pop off) esos valores , hacer la suma y meter (push) el resultado de regreso a la pila. El código para el tile + es: lw $t1, 8(ESP) % Load the first operand into temporary $t1 lw $t2, 4(ESP) % Load the second operand into temporary $t2 add $t1, $t1, $t2 % Do the addition. Storing result in $t1 sw $t1, 8(ESP) % Store the result on the expression stack add $ESP, $ESP, 4 % Update the expression stack pointer
  • 192. y el código para toda la expresión es: addi $t1, $zero, 3 % Load the constant value 3 into the register $t1 sw $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer addi $t1, $zero, 4 % Load the constant value into 4 the register $t1 sw $t1, 0($ESP) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 %Update the expression stack pointer lw $t1, 8($ESP) % Load the first operand into temporary $t1 lw $t2, 4($ESP) % Load the second operand into temporary $t2 add $t1, $t1, $t2 % Do the addtion, storing result in $t1 sw $t1, 8(ESP) % Update the expression stack pointer
  • 193. Registros Considere el árbol de expresión Register(FP) Esto ocupa un tile. sw $FP, 0($ESP) addi $ESP, ESP, -4 Combinando otros tiles discutidos antes, el árbol - Register(FP) Constant(8) Puede ser los tiles: - Register(FP) Constant(8)
  • 194. Produciendo el árbol sw $FP, 0($ESP) % Store frame pointer on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer addi $t1, $zero, 8 % Load the constant value 8 into the register $t1 sw $t1, 0($esp) % Store $t1 on the top of the expression stack addi $ESP, $ESP, -4 % Update the expression stack pointer lw $t1, 8($ESP) % Load the first operand into temporary $t1