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