⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semant.java

📁 编译原理大作业---tiger编译器 包括semant,translate,mipsframe,regalloc等所有phase 懂的人自会知道
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            recout="Campi del record \"" + dichiarazione.name + "\":\n";            Types.Type tipo=transTy(dichiarazione.ty);            recout=""; // azzera la stringa per il debug            // lega al Types.NAME "campo" (un header), il tipo appena creato con transTy(dichiarazione.ty)            Types.NAME campo=(Types.NAME)env.tenv.get(dichiarazione.name);            campo.bind((Types.RECORD)tipo);         }         else {            Types.Type tipo=transTy(dichiarazione.ty);            // lega al Types.NAME "campo" (un header), il tipo appena creato con transTy(dichiarazione.ty)            Types.NAME campo=(Types.NAME)env.tenv.get(dichiarazione.name);            campo.bind(tipo);            if(campo.isLoop()==true)  env.errorMsg.error(dichiarazione.pos, "Ciclo illegale nelle dichiarazioni.");         }      }      // per Translate      if(env.errorMsg.num_error==0) { return trans.typeDec(); }      return null;   }   /***  FunctionDec  ***/   // (NOTA: "d" e' una lista di dichiarazioni, per eventuale ricorsione)   Translate.Exp  transDec(Absyn.FunctionDec d) {      // stringhe per il debug      String out = "", outinizio = "", par = "";      // test: funzione o procedura? (...viene restituito un valore?)      boolean isProc = false;      // per il corpo della funzione      ExpTy temp = null;      Types.Type result = null;      Types.RECORD formals = null;      // scorre e crea tutti gli header (i vari FunEntry)      for (Absyn.FunctionDec dichiarazione=d;dichiarazione!=null;dichiarazione=dichiarazione.next) {         out="Function header: " + dichiarazione.name;         // crea una BoolList per gli "escape" dei parametri formali         // che verra' sovrascritta e riempita in transTypeFields         Util.BoolList bl = new Util.BoolList(true,null);         // controllo "ad hoc" per risolvere il problema delle dichiarazioni         // multiple nello stesso blocco con lo stesso nome         for (Absyn.FunctionDec dInLista=dichiarazione.next; dInLista!=null; dInLista=dInLista.next) {             if (dichiarazione.name==dInLista.name)               env.errorMsg.error(dichiarazione.pos, "Nome duplicato in dichiarazioni di funzioni nello stesso blocco.");         }         if (dichiarazione.params!=null) {            par = "\t Parametri della funzione:";            formals = transTypeFields(dichiarazione.params,bl);            // stampa tutto il fieldlist per debug            for (Types.RECORD temprec=formals; temprec!=null; temprec=temprec.tail)                par = par+"\n\t   " + temprec.fieldName + ": " + nomeClasse(temprec.fieldType);         }         else {            formals = null;            par = "\t Nessun parametro.";         }         out = out+"\n"+par;         stampaDeb(dichiarazione.pos, out+"\n");         out = par = ""; // azzera le stringhe         // prende il Tipo restituito (se esiste)         if (dichiarazione.result!=null) result = transTy(dichiarazione.result);         else result = null;         // crea un nuovo livello e una nuova label         out = out +"\n\tLivello precedente: " + level.frame.name;         level = new Translate.Level(level,dichiarazione.name,bl);         Temp.Label label = new Temp.Label();         // debug         outinizio = "Function info: " + level.frame.name;         out = out +"\n\tLivello funzione: " + level.frame.name + "\n\tLabel funzione: " + label;         // inserisce la FunEntry         env.venv.put(dichiarazione.name,new FunEntry(level,label,formals,result));         stampaDeb(dichiarazione.pos,outinizio+out+"\n");         out = par = "";     }     // scorre e processa tutti i corpi     for (Absyn.FunctionDec dichiarazione=d;dichiarazione!=null;dichiarazione=dichiarazione.next) {        env.venv.beginScope();        for (Absyn.FieldList p=dichiarazione.params; p!=null; p=p.tail) {           env.venv.put(p.name,new VarEntry(level.allocLocal(p.escape),(Types.Type)env.tenv.get(p.typ)));        }       // recupera la funEntry inserita prima       FunEntry fe=(FunEntry)env.venv.get(dichiarazione.name);       // processa il corpo della funzione       temp = transExp(dichiarazione.body);       env.venv.endScope();       // prende il Tipo restituito (se esiste)       if(dichiarazione.result!=null) result = transTy(dichiarazione.result);       else result=null;       // controlla "nella forma lunga"==funzione se il Tipo restituito       // della espr. combacia con il tipo restituito dalla funzione       if (result!=null) {          if (!(result.actual()==temp.ty.actual())) {             env.errorMsg.error(dichiarazione.pos, "Tipo restituito " + nomeClasse(result.actual()) +" non compatibile con " + nomeClasse(temp.ty.actual()));          }       }       // controlla, se e' una procedura, che restituisca un VOID e non un valore       if (result == null) {          // e' una procedura          isProc=true;          if (temp.ty!=VOID) {             // non esegue actual() di null             if(temp.ty!=null)  env.errorMsg.error(dichiarazione.pos,"La procedura restituisce un valore di tipo \"" + nomeClasse(temp.ty.actual()) + "\"");          }       }       if (result!=null) out=out+"tipo restituito dalla funzione " + dichiarazione.name +": " + nomeClasse(result.actual());       else out=out+"tipo restituito dalla funzione "+ dichiarazione.name +": VOID (procedura)";       // inserisce i frags per ogni funzione       trans.functionDec(fe.level,temp.exp,isProc);       if (debflag==1) System.out.println("");       stampaDeb(dichiarazione.pos, out+"\n");       out=par=""; // azzera le stringhe    }    if (env.errorMsg.num_error==0) { return trans.functionDec(); }    return null;   }    /****************************     *           TIPI           *     ****************************/   Types.Type transTy(Absyn.Ty t) {      if (t instanceof Absyn.NameTy) return transTy((Absyn.NameTy)t);      if (t instanceof Absyn.RecordTy) return transTy((Absyn.RecordTy)t);      if (t instanceof Absyn.ArrayTy) return transTy((Absyn.ArrayTy)t);      throw new Error("transTy");  // rimuovere questa riga di codice?   }   // NameTy   Types.Type transTy(Absyn.NameTy t) {     Types.NAME nome= new Types.NAME(t.name);     // controlla il tipo se esiste, altrimenti do' errore     Types.Type tipo=checkType(t.name,t.pos);     // se il tipo esiste     if (tipo!=null) { nome.bind(tipo); }     else { nome = null; }     return nome;   }   // RecordTy   Types.Type transTy(Absyn.RecordTy t) {      Types.RECORD rec;      // se e' il caso "type c={} " allora crea un tipo record vuoto      if(t.fields==null) return new Types.RECORD(null,null,null);      rec=transTypeFields(t.fields);      // Stamps tutto il fieldlist per debug      for(Types.RECORD temprec=rec; temprec!=null; temprec=temprec.tail)         recout=recout+"\t   " + temprec.fieldName + ": " + nomeClasse(temprec.fieldType) + "\n";      stampaDeb(t.pos, recout);      return rec;   }   // ArrayTy   Types.Type transTy(Absyn.ArrayTy t) {    // controlla il tipo se esiste, altrimenti do' errore    return new Types.ARRAY(checkType(t.typ,t.pos));   }   // transTypeFields   Types.RECORD transTypeFields(Absyn.FieldList f) {    Types.RECORD result;    Types.RECORD temp;    Types.RECORD coda;    // --- PASSO BASE    // controlla il tipo del primo campo    Types.Type tc = checkType(f.typ,f.pos);    result = new Types.RECORD(f.name, tc, null);    temp=result;    // --- PASSO ITERATO    for(f=f.tail;f!=null;f=f.tail) {       // controlla il tipo del campo       tc = checkType(f.typ,f.pos);       coda = new Types.RECORD(null,null,null);       coda.fieldName=f.name;       coda.fieldType=tc;       temp.tail=coda;       // questo per togliere l'ultima tripla (null,null,null)       if(!(f.tail==null)) {        coda.tail= new Types.RECORD(null,null,null);        temp=coda;       }    }   return result;   }   // transTypeFields: ( FieldList, BoolList )   // Overloading della principale.   // Usata solo in FunctionDec per settare la BoolList da   // passare a FunEntry.   Types.RECORD transTypeFields(Absyn.FieldList f, Util.BoolList bl) {    Types.RECORD result;    Types.RECORD temp;    Types.RECORD coda;    // --- PASSO BASE    // controlla il tipo del primo campo    Types.Type tc = checkType(f.typ,f.pos);    result = new Types.RECORD(f.name, tc, null);    bl = new Util.BoolList(f.escape,null);    temp=result;      // --- PASSO ITERATO    for(f=f.tail;f!=null;f=f.tail) {       // controlla il tipo del campo       tc = checkType(f.typ,f.pos);       coda = new Types.RECORD(null,null,null);       coda.fieldName=f.name;       coda.fieldType=tc;       temp.tail=coda;       // aggiunge un nuovo booleano alla BoolList       bl.tail=new Util.BoolList(f.escape,null);       // questo per togliere l'ultima tripla (null,null,null)       if(!(f.tail==null)) {        coda.tail= new Types.RECORD(null,null,null);        temp=coda;       }    }   return result;   }   // transTypeFields2   // 2 parametri: record su cui lavorare == tipo da legare, nome a cui legare il tipo   Types.RECORD transTypeFields2(Types.RECORD r,Types.NAME n) {      Types.RECORD result=r;      for(Types.RECORD tempr=r;tempr!=null;tempr=tempr.tail) {          if (tempr.fieldType==n) {             Types.NAME campo=(Types.NAME)tempr.fieldType;             campo.bind(tempr);          }      }      return result;   }    /*********************************     *           SUPPORTO            *     *********************************/   // Funzione getName (restituisce il nome di un Types.NAME)   String getName(Types.NAME tipo) { return tipo.name.toString(); }   // Funzione checkInt   // controlla se l'exp denota un intero.   Translate.Exp checkInt(ExpTy et, int pos) {    if(!(et.ty.actual()==INT)) env.errorMsg.error(pos, "Intero richiesto");    return et.exp;   }   // Funzione checkType   // controlla il tipo se esiste, altrimenti da' errore e restituisce null   Types.Type checkType(Symbol.Symbol s, int pos) {    // prende il tipo del simbolo...    Types.Type tc = (Types.Type)env.tenv.get(s);    // se non esiste nella tabella do' errore    if(tc==null) env.errorMsg.error(pos, "Tipo \"" + s.toString() + "\" indefinito");   return tc;   }   // Funzione checkComp   // per la comparazione di due ExpTy   void checkComp(int pos, ExpTy left, ExpTy right, String op) {    String out="Comparazione di tipi incompatibili (\"" + nomeClasse(left.ty.actual()) + "\" e \"" + nomeClasse(right.ty.actual()) +"\")";    stampaDeb(pos,"OpExp: " + nomeClasse(left.ty.actual()) + " " + op + " " + nomeClasse(right.ty.actual())  );    if((left.ty.actual()==INT)) {       if(!(right.ty.actual()==INT)) {        env.errorMsg.error(pos, out);       }    }    else if((left.ty.actual()==STRING)) {        if(!(right.ty.actual()==STRING)) {        env.errorMsg.error(pos, out);          }        }        else env.errorMsg.error(pos, "Comparazione non consentita per tipi \"" + nomeClasse(left.ty.actual())+ "\"");    }   // Funzione checkEq   // per la comparaziore di due ExpTy   void checkEq(int pos ,ExpTy left, ExpTy right, String op) {    String out="Comparazione di tipi incompatibili (\"" + nomeClasse(left.ty.actual()) + "\" e \"" + nomeClasse(right.ty.actual()) +"\")";    stampaDeb(pos,"OpExp: " + nomeClasse(left.ty.actual()) + " " + op + " " + nomeClasse(right.ty.actual())  );        if(left.ty.actual()==INT ) {          if(!(right.ty.actual()==INT)) env.errorMsg.error(pos,out);        }        else if(left.ty.actual()==STRING) {           if(!(right.ty.actual()==STRING)) env.errorMsg.error(pos,out);            }          else if((left.ty.actual()==NIL) && (right.ty.actual()==NIL)) {               env.errorMsg.error(pos,"nil = nil non permessa !");                }              else if((left.ty.actual() instanceof Types.RECORD)||(left.ty.actual() instanceof Types.ARRAY)) {                if(!(left.ty.actual()==right.ty.actual())) {                   if(!( ((left.ty.actual() instanceof Types.RECORD) && (right.ty.actual()==NIL))                      || ((right.ty.actual() instanceof Types.RECORD) && (left.ty.actual()==NIL)) )) {                      out="Comparazione tipi \"" + nomeClasse(left.ty.actual()) + "\" non valida";                    env.errorMsg.error(pos,out);                   }                    }               }   }   // Funzione nomeClasse   // Restituisce il nome della classe levando tutti gli   // eventuali package (es. Ciao.Types.STRING --> STRING)   public String nomeClasse(Object o) {    String temp;    String result="";    if(o==null) result="null";    else {       temp=o.getClass().getName();       for(int i=0;i<temp.length();i++)  {        if(temp.charAt(i)=='.') result=temp.substring(i+1);       }    }    return result;   }   // Funzione stampaDeb: stampa i messaggi di Debug (con la posizione)   public void stampaDeb(int pos, String msg) {      if (debflag == 1) System.out.println("(" + pos + ") > " + msg);   }   // Funzione che stampa la tabella dei tipi finali,   // da usare solo nel caso in cui non ci siano errori.   public void stampaTenv() {       System.out.println("\nTABELLA DEI TIPI: simbolo (nome) -> tipo -> tipo effettivo (.actual())");      System.out.println("");      java.util.Enumeration e= env.tenv.keys();      while(e.hasMoreElements())  {         Symbol.Symbol nome=(Symbol.Symbol)e.nextElement();         Types.Type tipo=(Types.Type)env.tenv.get(nome);         System.out.println("   " + nome + " -> " + nomeClasse(tipo) + " -> " + nomeClasse(tipo.actual()));      }   }   // Funzione che stampa la tabella delle variabili,   // da usare solo nel caso in cui non ci siano errori.   public void stampaVenv() {       System.out.println("\nTABELLA DELLE VARIABILI E DELLE FUNZIONI");      System.out.println("");      java.util.Enumeration e= env.venv.keys();      while(e.hasMoreElements())  {         Symbol.Symbol nome=(Symbol.Symbol)e.nextElement();         Entry entr=(Entry)env.venv.get(nome);         System.out.println("   " + nome + "  ->  " + nomeClasse(entr));      }      System.out.println("");   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -