COBOL - Chapitre 5 - Alternatives et débranchements
Date de publication : 24/01/2007 , Date de mise à jour : 07/02/2007
Par
Guillaume Ventre (Développement Mainframe) (Blog)
Nous allons aborder dans ce chapitre les moyens COBOL traduisant les alternatives et débranchements algorithmiques.
1. L'alternative simple IF
1.1. Les conditions de relation
1.2. Les conditions de classes
1.2.1. Classes numériques et alphanumériques
1.2.2. Classes spécifiques à un programme
1.3. Les conditions de signe
1.4. Les conditions de nom-condition
1.4.1. Le niveau 88
1.4.2. L'instruction SET
1.5. L'instruction NEXT SENTENCE
1.6. L'instruction CONTINUE
2. Le débranchement inconditionnel GO TO
3. L'appel de module PERFORM
3.1. Syntaxe
3.2. Fonctionnement
3.3. Exemple 1
3.4. Exemple 2
3.5. L'instruction EXIT
4. L'alternative complexe EVALUATE
5. Les boucles: les autres formats du PERFORM
5.1. PERFORM ... TIMES
5.2. PERFORM ... UNTIL
5.3. PERFORM ... VARYING ... UNTIL
5.4. PERFORM ouvert
6. Remerciements
1. L'alternative simple IF
Elle permet de traduire la structure alternative Si ... sinon ... finsi de l'algorithmique.
Syntaxe |
IF condition
instruction-1
[ELSE
instruction-2]
END-IF
|
 |
Le SCOPE-TERMINATOR END-IF n'existait pas en COBOL 74, c'est le point (.) qui fermait tous les IF ouverts.
|
L'imbrication des alternatives doit être manipulée avec discernement :
- trop de niveaux (+ de 3) amènent de très sérieux problèmes de compréhension,
- on peut limiter les niveaux en utilisant des appels à des modules internes (instruction PERFORM),
- on peut remplacer des alternatives imbriquées par une succession d'alternatives simples comportant des conditionnements booléens. En contrepartie, on risque d'oublier certaines branches.
1.1. Les conditions de relation
Les opérateurs autorisés sont: >, >= , <, <= , =, NOT, OR et AND.
 |
Certains compilateurs accèptent l'opérateur "différent" écrit sous la forme: <>. Préférez l'utilisation de cette opérateur sous sa forme: NOT =, vous vous garantissez ainsi de prendre une habitude d'écriture qui sera acceptée partout... vous gagnerez du temps.
|
Quelques exemples:
IF A = 2
MOVE B TO C
END-IF.
|
IF A > B
ADD 2 TO B
ELSE
ADD 2 TO C
END-IF.
|
Les comparaisons se font selon la séquence ASCII ou EBCDIC:
- en ASCII: espace < chiffres < lettres
- en EBCDIC: espace < lettres < chiffres
Ce chapitre du cours COBOL n'a pas pour vocation de vous expliquer la théorie logique du calcul des propositions, mais nous allons toutefois faire un petit rappel important concernant la loi de Morgan car c'est un piège classique pour tout développeur débutant:
La négation d'une conjonction de deux propositions est équivalente à la disjonction des négations des deux propositions.
La négation d'une disjonction de deux propositions est équivalente à la conjonction des négations des deux propositions.
Autrement dit:
Loi de Morgan |
NON (A ou B) = NON A et NON B
NON (A et B) = NON A ou NON B
|
Exemple: si vous souhaitez tester la non-condition Si situation familliale différente de célibataire OU différente de veuf OU différente de marié alors... finsi vous serez tenté de coder comme suit:
Codage erroné |
IF SITU-FAMILLE NOT = 'C' OR
SITU-FAMILLE NOT = 'V' OR
SITU-FAMILLE NOT = 'M'
[...]
END-IF.
|
En fait, avec la loi de Morgan, il faut coder ainsi:
Codage correct |
IF SITU-FAMILLE NOT = 'C' AND
SITU-FAMILLE NOT = 'V' AND
SITU-FAMILLE NOT = 'M'
[...]
END-IF.
|
1.2. Les conditions de classes
1.2.1. Classes numériques et alphanumériques
Syntaxe |
NUMERIC
nom-donnée-1 [NOT]
ALPHABETIC
|
Cette condition permet de tester si le nom-donnée de la condition contient des chiffres ou des lettres.
Exemple:
IF MONTANT NUMERIC
SUBTRACT MONTANT TO TOTAL GIVING NOUVEAU-SOLDE
ELSE
MOVE ANCIEN-SOLDE TO NOUVEAU-SOLDE
END-IF.
|
1.2.2. Classes spécifiques à un programme
Syntaxe |
CLASS nom [IS] littéral-1 [THRU littéral-2] littéral-3 [THRU littéral-4]...
.
|
Les classes ainsi définies peuvent ensuite être utilisées pour tester si le contenu d'une variable est valide.
Exemple:
CONFIGURATION SECTION.
SPECIAL-NAMES.
CLASS DATE-AVEC-SEPARATEUR IS '0' THRU '9' '-' '/'.
...
PROCEDURE DIVISION.
IF DATE-MVT DATE-AVEC-SEPARATEUR
DISPLAY DATE-MVT
ELSE
DISPLAY 'LA DATE EST ERRONEE'
END-IF.
|
 |
