12.7.2 制御ブロックの解析方針
制御フローを考慮した解析では,制御フローをたどりながら解析します。
制御フローの記述順序に従って,文から文へと制御を移行して,ほかへ制御を移行しない範囲を制御ブロックといいます。そのため,制御フローを考慮した解析では,制御ブロック中の文は記述順序のとおりに実行されるものとして扱います。
制御ブロックの移行
制御ブロック間で制御の移行が発生する文があります。制御の移行が発生する文を次に示します。
分類 |
制御の移行が発生する文 |
|
---|---|---|
制御の明示移行 |
手続き分岐文 |
|
条件文 |
|
|
制御の暗黙移行 |
|
|
プログラム制御 |
|
制御フローを考慮した解析では,プログラムの制御は,外部プログラムまたは内部プログラムをわたって,そのプログラムの引数まで解析します。
制御の移行が発生する文ごとに,制御の移行について説明します。
-
CONTINUE文の明示移行
CONTINUE文は無操作文で,実行に何の影響も及ぼしません。そのため,制御フローを考慮した解析では,制御ブロックに関係しないと判断します。
-
GO TO文の明示移行
-
GO TO文で段落"PARA-2"に制御が移行します。
-
-
PERFORM文の明示移行と暗黙移行
- そとPERFORM文の例
-
1. そとPERFORM文で段落"PARA-2"に制御が移行します。
2. PERFORM文の制御下で,その制御範囲内にある段落の最後の文(DISPLAY "PARAGRAPH B".)を実行したあと,制御文へ制御の暗黙移行をします。
- うちPERFORM文(ループ)の例
-
1. 繰り返し実行を起こすPERFORM文の制御下で実行中であり,そのPERFORM文に関連する制御機構とその段落の最初の文との間で,段落の繰り返し実行のたびに,制御の暗黙移行をします。
- そとPERFORM文(ループ)の例
-
1. そとPERFORM文で段落"PARA-1"に制御が移行します。
2. 繰り返し実行を起こすPERFORM文の制御下で実行中であり,そのPERFORM文に関連する制御機構とその段落の最初の文との間で,段落の繰り返し実行のたびに,制御の暗黙移行をします。
- そとPERFORM文(THRU構文)の例
-
1. そとPERFORM文で段落"PARA-1"に制御が移行します。
2. 段落"PARA-1"から処理が続く段落"PARA-2"に制御が移行します。
2. PERFORM文の制御下で,その制御範囲内にある段落"PARA-2"の最後の文(DISPLAY "PARAGRAPH B".)を実行したあと,制御文へ制御の暗黙移行をします。
- 注意事項
-
PERFORM文の制御の移行を実装する場合は,初期化漏れチェック機能の情報を参照してください。詳細は,マニュアル「COBOL2002 ユーザーズガイド」の「初期化漏れチェック機能」を参照してください。
-
EVALUATE文の明示移行
-
EVALUATE文の選択主体(データ項目:A)に対してWHENの選択対象が評価され,選択されたWHEN指定に制御が移行します。
-
EVALUATE文の選択主体(データ項目:A)に対してどのWHEN指定も選択されない場合に,WHEN OTHER指定があるときは,WHEN OTHER指定に制御が移行します。
-
各WHEN指定の最後のブロックの文からEND-EVALUATEへ制御の暗黙移行をします。
-
-
IF文の明示移行
-
IF文の条件が真の場合,THEN節に制御が移行します。
-
THEN指定のブロック内の最後の文からEND-IFへ制御の暗黙移行をします。
-
IF文の条件が偽の場合にELSE節があるときは,ELSE節に制御が移行します。
-
-
MERGE文の暗黙移行
-
MERGE文を実行する場合は,関連する入出力手続きへ制御の暗黙移行をします。
-
-
SORT文の暗黙移行
-
SORT文を実行する場合は,関連する入出力手続きへ制御の暗黙移行をします。
-
-
USE文の暗黙移行
USE文は,手続きの実行の条件を指定するための文で,USE文が実行されることはありません。USE文で指定される段落は,その段落内の行が調査起点として指定されたときだけ解析し,その段落内だけが解析対象となります。
-
EXIT文の制御移行
-
CALL文の引数の「SUB」が呼び出し対象プログラムとなり,プログラム呼び出しが成功した場合,制御が移行します。
-
EXIT文(GOBACK文含む)などのプログラム単位を終了する文がある場合,その先の文は無視して,呼び出し先プログラム(SUB)から呼び出し元のプログラムのCALL文の終わりに制御が移行します。
-
-
ALTER文の制御移行
ALTER文で行き先が変更となるGO TO文がある場合は,そのGO TO文によって制御を移行する可能性があるすべてのブロックを分岐ブロックとします。
PERFORM文によるループ区間の解析
制御フローを考慮した解析では,PERFORM文によるループ区間の途中から解析をする場合は,次のように解析します。
-
影響波及元解析の場合
-
解析の基点となる実行文から,ループ区間の開始までを解析します。
-
ループ区間の終了から,解析の基点となる実行文の直後までを解析します。
-
ループ区間の開始以前を解析します。
-
-
影響波及先解析の場合
-
解析の基点となる実行文から,ループ区間の終了までを解析します。
-
ループ区間の開始から,解析の基点となる実行文の直前までを解析します。
-
ループ区間の終了以降を解析します。
-
影響波及先解析の場合の例を次に示します。
- (例)「Move A TO B」の「A」が解析の基点で,影響波及先解析の場合の例
-
この例では,次のように解析します。
-
解析の基点となる実行文(MOVE A TO B)から,ループ区間の終了(MOVE B TO C)までを解析します。
-
ループ区間の開始(MOVE C TO D)から,解析の基点となる実行文の直前(MOVE D TO E)までを解析します。
-
ループ区間の終了(DISPLAY A.)以降を解析します。
-
選択可能な条件指定ができる手続き文の対応
手続き文には,選択可能な条件が指定できる手続き文があります。選択可能な条件指定ができる手続き文の場合,制御フローを考慮した解析では,次の表に示すように対応します。
- 注意事項
-
実行文の条件を評価した結果,コンパイラで不要と判断された条件指定が削除される旨のメッセージが表示されることがあります。制御フローを考慮した解析では,COBOLソースファイル中のソースコードがそのまま解析されます。
文 |
コード例 |
制御フローを考慮した解析での対応 |
解析時に想定する制御フロー |
---|---|---|---|
ACCEPT文 |
<ブロックA> ACCEPT … ON EXCEPTION <ON EXCEPTIONブロック> NOT ON EXCEPTION <NOT ON EXCEPTIONブロック> END-ACCEPT <ブロックB> |
ON EXCEPTIONのブロックに移行する場合の制御フロー(1.)と,ACCEPT文の処理からNOT ON EXCEPTIONのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
ADD文 |
<ブロックA> ADD … TO … ON SIZE ERROR <ON SIZE ERRORブロック> NOT ON SIZE ERROR <NOT ON SIZE ERRORブロック> END-ADD <ブロックB> |
ON SIZE ERRORのブロックに移行する場合の制御フロー(1.)と,ADD文の処理からNOT ON SIZE ERRORのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
CALL文 |
<ブロックA> CALL … ON EXCEPTION <ON EXCEPTIONブロック> NOT ON EXCEPTION <NOT ON EXCEPTIONブロック> END-CALL <ブロックB> |
ON EXCEPTIONのブロックに移行する場合の制御フロー(1.)と,CALL文の処理からNOT ON EXCEPTIONのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
<ブロックA> CALL … ON OVERFLOW <ON OVERFLOWブロック> END-CALL <ブロックB> |
CALL文の制御フロー(1.)と,ON OVERFLOWのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
|
COMPUTE文 |
<ブロックA> COMPUTE … = … ON SIZE ERROR <ON SIZE ERRORブロック> NOT ON SIZE ERROR <NOT ON SIZE ERRORブロック> END-COMPUTE <ブロックB> |
ON SIZE ERRORのブロックに移行する場合の制御フロー(1.)と,COMPUTE文の処理からNOT ON SIZE ERRORのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
DELETE文 |
<ブロックA> DELETE … RECORD INVALID KEY <ON INVALID KEYブロック> NOT INVALID KEY <NOT INVALID KEYブロック> END-DELETE <ブロックB> |
ON INVALID KEYのブロックに移行する場合の制御フロー(1.)ともNOT ON INVALID KEYのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
DISPLAY文 |
<ブロックA> DISPLAY … UPON … ON EXCEPTION <ON EXCEPTIONブロック> NOT ON EXCEPTION <NOT ON EXCEPTIONブロック> END-DISPLAY <ブロックB> |
ON EXCEPTIONのブロックに移行する場合の制御フロー(1.)と,DISPLAY文の処理からNOT ON EXCEPTIONのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
DIVIDE文 |
<ブロックA> DIVIDE … INTO … ON SIZE ERROR <ON SIZE ERRORブロック> NOT ON SIZE ERROR <NOT ON SIZE ERRORブロック> END-DIVIDE <ブロックB> |
ON SIZE ERRORのブロックに移行する場合の制御フロー(1.)と,DIVIDE文の処理からNOT ON SIZE ERRORのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
EVALUATE文 |
<ブロックA> EVALUATE … WHEN … <WHENブロック1> : WHEN … <WHENブロックN> : WHEN OTHER <WHEN OTHERブロック> END-EVALUATE <ブロックB> |
それぞれのWHENのブロックに移行する場合の制御フロー(1.および2.)と,WHEN OTHERのブロックに移行する場合の制御フロー(3.)のそれぞれを想定して解析します。 |
|
IF文 |
<ブロックA> IF <判定文> THEN <THENのブロック> ELSE <ELSEのブロック> END-IF <ブロックB> |
THENのブロックに移行する場合の制御フロー(1.)と,ELSEのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
MULTIPLY文 |
<ブロックA> MULTIPLY … BY … ON SIZE ERROR <ON SIZE ERRORブロック> NOT ON SIZE ERROR <NOT ON SIZE ERRORブロック> END-MULTIPLY <ブロックB> |
ON SIZE ERRORのブロックに移行する場合の制御フロー(1.)と,MULTIPLY文の処理からNOT ON SIZE ERRORのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
READ文 |
<ブロックA> READ … RECORD … AT END <AT ENDブロック> NOT AT END <NOT AT ENDブロック> END-READ <ブロックB> |
READ文の処理からAT ENDのブロックに移行する場合の制御フロー(1.)と,READ文の処理からNOT AT ENDのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
RETURN文 |
<ブロックA> RETURN … RECORD … AT END <AT ENDブロック> NOT AT END <NOT AT ENDブロック> END-RETURN <ブロックB> |
RETURN文の処理からAT ENDのブロックに移行する場合の制御フロー(1.)と,RETURN文の処理からNOT AT ENDのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
REWRITE文 |
<ブロックA> REWRITE … INVALID KEY <ON INVALID KEYブロック> NOT INVALID KEY <NOT INVALID KEYブロック> END-REWRITE <ブロックB> |
ON INVALID KEYのブロックに移行する場合の制御フロー(1.)と,NOT ON INVALID KEYのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
SEARCH文 |
<ブロックA> SEARCH … AT END <AT ENDブロック> WHEN <WHENブロック> END-SEARCH <ブロックB> |
SEARCH文の処理からAT ENDのブロックに移行する場合の制御フロー(1.)と,SEARCH文の処理からWHENのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
START文 |
<ブロックA> START … INVALID KEY <ON INVALID KEYブロック> NOT INVALID KEY <NOT INVALID KEYブロック> END-START <ブロックB> |
ON INVALID KEYのブロックに移行する場合の制御フロー(1.)と,NOT ON INVALID KEYのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
STRING文 |
<ブロックA> STRING … ON OVERFLOW <ON OVERFLOWブロック> NOT ON OVERFLOW <NOT ON OVERFLOWブロック> END-STRING <ブロックB> |
ON OVERFLOWのブロックに移行する場合の制御フロー(1.)と,STRING文の処理からNOT ON OVERFLOWのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
SUBTRACT文 |
<ブロックA> SUBTRACT … FROM … ON SIZE ERROR <ON SIZE ERRORブロック> NOT ON SIZE ERROR <NOT ON SIZE ERRORブロック> END-SUBTRACT <ブロックB> |
ON SIZE ERRORのブロックに移行する場合の制御フロー(1.)と,SUBTRACT文の処理からNOT ON SIZE ERRORのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
UNSTRING文 |
<ブロックA> UNSTRING … ON OVERFLOW <ON OVERFLOWブロック> NOT ON OVERFLOW <NOT ON OVERFLOWブロック> END-UNSTRING <ブロックB> |
ON OVERFLOWのブロックに移行する場合の制御フロー(1.)と,UNSTRING文の処理からNOT ON OVERFLOWのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
WRITE文 |
<ブロックA> WRITE … AT END-OF-PAGE <AT END-OF-PAGEブロック> NOT AT END-OF-PAGE <NOT AT END-OF-PAGEブロック> END-WRITE <ブロックB> |
WRITE文の処理からAT END-OF-PAGEのブロックに移行する場合の制御フロー(1.)と,WRITE文の処理からNOT AT END-OF-PAGEのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|
<ブロックA> WRITE … INVALID KEY <ON INVALID KEYブロック> NOT INVALID KEY <NOT INVALID KEYブロック> END-WRITE <ブロックB> |
ON INVALID KEYのブロックに移行する場合の制御フロー(1.)と,NOT ON INVALID KEYのブロックに移行する場合の制御フロー(2.)の両方を想定して解析します。 |
|