Head First COBOL

本稿は、SFC-RG Advent Calendar 2018の25日目の記事である。

about

AWS LamdaでCOBOL使える??」みたいな話で、COBOLが微妙に盛り上がっている。 せっかく会社の研修でCOBOLを覚えたので、COBOLの書き方*1を忘れなうちに残す。

環境

環境構築

Windowsでは環境構築が面倒くさいので、Ubuntu上(WSL)に環境構築を行う。

sudo apt install open-cobol
$ cobc --version
cobc (OpenCOBOL) 1.1.0
Copyright (C) 2001-2009 Keisuke Nishida / Roger While
Built    Feb 07 2016 10:28:13
Packaged Feb 06 2009 10:30:55 CET

バージョンがだいぶ古いが気にしない。。。 Macでの環境構築は下記参照。
mac OS HighSierraでのCOBOL環境構築

COBOLのシキタリ

COBOLと私たちが普段使っているC, Java, JavaScriptとではお作法がかなり違う。 COBOLでの代表的なお作法を示す。

プログラムが4つのDIVISIONによって構成される

COBOLはプログラムが4つのDIVISIONと呼ばれる単位で構成される。以下のサンプルプログラムを見てほしい。このサンプルプログラムにも色々文法の解説をしているが、ここで述べたことは基本的には既知のものと扱う。

解説の前にコンパイル方法だけ、記しておく。

$ cobc -x  subtraction.cob
$ ./subtraction
数値を入力してください
100
Input Number is :00100. Output Number is :00050.

まず気になるのは左カラム7列の数字であろう。この数字は、一連番号領域と呼ばれ、ただの行番号である。上で、固定形式/自由形式と行ったが、この行番号を表記するスタイルを固定形式と呼ぶ。

次項から、各セクションについて述べる。

INDENTIFICATION DIVISON

ここではプログラムがどんなプログラムなのか記述する。上のサンプルグラムでは、PROGRAM-ID. PROGRAM-1.としているが、PROGRAM-IDはなんでもいい。
サンプルプログラムは見ればわかるように、COBOLではDIVISIONごとに.で区切りを入れるので注意をして欲しい。

ENVIRONMENT DIVISION

ここではファイルの入出力の設定を行う。COBOLの真髄は、帳票の出力や計算にある。なのでここは超重要であるが、別章にて仔細を述べる。力尽きたので、機会があれば説明する。

DATA DIVISION

ここでは変数は配列の宣言を行う。COBOLではプログラム途中、具体的にはDATA DIVISION以外での変数宣言はできない。ちゃんとウォーターフォールでプログラム設計してから書けよってことである。

PROCEDURE DIVISON

ここで実際のプログラムの処理を書いていく。他言語的に言うと、importやらreqireやらを済ませたあとである。
サンプルプログラムに書いたように、プログラムは段落構造で記述する。

  • DIVISION 部
    • SECTION 章
      • 変数名だけ 段落

といった形で記述する。

変数と配列

型 PICTURE句

PICPICTURE句のことで、型を定義する。以下に代表的なPICTURE句を紹介する。

  • PIC 9(5)
    • 数字5桁の領域を確保
  • PIC X(5)
    • 英数字5桁で領域を確保
  • PIC ZZZ9.9
    • 整数部4桁、小数部1桁で領域を確保、桁が定義文行かなかったら非表示

変数

COBOLでは変数を宣言することは、その領域を確保することになる。下に変数を定義してみる。

WORKING-STORAGE          SECTION.
01  COMPANY.
  10  COMAPNY-NO         PIC X(30).
  10  SEC-CODE.           
    50  INDUSTRY-NO      PIC 9(2).
    50  BRANCH-NO        PIC 9(2).
  10  HQ-LOCATE          PIC x(10)

ここでの01 COMPANYという宣言は、集団項目と呼ばれ、この変数全体を指す。また、30+2+2+10桁の領域を確保したことになる。
0110はレベル番号と呼ばれ、項目の階層構造を示す。集団項目下の項目は普通項目と呼ばれる。

配列

配列も集団項目を利用して宣言される。以下に一次元配列を定義する。

01 ARRAY-NAME.
  10 ARRAY-ONE  PIC 9(4) OCCURS 5.

上の例では、5つの要素をもち、1つあたりの領域は数字4桁分の配列を宣言している。次のような配列だ。
■ ■ ■ ■ ■
二次元配列も同様に宣言すれば良い。

01 ARRAY-NAME.
  10              OCCURS 2. >*ここで2次元である事を定義  
    20 ARRAY-TWO  PIC 9(4) OCCURS 5.

そうすると次のような配列が宣言されたことになる。

■ ■ ■ ■ ■
■ ■ ■ ■ ■

条件分岐と繰り返し

条件分岐

COBOLの条件分岐は面白い。上のサンプルコードでは、一重の条件分岐を書いた。何が面白いかというとelse ifが取れないのでswitch文(COBOLではEVALUATE文)を書くか、ネストさせまくるしかない。
私は多重ネストは視認性が悪くて嫌いなので、ネストさせながらもelse-ifっぽく書く書き方をよくする。以下、サンプル。

IF SEC-CODE = 9434 THEN     *>イコールが1つでも比較であり代入ではない
   DISPLAY "ソフトバンク"
   
ELSE IF SEC-CODE = 9984 THEN
   DISPLAY "ソフトバンクグループ"
   
ELSE IF SEC-CODE = 4689 THEN
   DISPLAY "ヤフー"
   
ELSE
   DISPLAY "ソフトバンクグループではありません"
   
END-IF
END-IF
END-IF.

といった感じだ。最後のEND-IF.を忘れないように注意。 これをCOBOLのswitch文であるEVALUATE文で書くと以下のようになる。

EVALUATE SEC-CODE
  WHEN 9434
    DISPLAY "ソフトバンク"
  WHEN 9984
    DISPLAY "ソフトバンクグループ"
  WHEN 4689
    DISPLAY "ヤフー"
  WHEN OTHER
    DISPLAY "ソフトバンクグループではありません"

まとめ

本当は、ファイルの入出力をやって帳票出力するところまで書きたかったのでが、明石家サンタが見れなくなるので、ここで筆を置く。
今日もこの裏で全国津々浦々走っている夜間バッチたちとその製作者に本稿を捧げる。
メリークリスマス。

*1:簡易的な文法

*2:固定形式というものがある