Cohérence du programme

Analyse lexicale, syntaxique et sémantique...
Preuve de programme...
Optimisation...
Cohérence dynamique...
Complétude...

Avant de générer un programme exécutable ou un module objet à partir d'un ou plusieurs fichiers source, Up ! Compiler réalise différentes étapes importantes qui sont présentées dans cette rubrique. Il s'agit de vérifier la correction et la cohérence du futur programme.

Voici la présentation des principales étapes. Celles-ci sont présentées succinctement dans les sujets suivants.

Lors de l'analyse lexicale, Up ! Compiler vérifie que les éléments du langage sont corrects. Voici une liste non exhaustive des vérifications effectuées lors de l'analyse lexicale : Lors de l'analyse syntaxique, Up ! Compiler vérifie que les éléments du langage sont enchaînés correctement en vue de constituer les instructions du programme. Voici une liste non exhaustive des vérifications effectuées lors de l'analyse syntaxique : L'erreur la plus courante produite à cette étape est l'erreur de syntaxe. En ce cas, Up ! Compiler présente l'élément lexical inattendu et énonce la liste des éléments lexicaux attendus à la place.

Dans le cas d'un fonctionnement interactif, Up ! Compiler propose lors de cette phase d'effectuer des corrections pour les erreurs de syntaxes déterministes :

Lors qu'une telle erreur est détectée, il est proposée de corriger automatiquement le source et l'analyse continue comme s'il n'y avait pas eu d'erreur. Lors de l'analyse sémantique, Up ! Compiler vérifie que la sémantique des instructions est respectée conformément à ce qui est défini dans le Manuel de Référence. Voici une liste non exhaustive des vérifications effectuées lors de l'analyse sémantique : Revenir au haut de la page...
Le programme est syntaxiquement et sémantiquement cohérent. Il peut compiler, mais ce n'est pas pour autant qu'il fonctionnera correctement ! Up ! Compiler analyse alors finement le déroulement des algorithmes en vue de détecter des situations menant à des erreurs certaines. Pour chaque traitement, il y a trois décisions possibles : Pour effectuer cette preuve de programme, Up ! Compiler utilise les règles énoncées ci-dessous. Certaines concernent la définition des opérateurs sur les types. Il est important de respecter leur propriété. Si un opérateur ne peut pas respecter une de ces propriétés attendues, alors il ne faut employer un opérateur mais une méthode basée sur une procédure ou une fonction.

Voici une liste non exhaustive des vérifications effectuées lors de la preuve de programme :

ExpressionExpression équivalenteCommentaire
A Et BB Et ACommutativité de Et
(A Et B) Et CA Et (B Et C)Associativité de Et
A Ou BB Ou ACommutativité de Ou
(A Ou B) Ou CA Ou (B Ou C)Associativité de Ou
A OuExclusif BB OuExclusif ACommutativité d'OuExclusif
(A OuExclusif B) OuExclusif CA OuExclusif (B OuExclusif C)Associativité d'OuExclusif
Non(Non A)ARéflexivité de Non
Non(A Et B)Non A Ou Non BTransformation booléenne
Non(A EtSi B)Non A OuSinon Non BTransformation booléenne
Non(A Ou B)Non A Et Non BTransformation booléenne
Non(A OuSinon B)Non A EtSi Non BTransformation booléenne
Non(A OuExclusif B)Non A OuExclusif Non BTransformation booléenne
A & BB & ACommutativité de &
(A & B) & CA & (B & C)Associativité de &
A | BB | ACommutativité de |
(A | B) & CA | (B | C)Associativité de |
A + BB + ACommutativité de +
(A + B) & CA + (B | C)Associativité de +
A - BA + (- B)Elimination de -
- A + BB + (- A)Elimination de -
A - (B + C)(A - B) - CPseudo-associativité de -
A * BB * ACommutativité de *
(A * B) * CA * (B * C)Associativité de *
A / (B * C)(A / B) / CPseudo-associativité de /
(A + B) * CA * C + B * CDistributivité de + par rapport à *
(A - B) * CA * C - B * CDistributivité de - par rapport à *
(A + B) / CA / C + B / CDistributivité de + par rapport à /
(A - B) / CA / C - B / CDistributivité de - par rapport à /
A ^ (B * C)(A ^ B) ^ CPseudo-associativité de ^
- (- A)ARéflexivité de -
- (A + B)(- A) + (- B)Transformation arithmétique
- (A * B)(- A) * BTransformation arithmétique
- (A - B)(- A) + BTransformation arithmétique
- (A / B)(- A) / BTransformation arithmétique
A == BB == ACommutativité de ==
A != BB != ACommutativité de !=
A > BB < AInversion de la comparaison
A >= BB <= AInversion de la comparaison
Non (A > B)A <= BInversion de la comparaison
Non (A < B)A >= BInversion de la comparaison
Non (A >= B)A < BInversion de la comparaison
Non (A <= B)A > BInversion de la comparaison
Non (A == B)A != BInversion de la comparaison
Non (A != B)A == BInversion de la comparaison
A Entre B Et C(A >= B) Et (A <= C)Décomposition de Entre
A Dans (B, C)(A == B) Ou (A == C)Décomposition de Dans
A == B et B == CA == CTransitivité de ==
A < B et B < CA < CTransitivité de <
A <= B et B <= CA <= CTransitivité de <=
A < B et B == CA < CSemi-transitivité de <
A <= B et B == CA <= CSemi-transitivité de <=
A < B et A == CC < BSemi-transitivité de <
A <= B et A == CC <= BSemi-transitivité de <=
A == B et B != CA != CSemi-transitivité de ==

Revenir au haut de la page...
Up ! Compiler réalise des petites transformations au code intermédiaire issu de la vérification de programme. L'objectif est de rendre le programme plus performant : Il est possible d'influencer la tâche d'optimisation au moyen de l'instruction Optimiser. Celle-ci permet de signifier que le résultat d'un appel de procédure, de fonction ou de méthode est optimisable i.e. que deux appels successifs avec les mêmes paramètres produiront le même résultat sans effet de bord.

Toutes ces transformations sont sans incidence quant au bon fonctionnement du programme : elles le laissent inchangé. Néanmoins, aucune supposition ne doit être effectuée quand à l'ordre de l'évaluation des valeurs passées en paramètre à une fonction, une procédure, une méthode ou à un opérateur.

Il peut arriver que le premier paramètre soit évalué avant le second. Mais le contraire est possible. De plus, si le second paramètre est composée d'une expression, il est possible qu'une partie de l'expression du second paramètre soit évaluée, puis la valeur du premier paramètre est calculée puis, enfin, la fin de l'expression du second paramètre soit évaluée !

Il est cependant possible de définir des tests orientés. Voici des situations où cela est nécessaire :

Les tests orientés sont construits avec les instructions EtSi et OuSinon au lieu des instructions Et et Ou. L'ordre d'évaluation des deux sous-conditions est garanti pour les instructions EtSi et OuSinon alors qu'il n'est pas garanti pour les instructions Et et Ou.

Revenir au haut de la page...
Lors de la phase de preuve de programme, il y a trois décisions possibles pour chaque traitement : Dans le cas indéterministe, Up ! Compiler ajoute du code permettant de vérifier à l'exécution la cohérence dynamique du programme. Ainsi les tests suivants sont ajoutés : En cas d'erreur détectée à l'exécution, une exception est envoyée précisant le nom du fichier source, le numéro de ligne et colonne à l'origine de l'erreur. Cette exception peut être rattrapée au moyen de l'instruction AttraperException.

Ces tests sont particulièrement pertinents lors de la mise au point du programme. Ils permettent d'éciter les arrêts violents des programmes (General Protection Fault (GPF), Segment Violation, etc.).

Revenir au haut de la page...

Avant de générer le code objet, Up ! Compiler vérifie que le code du futur programme ou du futur module est complet. Il vérifie notamment que : Revenir au haut de la page...