Les classes ainsi définies ne sont utilisables que sur des variables alphanumériques.
Il faut un point unique pour clôturer le paragraphe SPECIAL-NAMES (il n'y a pas de point intermédiaire, même si plusieurs classes sont définies pour un programme).
|
1.3. Les conditions de signe
Syntaxe |
POSITIVE
Opérande-1 [NOT] NEGATIVE
ZERO
|
Cette condition permet de tester si un opérande de la condition est positif, négatif, égal ou différent de zéro.
Exemple:
IF SOLDE POSITIVE
MOVE '+' TO SOLDE-AFFICH-SIGNE
END-IF.
|
IF SOLDE ZERO
MOVE SPACE TO RESULT
END-IF.
|
1.4. Les conditions de nom-condition
Cette condition a l'avantage d'être très parlante. On l'utilise d'ailleurs très souvent pour positionner des "flags" ou des "tops" durant le déroulement d'un programme afin de mémoriser l'état d'une action à un moment "t".
1.4.1. Le niveau 88
Syntaxe |
88 nom-condition-1 VALUE littérale-1 [THRU littérale-2] [,littérale-3 [THRU littérale-4]...].
|
 |
La virgule est importante dans le cas où vous utilisez plus d'une valeur ou plage de valeur.
|
Premier exemple, vérification de la validité d'un compte:
DATA DIVISION.
01 COMPTES.
05 NOM PIC X(20).
05 PRENOM PIC X(20).
05 NUM-COMPTE PIC 9(10).
88 COURANT VALUE 1000000000 THRU 1999999999.
88 PEL VALUE 2000000000 THRU 2999999999.
88 CODEVI VALUE 3000000000 THRU 3999999999.
88 TITRE VALUE 4000000000 THRU 4999999999.
88 COMPTE-CORRECT VALUE 1000000000 THRU 4999999999.
[...]
PROCEDURE DIVISION.
IF NOT COMPTE-CORRECT
DISPLAY '*** ERREUR TYPE DE COMPTE INCONNU: ' NUM-COMPTE
DISPLAY '*** CLIENT: ' NOM ' ' PRENOM
END-IF.
|
Deuxième exemple, positionnement d'un flag pour mémoriser le fait qu'une personne a été traiter en amont du programme:
DATA DIVISION.
01 FLAG-PERSONNE PIC X(2).
88 PERS-OK VALUE 'OK'.
88 PERS-KO VALUE 'KO'.
[...]
PROCEDURE DIVISION.
[...]
MOVE 'OK' TO FLAG-PERSONNE.
[...]
IF PERS-OK
PERFORM TRAIT-COMPLET-PERSONNE
ELSE
PERFORM TRAIT-LIGHT-PERSONNE
END-IF.
|
 |
Notez que les niveaux 88 qualifient toujours le niveau hiérarchique supérieur. Dans le premier exemple, les niveaux 88 qualifient le niveau 05 NUM-COMPTE, dans le deuxième exemple, ils qualifient le niveau 01 FLAG-PERSONNE.
|
1.4.2. L'instruction SET
Pour rendre le code encore plus "parlant", on peut utiliser l'instruction SET avec les niveaux 88.
Syntaxe |
SET nom-condition TO TRUE.
|
Cette instruction permet d'initialiser la zone groupe associée au nom-condition à la valeur de ce nom-condition.
En reprenant le deuxième exemple, au lieu de:
MOVE 'OK' TO FLAG-PERSONNE.
|
On aurait:
1.5. L'instruction NEXT SENTENCE
En COBOL 85, la structure suivante :
Si Condition-1
| Si Condition-2
| | Traitement-1
| Fin si
Sinon
| Traitement-2
Fin si
|
Peut s'écrire ainsi:
IF condition-1
IF condition-2
PERFORM TRAITEMENT-1 THRU FIN-TRAITEMENT-1
END-IF
ELSE
PERFORM TRAITEMENT-2 THRU FIN-TRAITEMENT-2
END-IF.
|
En COBOL 74, du fait de l'absence du SCOPE-TERMINATOR END-IF, cette structure est intraduisible directement.
Le compilateur interprète le ELSE comme se rapportant au dernier IF, d'où l'obligation de coder une branche vide au deuxième IF à l'aide de NEXT SENTENCE:
IF condition-1
IF condition-2
PERFORM TRAITEMENT-1 THRU FIN-TRAITEMENT-1
ELSE
NEXT-SENTENCE
ELSE
PERFORM TRAITEMENT-2 THRU FIN-TRAITEMENT-2
.
|
 |
NEXT SENTENCE provoque un débranchement après le prochain point.
|
1.6. L'instruction CONTINUE
CONTINUE est une instruction que l'on peut également coder dans une branche vide d'un test. CONTINUE diffère de NEXT SENTENCE du fait que cette instruction a pour conséquence un débranchement au prochain ordre cobol et non à la prochaine phrase (soit après un point).
2. Le débranchement inconditionnel GO TO
GO TO permet de traduire l'instruction de débranchement inconditionnel "Aller à".
Dans une programmation structurée, on doit éviter l'usage du GO TO. D'ailleurs sur certains sites, les compilateurs sont paramétrés pour empêcher l'usage du GO TO et renvoient un code d'erreur sévère (12).
Sans faire un délire paranoïde sur le GO TO, son usage peut se justifier pour une sortie de programme du type "ALLER A LA FIN".
Le débranchement s'effectue à un nom de paragraphe (une étiquette) codée en colonne 8 avant ou après l'instruction GO TO. Exemple:
IF TRAITEMENT-KO
GO TO FIN-PROGRAMME
END-IF.
[...]
FIN-PROGRAMME.
DISPLAY 'FIN DE PROGRAMME'.
STOP RUN.
|
3. L'appel de module PERFORM
3.1. Syntaxe
Syntaxe |
PERFORM nom-paragraphe-1 [THRU nom-paragraphe-2]
|
3.2. Fonctionnement
On exécute toutes les instructions du paragraphe A jusqu'au prochain paragraphe.
PERFORM A THRU C → A.
↓
B.
↓
C.
↓
D.
|
On exécute toutes les instructions des paragraphes A, B et C inclus.
3.3. Exemple 1
PROCEDURE DIVISION.
FO-DEBUT.
PERFORM F1-INIT.
STOP RUN.
F1-INIT.
MOVE ZERO TO A.
MULTIPLY C BY 6 GIVING D.
ADD D 5 TO B.
F2-SUIT.
|
Les instructions du paragraphe F1-INIT sont exécutées en séquence jusqu'au paragraphe suivant.
 |
Vous pouvez vous abstenir de mettre un point après chaque phrase COBOL, mais un point est obligatoire à la fin d'un paragraphe.
|
3.4. Exemple 2
PROCEDURE DIVISION.
01-PAR-A.
PERFORM 02-PAR-B THRU 02-FIN
STOP RUN
.
02-PAR-B.
MULTIPLY NUM-A BY NUM-B GIVING NUM-C ROUNDED
ON SIZE ERROR
DISPLAY 'ZONE NUM-C TROP PETITE'
PERFORM 02-FIN
END-MULTIPLY
ADD NUM-C 2 TO NUM-A
.
02-FIN.
ADD 3 TO NUM-B
ADD 1 TO I
MOVE NUM-B TO NUM-C
.
03-PAR-C.
|
On exécute toutes les instructions de 02-PAR-B et toutes celles de 02-FIN.
3.5. L'instruction EXIT
L'instruction EXIT indique qu'un paragraphe est vide. EXIT doit être le seul ordre d'un paragraphe. Exemple:
PROCEDURE DIVISION.
PERFORM DEBUT-PARAGRAPHE-1 THRU FIN-PARAGRAPHE-1.
DEBUT-PARAGRAPHE-1.
ADD 1 TO I
MOVE I TO WS-INDEX
DISPLAY 'OK'
.
FIN-PARAGRAPHE-1. EXIT.
DEBUT-PARAGRAPHE-2.
[...]
|
4. L'alternative complexe EVALUATE
C'est l'instruction COBOL qui permet de traduire le "choix selon" du pseudo-code et dont la représentation sous forme d'ordinogramme est la suivante :
|
________|_______
| |
| CODE PRODUIT |
|________________|
|
|
____________________________|___________________________
| | | |
| A | B | C | Autre
______|_______ ______|_______ ______|_______ ______|_______
| | | | | | | |
| traitement-A | | traitement-B | | traitement-C | | erreurs |
|______________| |______________| |______________| |______________|
| | | |
| | | |
|__________________|__________________|__________________|
|
|
|
|
En COBOL 74, cette structure complexe doit être découpée en une série de structures alternatives simples:
COBOL 74 |
PROCEDURE DIVISION.
IF CODE-PRODUIT = 'A'
PERFORM TRAIT-A THRU F-TRAIT-A
PERFORM SUITE
.
IF CODE-PRODUIT = 'B'
PERFORM TRAIT-B THRU F-TRAIT-B
PERFORM SUITE
.
IF CODE-PRODUIT = 'C'
PERFORM TRAIT-C THRU F-TRAIT-C
PERFORM SUITE
.
PERFORM TRAIT-ERREUR THRU F-TRAIT-ERREUR.
SUITE.
[...]
|
En COBOL 85, on peut traiter cette figure algorithmique en une seule instruction à l'aide d'EVALUATE:
COBOL 85 |
PROCEDURE DIVISION.
EVALUATE CODE-PRODUIT
WHEN A PERFORM TRAIT-A THRU F-TRAIT-A
WHEN B PERFORM TRAIT-B THRU F-TRAIT-B
WHEN C PERFORM TRAIT-C THRU F-TRAIT-C
WHEN OTHER PERFORM TRAIT-ERREUR THRU F-TRAIT-ERREUR.
END-EVALUATE.
SUITE.
[...]
|
La syntaxe de l'instruction EVALUATE est la suivante:
Syntaxe |
nom-donnée-1 nom-donnée-2
EVALUATE expression-1 [ALSO expression-2 ]...
TRUE/FALSE TRUE/FALSE
ANY ANY
littéral-1 littéral-4
condition-1 condition-2
WHEN TRUE/FALSE [ALSO TRUE/FALSE ]...
nom-donnée-3 nom-donnée-4
littéral-2 littéral-5
THRU littéral-3 THRU littéral-6
ordre(s)-1
[WHEN...]...
[WHEN OTHER
ordre(s)-2]
END-EVALUATE.
|
Lorsque les mots-clés TRUE et FALSE sont utilisés, cela suppose que des conditions ou des expressions sont utilisées dans les WHEN suivants.
ALSO permet de séparer plusieurs séries de tests.
Des exemples valent mieux qu'un long discours:
Exemple 1: EVALUATE TRUE |
DATA DIVISION.
05 RESULTAT PIC 9V9.
88 EXCELLENT VALUE 5,0.
88 BON VALUE 4,0 THRU 4,9.
88 MOYEN VALUE 2,5 THRU 3,9.
88 INSUFFISANT VALUE 1,9 THRU 2,4.
88 NUL VALUE 0 THRU 1,8.
PROCEDURE DIVISION.
EVALUATE TRUE
WHEN EXCELLENT PERFORM TRAIT-1 THRU F-TRAIT-1
WHEN NUL PERFORM TRAIT-2 THRU F-TRAIT-2
WHEN OTHER PERFORM TRAIT-3 THRU F-TRAIT-3
END-EVALUATE.
|
Exemple 2: EVALUATE nom-donnée |
DATA DIVISION.
05 RESULTAT PIC 9V9.
88 EXCELLENT VALUE 5,0.
88 BON VALUE 4,0 THRU 4,9.
88 MOYEN VALUE 2,5 THRU 3,9.
88 INSUFFISANT VALUE 1,9 THRU 2,4.
88 NUL VALUE 0 THRU 1,8.
PROCEDURE DIVISION.
EVALUATE RESULTAT
WHEN 5,0 PERFORM TRAIT-1 THRU F-TRAIT-1
WHEN 0 THRU 1,8 PERFORM TRAIT-2 THRU F-TRAIT-2
WHEN OTHER PERFORM TRAIT-3 THRU F-TRAIT-3
END-EVALUATE.
|
Exemple 3: EVALUATE expression |
DATA DIVISION.
05 RESULTAT PIC 9V9.
88 EXCELLENT VALUE 5,0.
88 BON VALUE 4,0 THRU 4,9.
88 MOYEN VALUE 2,5 THRU 3,9.
88 INSUFFISANT VALUE 1,9 THRU 2,4.
88 NUL VALUE 0 THRU 1,8.
PROCEDURE DIVISION.
EVALUATE RESULTAT <= 1,8
WHEN TRUE PERFORM TRAIT-2 THRU F-TRAIT-2
WHEN FALSE PERFORM ...
END-EVALUATE.
|
Exemple 4: EVALUATE avec ALSO |
PROCEDURE DIVISION.
EVALUATE A = B ALSO C > D ALSO TRUE
WHEN TRUE ALSO TRUE ALSO E = F + 15
PERFORM TRAIT-1 THRU F-TRAIT-1
WHEN TRUE ALSO TRUE ALSO E > 12
PERFORM TRAIT-2 THRU F-TRAIT-2
WHEN TRUE ALSO FALSE ALSO ANY
PERFORM TRAIT-3 THRU F-TRAIT-3
WHEN FASLE ALSO TRUE ALSO ANY
PERFORM TRAIT-4 THRU F-TRAIT-4
WHEN OTHER
PERFORM TRAIT-5 THRU F-TRAIT-5
END-EVALUATE.
|
5. Les boucles: les autres formats du PERFORM
Dans sa syntaxe simple, nous avons vu que le PERFORM permettait d'appeler un module, puis de reprendre l'exécution en séquence. D'autres syntaxes du PERFORM permettent d'effectuer ces appels un certain nombre de fois et/ou de préciser des conditions d'arrêt de boucle.
5.1. PERFORM ... TIMES
C'est l'instruction Cobol qui permet de traduire le "répeter ... fin-répéter" du pseudo-code.
Syntaxe |
PERFORM nom-paragraphe-1 [THRU nom-paragraphe-2] n TIMES
|
n peut être une constante ou une variable numérique entière.
Exemple:
PERFORM TRAIT-CLIENT 3 TIMES.
|
Le paragraphe TRAIT-CLIENT est exécuté 3 fois d'affilé.
5.2. PERFORM ... UNTIL
Syntaxe |
PERFORM nom-paragraphe-1 [THRU nom-paragraphe-2]
[WITH TEST BEFORE]
[WITH TEST AFTER]
UNTIL condition
|
La clause WITH TEST BEFORE ou WITH TEST AFTER permet de préciser la position du test. Par défaut, la clause est WITH TEST BEFORE.
La condition spécifiée après le UNTIL peut prendre toutes les formes autorisées dans l'instruction IF. C'est une condition d'arrêt de la boucle.
Exemples:
WITH TEST BEFORE |
PERFORM TRAITEMENT UNTIL A = 15
|
WITH TEST AFTER |
PERFORM TRAITEMENT WITH TEST AFTER UNTIL A = 15
|
 |
La structure algorithmique "tant-que ... fin-tant-que" n'est pas traduisible en COBOL au sens strict car dans le "tant-que", la condition exprimée est une condition de continuation.
En inversant la condition du "tant-que" de l'algorithmique et en utilisant le PERFORM WITH TEST BEFORE, on obtient un "tant-que" à la sauce COBOL !
La structure "répéter ... jusqu'à" est traduisible en utilisant WITH TEST AFTER.
|
5.3. PERFORM ... VARYING ... UNTIL
Syntaxe |
PERFORM nom-paragraphe-1 [THRU nom-paragraphe-2]
VARYING nom-donnée FROM valeur-initiale BY pas
UNTIL condition
|
En plus des fonctionnalités du PERFORM ... UNTIL, le PERFORM ... VARYING ... UNTIL permet d'incrémenter une variable numérique à chaque débranchement.
- nom-donnée permet de préciser le nom de la variable à incrémenter.
- valeur-initiale indique la valeur d'initialisation de cette variable (valeur prise au premier débranchement).
- pas précise la valeur d'incrémentation prise par la variable à chaque itération; la valeur spécifiée peut être négative.
Exemple:
PERFORM TRAITEMENT VARYING I FROM 5 BY 1
UNTIL I > 20.
|
I prendra successivement les valeurs 1, 2, 3, 4 ... 20, 21. Pour cette dernière valeur le débranchement ne sera pas effectué, le test d'arrêt de boucle étant vérifié.
Cet exemple permet de mettre en valeur 3 points importants:
- Attention à la déclaration de la variable I. Dans l'exemple précédent I doit être déclaré au moins sur deux caractères numériques sinon la boucle est une boucle infinie.
- A la sortie de la boucle, I vaut le premier nombre pour lequel le test a été vérifié. Dans l'exemple précédent l'instruction DISPLAY I après le PERFORM donnerait le résultat 21.
- Il est fortement déconseillé de modifier la valeur de I à l'intérieur du PERFORM. Dans l'exemple précédent si I est réinitialisé dans le paragraphe TRAITEMENT, la boucle est infinie.
5.4. PERFORM ouvert
Les différentes syntaxes du PERFORM que nous venons d'étudier sont utilisées pour exprimer un débranchement à un module donné.
Il est possible de ne pas générer de débranchement et de coder les instructions à exécuter à l'intérieur du PERFORM, c'est-à-dire entre le verbe PERFORM et le SCOPE-TERMINATOR END-PERFORM. On parle alors de PERFORM in-line ou PERFORM ouvert.
Exemple:
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10
MOVE ZERO TO NUM (I)
MOVE SPACE TO ALPHA (I)
END-PERFORM.
|
6. Remerciements


Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ©
2006-2007 Guillaume Ventre. Aucune reproduction, même partielle, ne peut être
faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à
trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.