1. 導入:なぜパラグラフ内の文構成が重要なのか?
COBOLプログラムにおいて、パラグラフ(段落)は処理のまとまりを表現する重要な要素です。そして、そのパラグラフは複数の「文(Sentence)」で構成されています。一見単純な構造に見えますが、この文の構成、特にIF文などの条件分岐におけるピリオド(.)の使い方が、プログラムの論理を意図せず破壊してしまうことがあります。本記事では、この「文」の構成における注意点と、それを回避するための具体的な実装方法について、ベテランCOBOL技術者の視点から解説します。
2. 基礎知識:パラグラフ、文、そしてピリオドの役割
COBOLにおける「パラグラフ」は、プログラムの可読性を高め、処理の流れを分かりやすくするための構造です。通常、大文字で書かれた名前(ラベル)の後に続きます。
一方、「文(Sentence)」は、COBOLの実行可能な命令のまとまりです。各文は、通常、ピリオド(.)で区切られます。このピリオドは、文の終端を示す記号として機能します。
しかし、注意が必要なのは、1つの文の中に複数の命令を記述できる場合でも、途中にピリオドを置いてしまうと、COBOLコンパイラはそのピリオドを文の終端と解釈してしまう点です。これにより、本来IF文の真偽判定ブロック内に含めるべき命令が、IF文の外部に切り離されてしまうという現象が発生します。
3. 実装/解決策:IF文とピリオドの正しい関係
IF文の構文を思い出してみましょう。
IF 条件式
PERFORM 処理A
MOVE A TO B
ADD 1 TO C
DISPLAY “完了”
END-IF.
上記のように、IF文に続く複数の命令は、通常、IF文のブロック(`IF 条件式` から `END-IF` まで)の中に記述されます。
ここで問題となるのは、以下のような記述です。
IF A = B
MOVE C TO D. <-- ここにピリオドがあると問題!
DISPLAY E. <-- このDISPLAYもIFの外になる可能性
END-IF.
この例では、`MOVE C TO D.` のピリオドが、`MOVE` 命令を1つの文として完結させてしまいます。その結果、`DISPLAY E.` も、コンパイラによっては `MOVE` 文の後に続く独立した文と解釈され、IF文の条件判定とは無関係に実行されてしまう可能性があります。
IF文の論理を正しく保つためには、IF文のブロック内では、原則としてピリオドを使用しないことが重要です。`END-IF` が、IF文ブロック全体の終端を示します。
もし、IF文のブロック内で複数の独立した文を実行したい場合は、各文の終わりにピリオドを置くのではなく、PERFORM文を使って別のパラグラフやセクションを呼び出すなどの工夫が必要です。
4. サンプルプログラム:正しい文構成の実践
以下のサンプルプログラムは、IF文内の文構成における正しいアプローチを示しています。
IDENTIFICATION DIVISION.
PROGRAM-ID. SENTENCE-EXAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATA-A PIC X(10) VALUE “HELLO”.
01 WS-DATA-B PIC X(10) VALUE “WORLD”.
01 WS-NUM-1 PIC 9(3) VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
DISPLAY “— プログラム開始 —“.
- IF文の例1:正しいピリオドの使い方
IF WS-DATA-A = “HELLO”
DISPLAY “WS-DATA-AはHELLOです。”
MOVE “GOODBYE” TO WS-DATA-A
ADD 1 TO WS-NUM-1
- IF文のブロック内では、原則ピリオドは使わない
END-IF.
- IF文の例2:ピリオドを誤って使用した場合の例(コメントアウト)
- IF WS-DATA-B = “WORLD”
- DISPLAY “WS-DATA-BはWORLDです。” <--- このDISPLAYはIF文の外になる可能性
- MOVE “EARTH” TO WS-DATA-B. <--- このMOVE文でIF文が終了してしまう
- END-IF.
DISPLAY “WS-DATA-Aの値: ” WS-DATA-A
DISPLAY “WS-NUM-1の値: ” WS-NUM-1
- PERFOMを使った処理の分離例
IF WS-DATA-A NOT = “HELLO”
PERFORM PROCESS-AFTER-IF
END-IF.
DISPLAY “— プログラム終了 —“.
STOP RUN.
PROCESS-AFTER-IF.
DISPLAY “PERFORMされた処理です。”.
- ここではピリオドを使っても問題ありません。
MOVE “TEST” TO WS-DATA-A.
DISPLAY “PERFORM処理内のWS-DATA-Aの値: ” WS-DATA-A.
EXIT.
コードの解説:
- `IF WS-DATA-A = “HELLO”` のブロック内では、`DISPLAY`、`MOVE`、`ADD` 命令の後にピリオドを置いていません。これは、これらの命令がIF文の条件が真であった場合に実行されるべき一連の処理であることを明確に示しています。`END-IF.` がIF文ブロックの終端を正しく示します。
- コメントアウトされている例2は、ピリオドを誤って使用した場合にどのような問題が発生しうるかを示唆しています。
- `PERFORM PROCESS-AFTER-IF` を使用することで、IF文のブロック外の処理を呼び出し、コードの構造をより明確に保つことができます。`PROCESS-AFTER-IF` パラグラフ内では、通常の文の区切りとしてピリオドを使用しています。
5. 応用・注意点:現場で役立つヒント
- 可読性の重要性: 複雑なIF文では、ネストが深くなったり、多くの命令が含まれたりすることがあります。このような場合、ピリオドの誤用はコードの理解を著しく困難にします。常に、コードを読む人が処理の流れを容易に追えるように、シンプルで明確な文構成を心がけましょう。
- コンパイラの挙動: COBOLコンパイラによっては、ピリオドの解釈に若干の違いが出ることがあります。しかし、標準的なCOBOLの仕様に沿って、IF文ブロック内ではピリオドを避けるのが最も安全で移植性の高いコーディングスタイルです。
- PERFORMの活用: IF文のブロック内に多くの処理を記述したい場合は、それを独立したパラグラフやセクションに切り出し、PERFORM文で呼び出すことを強く推奨します。これにより、IF文自体の可読性が向上し、保守性も高まります。
- `END-IF` の必要性: `END-IF` は、IF文のブロックを明示的に終了させるために非常に有効です。特に、ネストしたIF文や、複数の文を含むIF文では、`END-IF` を適切に使用することで、文の範囲を明確にすることができます。
これらの点を意識することで、COBOLプログラムにおけるIF文の論理破壊を防ぎ、より堅牢で保守しやすいコードを作成することができます。

コメント