Coverage Report - ProjetCompil.Verif.Src.Verif
 
Classes in this File Line Coverage Branch Coverage Complexity
Verif
80 %
193/240
51 %
83/161
5,625
Verif$1
0 %
0/1
N/A
5,625
 
 1  
 package ProjetCompil.Verif.Src;
 2  
 
 3  
 import ProjetCompil.Global.Src.*;
 4  
  
 5  
 /**
 6  
  * Cette classe permet de réaliser la vérification et la décoration 
 7  
  * de l'arbre abstrait d'un programme.
 8  
  */
 9  866
 public class Verif {
 10  
 
 11  
    private Environ env; // L'environnement des identificateurs
 12  
 
 13  
    /**
 14  
     * Constructeur.
 15  
     */
 16  26
    public Verif() {
 17  26
       env = new Environ();
 18  26
    }
 19  
 
 20  
    /**
 21  
     * Vérifie les contraintes contextuelles du programme correspondant à 
 22  
     * l'arbre abstrait a, qui est décoré et enrichi. 
 23  
     * Les contraintes contextuelles sont décrites 
 24  
     * dans Context.txt.
 25  
     * En cas d'erreur contextuelle, un message d'erreur est affiché et 
 26  
     * l'exception ErreurVerif est levée.
 27  
     */
 28  
    public void verifierDecorer(Arbre a) throws ErreurVerif {
 29  26
       verifier_PROGRAMME(a);
 30  2
    }
 31  
 
 32  
    /**
 33  
     * Initialisation de l'environnement avec les identificateurs prédéfinis.
 34  
     */
 35  
    private void initialiserEnv() {
 36  
       Defn def;
 37  
       // integer
 38  26
       def = Defn.creationType(Type.Integer);
 39  26
       def.setGenre(Genre.PredefInteger);
 40  26
       env.enrichir("integer", def);
 41  
       
 42  
       // ------------
 43  
       // A COMPLETER
 44  
       // ------------
 45  26
       def = Defn.creationType(Type.Boolean);
 46  26
       def.setGenre(Genre.PredefBoolean);
 47  26
       env.enrichir("boolean", def);
 48  
       
 49  26
       def = Defn.creationConstBoolean(false);
 50  26
       def.setGenre(Genre.PredefFalse);
 51  26
       env.enrichir("false", def);
 52  
       
 53  26
       def = Defn.creationConstBoolean(true);
 54  26
       def.setGenre(Genre.PredefTrue);
 55  26
       env.enrichir("true", def);
 56  
       
 57  26
       def = Defn.creationConstInteger(java.lang.Integer.MAX_VALUE);
 58  26
       def.setGenre(Genre.PredefMaxInt);
 59  26
       env.enrichir("max_int", def);
 60  
       
 61  26
       def = Defn.creationType(Type.Real);
 62  26
       def.setGenre(Genre.PredefReal);
 63  26
       env.enrichir("real", def);
 64  26
    }
 65  
 
 66  
    //NOTE: Il existe des constantes ?
 67  
    
 68  
    private boolean estFeuille(Arbre a){
 69  544
            return (a.getArite() == 0);
 70  
    }
 71  
    
 72  
    
 73  
    /**************************************************************************
 74  
     * PROGRAMME
 75  
     **************************************************************************/
 76  
    private void verifier_PROGRAMME(Arbre a) throws ErreurVerif {
 77  26
       initialiserEnv();
 78  26
       verifier_LISTE_DECL(a.getFils1());
 79  22
       verifier_LISTE_INST(a.getFils2());
 80  2
    }
 81  
    
 82  
    /*
 83  
     * PARTIE DECLARATION DE VARIABLES
 84  
     */
 85  
    
 86  
    private int verifier_CONST_ENT(Arbre a) throws ErreurVerif {
 87  142
            if (!estFeuille(a))
 88  0
                         throw new ErreurInterneVerif("Abre incorrect dans verifier_ENTIER");
 89  
 
 90  142
                 a.setDecor(new Decor(Type.Integer));
 91  142
                 return a.getEntier();
 92  
    }
 93  
    
 94  
    private int verifier_IDENT_CONST(Arbre a) throws ErreurVerif {
 95  0
            if (!estFeuille(a))
 96  0
                         throw new ErreurInterneVerif("Abre incorrect dans verifier_IDENT_CONST");
 97  
         
 98  0
                 Defn def = env.chercher(a.getChaine()); // On vérifie si c'est bien un type définit
 99  0
                 if (def == null) { // Si la variable n'a pas été définie
 100  0
                         ErreurContext.ErreurVariableNonDeclaree.leverErreurContext(a.getChaine(), a.getNumLigne());
 101  0
                 } //NOTE: Pas sur que ça soit utilisé uniquement pour les intervals
 102  0
                 else if ((def.getType() != Type.Integer) || (def.getNature() != NatureDefn.ConstInteger))  // Si ce n'est pas un entier
 103  0
                         ErreurContext.ErreurBorneNonEntier.leverErreurContext(a.getChaine(), a.getNumLigne());
 104  0
                 a.setDecor(new Decor(def));
 105  0
                 return def.getValeurInteger();
 106  
    }
 107  
    
 108  
    private int verifier_CONST(Arbre a) throws ErreurVerif {
 109  0
                 switch (a.getNoeud()) {
 110  
                         case Ident:
 111  0
                                 return verifier_IDENT_CONST(a);
 112  
                         case Entier:
 113  142
                                 return verifier_CONST_ENT(a);
 114  
                                 
 115  
                         default:
 116  0
                                 throw new ErreurInterneVerif("Abre incorrect dans verifier_CONST");
 117  
                 }
 118  
    }
 119  
    
 120  
    private int verifier_CONSTANTE(Arbre a) throws ErreurVerif {
 121  142
                 switch (a.getNoeud()) {
 122  
                         case PlusUnaire:
 123  0
                                 return new Integer(+verifier_CONST(a.getFils1()));
 124  
                         case MoinsUnaire:
 125  1
                                 return new Integer(-verifier_CONST(a.getFils1()));
 126  
                                 
 127  
                         default:
 128  141
                                 return verifier_CONST(a);
 129  
                 }
 130  
         }
 131  
 
 132  
    private Type verifier_TYPE_INTERVALLE(Arbre a) throws ErreurVerif {
 133  71
            int borneInf = verifier_CONSTANTE(a.getFils1());
 134  71
            int borneSup = verifier_CONSTANTE(a.getFils2());
 135  
 
 136  71
            if (borneInf > borneSup)
 137  1
                    ErreurContext.ErreurBorneDefinitionIntervalleInverse.leverErreurContext("", a.getNumLigne());
 138  70
            else if (borneSup == borneInf)
 139  0
                    ErreurContext.ErreurBorneDefinitionIntervalleVide.leverErreurContext("", a.getNumLigne());
 140  70
            return Type.creationInterval(borneInf, borneSup);
 141  
    }
 142  
    
 143  
    private Type verifier_IDENT_TYPE(Arbre a) throws ErreurVerif {
 144  80
            if (!estFeuille(a))
 145  0
                         throw new ErreurInterneVerif("Abre incorrect dans verifier_IDENT_TYPE");
 146  80
                 Defn def = env.chercher(a.getChaine()); // On vérifie si c'est bien un type définit
 147  
 
 148  
                 // Regarde dans la table d'environnement si le type a bien été défini et si c'est bien un type (pas une valeur comme true)
 149  80
                 if (def == null){ //def.getNature() != NatureDefn.Type ||
 150  2
                           System.err.print("blabla 192");
 151  2
                         ErreurContext.ErreurTypeNonDeclare.leverErreurContext(a.getChaine(), a.getNumLigne());
 152  0
                           System.err.print("blabla 192");
 153  
                 }
 154  78
                 a.setDecor(new Decor(def)); // On décore l'abre
 155  
                 
 156  78
                 return def.getType();
 157  
    }
 158  
    
 159  
    private Type verifier_TYPE(Arbre a) throws ErreurVerif {
 160  151
            switch (a.getNoeud()) {
 161  
                   case Ident: // Type
 162  80
                           return verifier_IDENT_TYPE(a);
 163  
                   case Intervalle:
 164  48
                           return verifier_TYPE_INTERVALLE(a);
 165  
                   case Tableau:
 166  23
                           return Type.creationArray(verifier_TYPE_INTERVALLE(a.getFils1()), verifier_TYPE(a.getFils2()));
 167  
                   default:
 168  0
                           throw new ErreurInterneVerif("Abre incorrect dans verifier_TYPE, type inconnu");
 169  
            }
 170  
    }
 171  
    
 172  
    /**
 173  
     * Permet de vérifier un identificateur comportant un nom de variable
 174  
     * @param a
 175  
     * @param type
 176  
     * @throws ErreurVerif
 177  
     */
 178  
    private void verifier_IDENT_DEF_VAR(Arbre a, Type type) throws ErreurVerif {
 179  158
            if (!estFeuille(a))
 180  0
                         throw new ErreurInterneVerif("Abre incorrect dans verifier_IDENT_DEF_VAR");
 181  158
                 if (env.chercher(a.getChaine()) != null)  // Si la variable a déjà été définie
 182  1
                         ErreurContext.ErreurRedefinitionVariable.leverErreurContext(a.getChaine(), a.getNumLigne());
 183  157
                 Defn def = Defn.creationVar(type); // On ajoute la définition de la variable
 184  157
                 a.setDecor(new Decor(def));
 185  157
                 env.enrichir(a.getChaine(), def);
 186  157
    }
 187  
   
 188  
    private void verifier_LIST_IDENT(Arbre a, Type type) throws ErreurVerif {
 189  158
            if (a.getFils1().getNoeud() == Noeud.ListeIdent)
 190  33
                    verifier_LIST_IDENT(a.getFils1(), type); // On vérifié les déclarations suivantes
 191  158
            verifier_IDENT_DEF_VAR(a.getFils2(), type); // N'est pas spécialement un type
 192  157
    }
 193  
    
 194  
    private void verifier_DECL(Arbre a) throws ErreurVerif {
 195  128
            Type type = verifier_TYPE(a.getFils2());
 196  125
            verifier_LIST_IDENT(a.getFils1(), type);
 197  124
    }
 198  
    
 199  
    /**************************************************************************
 200  
     * LISTE_DECL
 201  
     **************************************************************************/
 202  
    private void verifier_LISTE_DECL(Arbre a) throws ErreurVerif {
 203  135
            if (a.getNoeud() != Noeud.Vide) {
 204  135
                    if (a.getFils1().getNoeud() == Noeud.ListeDecl)
 205  109
                            verifier_LISTE_DECL(a.getFils1()); // On vérifié les déclarations suivantes
 206  128
                    verifier_DECL(a.getFils2());
 207  
                 }
 208  124
    }
 209  
    
 210  
    /*
 211  
     * PARTIE INSTRUCTIONS
 212  
     */
 213  
    
 214  
 
 215  
    /**************************************************************************
 216  
     * LISTE_INST
 217  
     **************************************************************************/
 218  
         void verifier_LISTE_INST(Arbre a) throws ErreurVerif {
 219  153
                 switch (a.getNoeud()) {
 220  
                         case Vide: 
 221  33
                         break; 
 222  
                         case ListeInst:
 223  120
                                 verifier_LISTE_INST(a.getFils1()); 
 224  73
                                 verifier_INST(a.getFils2());
 225  50
                         break;
 226  
                         
 227  
                         default: 
 228  0
                                 throw new ErreurInterneVerif("Arbre incorrect dans verifier_LISTE_INST"); 
 229  
                 } 
 230  83
         }
 231  
         
 232  
         private Type verifier_IDENT_FACTEUR(Arbre a) throws ErreurVerif{
 233  55
                 if (!estFeuille(a))
 234  0
                         throw new ErreurInterneVerif("Abre incorrect dans verifier_IDENT_PLACE");
 235  55
                 Defn def = env.chercher(a.getChaine()); // On vérifie si c'est bien un type définit
 236  
 
 237  
                 // Regarde dans la table d'environnement si le type a bien été défini et si c'est bien un type (pas une valeur comme true)
 238  55
                 if (def == null) 
 239  0
                         ErreurContext.ErreurTypeNonDeclare.leverErreurContext(a.getChaine(), a.getNumLigne());
 240  55
                 else if (def.getNature() != NatureDefn.Var && def.getNature() != NatureDefn.ConstBoolean
 241  0
                                 && def.getNature() != NatureDefn.ConstInteger) {
 242  0
                         ErreurContext.ErreurIdentificateurVarOuConstanteAttendu.leverErreurContext(a.getChaine(), a.getNumLigne());
 243  
                 }
 244  
                 
 245  55
                 a.setDecor(new Decor(def, def.getType()));// On décore l'abre
 246  
                 
 247  55
                 return def.getType();
 248  
         }
 249  
         
 250  
         
 251  
         private Type verifier_EXP(Arbre a) throws ErreurVerif {
 252  
                 Type t1, t2;
 253  
                 ResultatBinaireCompatible compBin;
 254  118
                 Type result = null;
 255  236
                 switch (a.getNoeud()) {
 256  
                         case Entier:// Pour aller dans FACTEUR
 257  35
                                 if (!estFeuille(a))
 258  0
                                         throw new ErreurInterneVerif("Abre incorrect dans verifier_FACTEUR");
 259  35
                                 a.setDecor(new Decor(Type.Integer));
 260  35
                                 result = Type.Integer;
 261  35
                         break;
 262  
                         case Reel:
 263  0
                                 if (!estFeuille(a))
 264  0
                                         throw new ErreurInterneVerif("Abre incorrect dans verifier_FACTEUR");
 265  0
                                 a.setDecor(new Decor(Type.Real));
 266  0
                                 result = Type.Real;
 267  0
                         break;
 268  
                         case Chaine:
 269  11
                                 if (!estFeuille(a))
 270  0
                                         throw new ErreurInterneVerif("Abre incorrect dans verifier_FACTEUR");
 271  11
                                 a.setDecor(new Decor(Type.String));
 272  11
                                 result = Type.String;
 273  11
                         break;
 274  
                         case Index:
 275  
                                 //result = verifier_FACTEUR(a);
 276  3
                                 t1 = verifier_PLACE(a.getFils1());
 277  3
                                 t2 = verifier_EXP(a.getFils2());
 278  3
                                 compBin = ReglesTypage.binaireCompatible(a.getNoeud(), t1, t2);
 279  3
                                 if (!compBin.getOk())
 280  0
                                         ErreurContext.ErreurOperationIncompatible.leverErreurContext(a.getNoeud().toString(), a.getNumLigne());
 281  3
                                 a.setDecor(new Decor(compBin.getTypeRes()));
 282  3
                                 result = compBin.getTypeRes();
 283  3
                         break;
 284  
                         case Ident:
 285  55
                                 result = verifier_IDENT_FACTEUR(a); //TODO Verifier qu'il fasse pas faire un FACTEUR
 286  55
                         break; 
 287  
                         case Et:
 288  
                         case Ou:
 289  
                         case Egal:
 290  
                         case InfEgal:
 291  
                         case SupEgal:
 292  
                         case NonEgal:
 293  
                         case Inf:
 294  
                         case Sup:
 295  
                         case Plus:
 296  
                         case Moins:
 297  
                         case Mult:
 298  
                         case DivReel:
 299  
                         case Reste:
 300  
                         case Quotient:
 301  12
                                 t1 = verifier_EXP(a.getFils1());
 302  12
                                 t2 = verifier_EXP(a.getFils2());
 303  12
                                 compBin = ReglesTypage.binaireCompatible(a.getNoeud(), t1, t2);
 304  
                                 /*System.out.println("("+t1.getNature().toString()
 305  
                                                 + " " + t2.getNature().toString() + ") = "+compBin.getOk());*/
 306  12
                                 if (!compBin.getOk())
 307  4
                                         ErreurContext.ErreurOperationIncompatible.leverErreurContext(a.getNoeud().toString() + "("+t1.getNature().toString()
 308  2
                                                         + " " + t2.getNature().toString() + ")", a.getNumLigne());
 309  10
                                 a.setDecor(new Decor(compBin.getTypeRes()));
 310  10
                                 result = compBin.getTypeRes();
 311  10
                         break;
 312  
                         case PlusUnaire:
 313  
                         case MoinsUnaire:
 314  
                         case Non:
 315  2
                                 Type t = verifier_EXP(a.getFils1());
 316  2
                                 ResultatUnaireCompatible compUn = ReglesTypage.unaireCompatible(a.getNoeud(), t);
 317  2
                                 if (!compUn.getOk())
 318  1
                                         ErreurContext.ErreurOperationIncompatible.leverErreurContext(a.getNoeud().toString(), a.getNumLigne());
 319  1
                                 a.setDecor(new Decor(compUn.getTypeRes()));
 320  1
                                 result = compUn.getTypeRes();
 321  1
                         break;
 322  
                         
 323  
                         default:
 324  0
                                 throw new ErreurInterneVerif("Arbre incorrect dans verifier_EXP" + a.getNoeud().toString());
 325  
                 }
 326  115
                 return result;
 327  
         }
 328  
         
 329  
         /**
 330  
          * 
 331  
          * Note : est aussi utilisé dans PLACE
 332  
          * @param a
 333  
          * @return
 334  
          * @throws ErreurVerif
 335  
          */
 336  
         private Type verifier_IDENT_PLACE(Arbre a) throws ErreurVerif {
 337  63
                 if (!estFeuille(a))
 338  0
                         throw new ErreurInterneVerif("Abre incorrect dans verifier_IDENT_PLACE");
 339  63
                 Defn def = env.chercher(a.getChaine()); // On vérifie si c'est bien un type définit
 340  
 
 341  
                 // Regarde dans la table d'environnement si le type a bien été défini et si c'est bien un type (pas une valeur comme true)
 342  63
                 if (def == null) 
 343  2
                         ErreurContext.ErreurTypeNonDeclare.leverErreurContext(a.getChaine(), a.getNumLigne());
 344  61
                 else if (def.getNature() != NatureDefn.Var) {
 345  0
                         ErreurContext.ErreurIdentificateurVarAttendu.leverErreurContext(a.getChaine(), a.getNumLigne());
 346  
                 }
 347  
                 
 348  61
                 a.setDecor(new Decor(def, def.getType()));// On décore l'abre
 349  
                 
 350  61
                 return def.getType();
 351  
                         
 352  
         }
 353  
         
 354  
         private Type verifier_PLACE(Arbre a) throws ErreurVerif {
 355  61
                 Type result = null;
 356  
                 
 357  61
                 switch (a.getNoeud()) {
 358  
                         case Ident:
 359  56
                                 result = verifier_IDENT_PLACE(a);
 360  54
                         break; 
 361  
                         case Index:
 362  5
                                 Type t1 = verifier_PLACE(a.getFils1());
 363  3
                                 Type t2 = verifier_EXP(a.getFils2()); //TODO Coder cette partie
 364  3
                                 ResultatBinaireCompatible comp = ReglesTypage.binaireCompatible(a.getNoeud(), t1, t2);
 365  3
                                 if (!comp.getOk())
 366  0
                                         ErreurContext.ErreurAffectionIncompatible.leverErreurContext(t1.getNature().toString()+ "("+a.getFils1().getNoeud().toString()+")" + " & "+t2.getNature().toString(), a.getNumLigne());
 367  3
                                 if (comp.getConv2()){
 368  0
                                         Arbre nc = Arbre.creation1(Noeud.Conversion, a.getFils(2), a.getNumLigne());
 369  0
                                         a.setFils(2, nc);
 370  0
                                         nc.setDecor(new Decor(t1));
 371  
                                 }
 372  3
                                 result = t2;
 373  3
                         break;
 374  
                         
 375  
                         default: 
 376  0
                                 throw new ErreurInterneVerif("Arbre incorrect dans verifier_PLACE"); 
 377  
                 }
 378  
                 
 379  57
                 return result;
 380  
         }
 381  
         
 382  
         private Type verifier_PAS(Arbre a) throws ErreurVerif {
 383  7
                 Type result = null;
 384  7
                 switch (a.getNoeud()) {
 385  
                         case Increment:
 386  
                         case Decrement:
 387  7
                                 Type t1 = verifier_IDENT_PLACE(a.getFils1()); //NOTE: C'est le même donc on réutilise
 388  7
                                 Type t2 = verifier_EXP(a.getFils2());
 389  7
                                 Type t3 = verifier_EXP(a.getFils3());
 390  7
                                 if ((t1.getNature() != NatureType.Interval)
 391  6
                                                 || (t2.getNature() != NatureType.Interval)
 392  5
                                                 || (t3.getNature() != NatureType.Interval)) {
 393  2
                                         ErreurContext.ErreurPasFor.leverErreurContext("", a.getNumLigne());
 394  
                                 }
 395  5
                                 result = t1;
 396  5
                                 break;
 397  
                         default:
 398  0
                                 throw new ErreurInterneVerif("Erreur de l'analyseur syntaxique");
 399  
                 }
 400  5
                 return result;
 401  
         }
 402  
         
 403  
         private void verifier_LISTE_EXP(Arbre a) throws ErreurVerif {
 404  19
                 switch (a.getNoeud()) {
 405  
                         case ListeExp:
 406  19
                                 if (a.getFils1().getNoeud() != Noeud.Vide)
 407  12
                                         verifier_LISTE_EXP(a.getFils1());
 408  19
                                 Type t = verifier_EXP(a.getFils2());
 409  19
                                 if (t.getNature() != NatureType.Interval && t.getNature() != NatureType.Real
 410  13
                                                 && t.getNature() != NatureType.String)
 411  2
                                         ErreurContext.ErreurWrite.leverErreurContext(t.getNature().toString(), a.getNumLigne());
 412  0
                         break;
 413  
                 
 414  
                         default:
 415  0
                                 throw new ErreurInterneVerif("Arbre incorrect dans verifier_LISTE_EXP");
 416  
                 }
 417  17
         }
 418  
         
 419  
         private void verifier_INST(Arbre a) throws ErreurVerif {
 420  
                 Type t1, t2;
 421  73
                 switch (a.getNoeud()) {
 422  
                         case Nop: 
 423  0
                         break; 
 424  
                         case Affect:
 425  50
                                 t1 = verifier_PLACE(a.getFils1());
 426  48
                                 t2 = verifier_EXP(a.getFils2());
 427  45
                                 ResultatAffectCompatible comp = ReglesTypage.affectCompatible(t1, t2);
 428  45
                                 if (!comp.getOk())
 429  8
                                         ErreurContext.ErreurAffectionIncompatible.leverErreurContext(t1.getNature().toString() + " et "+t2.getNature().toString(), a.getNumLigne());
 430  37
                                 if (comp.getConv2()){
 431  3
                                         Arbre nc = Arbre.creation1(Noeud.Conversion, a.getFils(2), a.getNumLigne());
 432  3
                                         a.setFils(2, nc);
 433  3
                                         nc.setDecor(new Decor(t1));
 434  
                                 }
 435  
                                         
 436  37
                                 a.setDecor(new Decor(t1));
 437  37
                         break;
 438  
                         case Pour:
 439  7
                                 verifier_PAS(a.getFils1()); // Vérifie déjà que c'est un interval
 440  5
                                 verifier_LISTE_INST(a.getFils2());
 441  3
                         break;
 442  
                         case TantQue:
 443  1
                                 t1 = verifier_EXP(a.getFils1());
 444  1
                                 if (t1.getNature() != NatureType.Boolean) 
 445  0
                                         ErreurContext.ErreurCondition.leverErreurContext(a.getNoeud().toString(), a.getNumLigne());
 446  1
                                 verifier_LISTE_INST(a.getFils2());
 447  1
                         break;
 448  
                         case Si:
 449  4
                                 t1 = verifier_EXP(a.getFils1());
 450  4
                                 if (t1.getNature() != NatureType.Boolean) 
 451  1
                                         ErreurContext.ErreurCondition.leverErreurContext(a.getNoeud().toString(), a.getNumLigne());
 452  3
                                 verifier_LISTE_INST(a.getFils2());
 453  2
                                 verifier_LISTE_INST(a.getFils2());
 454  2
                         break;
 455  
                         case Ecriture:
 456  7
                                 verifier_LISTE_EXP(a.getFils1()); // La vérification de type se fait dans cette méthode
 457  5
                         break;
 458  
                         case Lecture:
 459  3
                                 t1 = verifier_PLACE(a.getFils1());
 460  3
                                 if (t1.getNature() != NatureType.Interval && t1.getNature() != NatureType.Real)
 461  2
                                         ErreurContext.ErreurLecture.leverErreurContext(t1.getNature().toString(), a.getNumLigne());
 462  0
                         break;
 463  
                         case Ligne:
 464  1
                         break;
 465  
                         
 466  
                         default:
 467  0
                                 throw new ErreurInterneVerif("Arbre incorrect dans verifier_INST");
 468  
                 }
 469  50
         }
 470  
 
 471  
 }