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

📄 semant.java

📁 编译原理大作业---tiger编译器 包括semant,translate,mipsframe,regalloc等所有phase 懂的人自会知道
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      }      stampaDeb(e.pos,out);      if (env.errorMsg.num_error==0) {         return new ExpTy(trans.ifExp(check.exp,thenc.exp,elsec.exp), thenc.ty);      }      else return new ExpTy(null, thenc.ty);   }   // WhileExp   ExpTy transExp(Absyn.WhileExp e) {    // crea una nuova etichetta e salva in old_done    // il valore di current_done.    Temp.Label new_done= new Temp.Label();    Temp.Label old_done= current_done;    // aggiorna current_done alla nuova etichetta    current_done=new_done;    // controlla il tipo dell'espressione "test"    ExpTy check=transExp(e.test);    if(!(check.ty.actual()==INT)) env.errorMsg.error(e.test.pos,"Il test del ciclo WHILE deve essere di tipo INT");    // incrementa il contatore dei cicli    loopDepth++;    // processa il corpo della while    ExpTy body=transExp(e.body);    // dopo aver processato il corpo ripristina il valore precedente di current_done.    current_done=old_done;    // controlla che il corpo della While abbia Tipo restituito VOID !    if(!(body.ty==VOID)) {       env.errorMsg.error(e.body.pos,"il corpo del ciclo WHILE deve essere di tipo VOID");    }    // decrementa il contatore dei cicli    loopDepth--;    stampaDeb(e.pos,"WhileExp: \"" + nomeClasse(check.ty) +"\"");    if(env.errorMsg.num_error==0) {       return new ExpTy(trans.whileExp(new_done,check.exp,body.exp),VOID);    }    else return new ExpTy(null,VOID);   }   // NilExp   ExpTy transExp(Absyn.NilExp e) {   return new ExpTy(trans.nilExp(),NIL);   }   // IntExp   ExpTy transExp(Absyn.IntExp e) {    if(env.errorMsg.num_error==0) {       return new ExpTy(trans.intExp(e.value),INT);    }    else return new ExpTy(null,INT);   }   // StringExp   ExpTy transExp(Absyn.StringExp e) {      if (env.errorMsg.num_error==0) { return new ExpTy(trans.stringExp(e.value), STRING); }      else return new ExpTy(null,STRING);   }   // BreakExp   ExpTy transExp(Absyn.BreakExp e) {      // se non si trova dentro una while o una for segnala errore      if (loopDepth==0)         env.errorMsg.error(e.pos,"break illegale ( si trova fuori da una WHILE / FOR  )");      else { stampaDeb(e.pos, "BreakExp:  Label DONE del ciclo = " + current_done ); }      if (env.errorMsg.num_error==0) { return new ExpTy(trans.breakExp(current_done),VOID); }      else return new ExpTy(null,VOID);   }   // CallExp   ExpTy transExp(Absyn.CallExp e) {    // Vector da utilizzare in Translate    // contente gli alberi del codice intermedio dei parametri.    Vector paramsVector = new Vector();    // Flag per il controllo del caso anomalo: meno parametri ....    boolean flag=false;    // Flag per vedere se restituisce un VOID oppure no.    boolean isVoid=true;    Types.Type res=VOID;    FunEntry fun = null;    // Symbol func  Explist args -> head , tail (Explist)    Entry x = (Entry)env.venv.get(e.func);    if (!(x instanceof FunEntry)) { // controlla se e' una funzione       env.errorMsg.error(e.pos,"Funzione \"" + e.func + "\" indefinita");    }    else { // e' una FunEntry       // Da Env --> FunEntry [formals:Types.RECORD results:Types.Type]       fun = (FunEntry)x;       // Tipo restituito       if (fun.results!=null) {          isVoid = false;          res = fun.results;       }       //scorre la lista dei campi dichiarati della call per controllare tutto       // RECORD: fieldName , fieldType, tail       for(Types.RECORD formali=fun.formals;formali!=null;formali=formali.tail) {        // controlla se vengono inizializzati meno campi di quelli dichiarati...        if(e.args == null) {           env.errorMsg.error(e.pos,"Passati meno parametri di quelli dichiarati");           flag=true;           break;        }        // ricava l'ExpTy del parametro        ExpTy temp=transExp(e.args.head);        // Aggiunge l'albero di Codice intermedio del parametro corrente        // nel vettore dei parametri formali usato poi in Translate ( trans.callExp(...))        paramsVector.addElement(temp.exp);        // confronta i tipi formali con quelli della call.        // non esegue actual() di un null        if((formali.fieldType!=null)&&(temp.ty!=null)) {           if (!(formali.fieldType.actual()==temp.ty.actual())) {              stampaDeb(0,"1: " + formali.fieldType.actual());              stampaDeb(0,"2: " + temp.ty.actual());              String out="Non puoi dare al parametro \"" + formali.fieldName + "\" di tipo \"" + nomeClasse(formali.fieldType.actual()) + "\" l'espr. di tipo \"" + nomeClasse(temp.ty.actual())+ "\"";              env.errorMsg.error(e.args.head.pos,out);           }        }        else env.errorMsg.error(e.args.head.pos,"Impossibile chiamare la funzione/procedura \"" + e.func + "\"");        // scorre i parametri della call        e.args=e.args.tail;       }    }    // Se e' una funzione  ...    if((x instanceof FunEntry)) {       // controlla che non vengano inizializzati piu' parametri di quelli dichiarati...       if ((e.args != null) && (flag==false)) {          env.errorMsg.error(e.args.head.pos,"Passati piu' parametri di quelli dichiarati");       }       stampaDeb(e.pos,"CallExp: \""+ e.func + "\": " + nomeClasse(res.actual()));    }    if (env.errorMsg.num_error==0) {       return new ExpTy(trans.callExp(level,fun.level,paramsVector,isVoid),res);    }    else return new ExpTy(null,res);   }   // RecordExp   ExpTy transExp(Absyn.RecordExp e) {    //Flag per il controllo del caso anomalo: meno campi ....    boolean flag=false;    boolean ok=true;    // Vector per memorizzare tutti i campi    Vector fieldsVector = new Vector();    Types.Type temp=checkType(e.typ,e.pos);    Types.RECORD temp1=new Types.RECORD(null,null,null);    // controlla se e.typ e' un record    // non esegue actual() di un null, inoltre se il record non esiste non procede oltre    if(temp!=null) {       if(!(temp.actual() instanceof Types.RECORD)) { env.errorMsg.error(e.pos, "Tipo RECORD richiesto"); ok=false;}       else {        temp1=(Types.RECORD)temp.actual();          Types.Type typ =(Types.Type)env.tenv.get(e.typ);        // scorre la lista dei campi per controllare tutto          for(Types.RECORD campi_dichiarati=(Types.RECORD)typ.actual() ; campi_dichiarati!=null ; campi_dichiarati=campi_dichiarati.tail) {           // controlla se non dichiariamo niente fin da subito > type c={}           if(campi_dichiarati.fieldType==null) break;           // controlla se vengono inizializzati meno campi di quelli dichiarati...           if(e.fields == null) {              env.errorMsg.error(e.pos,"Inizializzati meno campi di quelli dichiarati");            flag=true;            break;           }           // controlla se i "nomi" combaciano           if(!(campi_dichiarati.fieldName.toString().equals(e.fields.name.toString())))            env.errorMsg.error(e.pos, "Il campo \"" + e.fields.name + "\" non corrisponde a quello dichiarato \"" + campi_dichiarati.fieldName + "\"");           // controlla se il tipo dell'inizializzazione dei campi e' lo stesso di quello dichiarato           ExpTy temp2=transExp(e.fields.init);           // questo perche' actual() di null e' impossibile!           if((temp2.ty!=null)&&(campi_dichiarati.fieldType!=null)) {            if(!(campi_dichiarati.fieldType.actual()==temp2.ty.actual())) {               if(!((campi_dichiarati.fieldType.actual() instanceof Types.RECORD) && (temp2.ty.actual()==NIL))) {                String out="Non puoi inizializzare il campo \"" + e.fields.name + "\" di tipo \"" + nomeClasse(campi_dichiarati.fieldType.actual()) + "\" con l'espr. di tipo \"" + nomeClasse(temp2.ty.actual())+ "\"";                env.errorMsg.error(e.pos,out);               }            }           }           else env.errorMsg.error(e.pos,"Impossibile inizializzare il campo \"" + e.fields.name +"\"");           // aggiunge il campo al vector           fieldsVector.addElement(temp2.exp);           // per scorrere i campi del record           e.fields=e.fields.tail;        }        // se vengono inizializzati piu' campi di quelli dichiarati...           if((e.fields != null) && (!flag)) env.errorMsg.error(e.fields.pos,"Inizializzati piu' campi di quelli dichiarati");       }    }    else {       env.errorMsg.error(e.pos,"Tipo RECORD indefinito");       ok=false;    }    if (ok)  {       if(env.errorMsg.num_error==0) { return new ExpTy(trans.recordExp(fieldsVector),temp1); }       else return new ExpTy(null,temp1);    }    else return new ExpTy(null,INT);   }   // VarExp   ExpTy transExp(Absyn.VarExp e) { return transVar(e.var); }   // SeqExp   ExpTy transExp(Absyn.SeqExp e) {     // Vettore in cui vengono memorizzati tutti i pezzi di albero intermedio     Vector pezzi = new Vector();     // () e' di tipo VOID!     ExpTy et = new ExpTy(null,VOID);     Absyn.ExpList l = e.list;     while (l!=null) {        et = transExp(l.head);        // aggiunge il pezzo di Cod. intermedio al vettore        pezzi.addElement(et.exp);        l=l.tail;     }     if (env.errorMsg.num_error==0) { return new ExpTy(trans.seqExp(pezzi,et.ty == VOID),et.ty); }     else return et;   }   // ArrayExp   ExpTy transExp(Absyn.ArrayExp e) {    boolean ok = true;    ExpTy x = null;    ExpTy size = null;    // prendo il tipo di e.typ (se non esiste mi da null)    Types.Type temp=checkType(e.typ,e.pos);    Types.ARRAY temp1=new Types.ARRAY(null);    // controlla se e.typ e' un array    // non esegue actual() di un null e inoltre salta tutto e restituisce un VOID.    if(temp!=null) {       if(!(temp.actual() instanceof Types.ARRAY)) { env.errorMsg.error(e.pos, "Tipo ARRAY richiesto"); ok=false;}       else {          size = transExp(e.size);          checkInt(size, e.size.pos);          temp1 = (Types.ARRAY)temp.actual();          x = transExp(e.init);          // controlla se il tipo dell'inizializzazione e' lo stesso di quello degli elementi dell'array.          // non posso eseguire actual() di null!!!          if ((temp1.element!=null) && (x.ty!=null)) {              if (!(temp1.element.actual()==x.ty.actual())) {                 String msg=""+nomeClasse(temp1.element.actual()) + " != " + nomeClasse(x.ty.actual());                 env.errorMsg.error(e.pos, "Inizial. di tipo diversa: " + msg);              }              stampaDeb(e.pos,"ArrayExp: array of " + nomeClasse(x.ty.actual()));          }          else env.errorMsg.error(e.pos,"Impossibile inizializzare l'array \"" + e.typ + "\"");       }    }    else {       env.errorMsg.error(e.pos,"Tipo ARRAY indefinito");       ok=false;    }    if (ok) {       if(env.errorMsg.num_error==0) { return new ExpTy(trans.arrayExp(size.exp,x.exp),temp1); }       else return new ExpTy(null,temp1);    }    else return new ExpTy(null,INT);   }   /*******************************    *        DICHIARAZIONI        *    *******************************/   Translate.Exp transDec(Absyn.Dec d) {      if(d instanceof Absyn.VarDec) return transDec((Absyn.VarDec)d);      if(d instanceof Absyn.TypeDec) return transDec((Absyn.TypeDec)d);      if(d instanceof Absyn.FunctionDec) return transDec((Absyn.FunctionDec)d);      throw new Error("transDec");   }   /***  VarDec  ***/   Translate.Exp transDec(Absyn.VarDec d) {    ExpTy tmp = transExp(d.init);    Types.Type vt = null;    // verifica se e' della forma "corta" (senza tipo)    if(d.typ==null) {       // controlla se l'exp. di inizial. e' nil (in caso affermativo segnala un errore)       if(d.init instanceof Absyn.NilExp) {        env.errorMsg.error(d.pos,"L'espr. \"Nil\" richiede la dichiarazione esplicita del tipo");       }    }    // se invece e' della forma "lunga" (con il tipo)    else {       vt = transTy(d.typ);       // controlla il tipo di exp con il tipo della variabile       // se l'exp e' di tipo NIL controlla che il tipo della variabile sia RECORD       // non esegue actual() di null       if ((vt!=null)&&(tmp.ty!=null)) {          if (!(vt.actual()==tmp.ty.actual())) {             if (tmp.ty==NIL) {                if (!(vt.actual() instanceof Types.RECORD)) {                   String out="Non puoi inizializzare la var. di tipo \"" + nomeClasse(vt.actual()) + "\" con l'espr. di tipo \"" + nomeClasse(tmp.ty.actual())+ "\"";                   env.errorMsg.error(d.pos,out);                }             }             else if ((tmp.ty instanceof Types.RECORD)||(tmp.ty instanceof Types.ARRAY)) {                     String out="Differenti tipi \"" + nomeClasse(tmp.ty) +"\"";                     env.errorMsg.error(d.pos,out);                  }                  else {                     String out="Non puoi inizializzare la var. di tipo \"" + nomeClasse(vt.actual()) + "\" con l'espr. di tipo \"" + nomeClasse(tmp.ty.actual())+ "\"";                     env.errorMsg.error(d.pos,out);                  }             stampaDeb(d.pos,"VarDec: \""+d.name+"\": " + nomeClasse(tmp.ty.actual()));          }       }       else env.errorMsg.error(d.pos,"Non posso inizializzare la variabile \"" + d.name + "\"");    }    // fornisce, comunque sia, il tipo dell'exp di inizializzazione    // nel caso sia NIL allora prende il nome del tipo associato alla variabile.    // stampa il campo escape della variabile    stampaDeb(d.pos,"Escape di " + d.name + ": " + d.escape);    // memorizza l'accesso alla variabile    Translate.Access acc=level.allocLocal(d.escape);    if(tmp.ty==NIL) env.venv.put(d.name, new VarEntry(acc,vt));    else env.venv.put(d.name, new VarEntry(acc,tmp.ty));    // per Translate    if(env.errorMsg.num_error==0) { return trans.varDec(acc,level,tmp.exp); }   return null;   }   /***  TypeDec  ***/   Translate.Exp transDec(Absyn.TypeDec d) {      // per il next, se esiste      Types.Type tipo2 = null;      Types.NAME header2 = null;      // scorre e crea tutti gli header      for (Absyn.TypeDec dichiarazione=d;dichiarazione!=null;dichiarazione=dichiarazione.next) {         Types.NAME h = new Types.NAME(d.name);         // controllo "ad hoc" per risolvere il problema delle dichiarazioni         // multiple nello stesso blocco con lo stesso nome         for (Absyn.TypeDec dInLista=dichiarazione.next; dInLista!=null; dInLista=dInLista.next) {            if (dichiarazione.name==dInLista.name) {               env.errorMsg.error(dichiarazione.pos, "Nome duplicato in dichiarazioni di tipi nello stesso blocco.");            }         }         env.tenv.put(dichiarazione.name, h);      }      // scorre e processa tutti i corpi      for (Absyn.TypeDec dichiarazione=d;dichiarazione!=null;dichiarazione=dichiarazione.next) {         if (dichiarazione.ty instanceof Absyn.RecordTy) {            // crea il record tipo

⌨️ 快捷键说明

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