COBOL85入門
目次
- はじめに
- 動作環境
- 対象者
- COBOLとは?
- 環境構築
- COBOLの仕様
- 最終目的
- ルール
- コメント
- コーディング規約
- 基本構造
- ハローワールド
- データ形式
- 演算子
- 配列
- I/O
- 制御構造
- API
- その他
- デバック
- 最後に
- 参考資料
はじめに
オープンソースでCOBOL開発が出来るOpenCOBOLを使った入門です。実際にCOBOLプログラミングをしていない開発者が数時間でCOBOLの概要をつかめるようにまとめました。また実際に触れたり、リファレンスとして使えるようにサンプルコードをたくさん用意しました。
最近プログラミングをはじめた開発者は、メインフレームを使った新規の開発に参加することは少ないと思います。またメインフレームやオフコンが使われ始めた1980年代などは、今のようにインターネットも普及していませんし、オープンソースからソースコードを入手することも今のようにはいきませんでした。そのためJavaなどにくらべインターネットのソースコードも極端に少ないものです。
ですが、いまでも使われるCOBOLの文法や言語構造と最近の言語を比較することでいろいろなことが学べます。今の言語では当たり前のことが出来なかったりして調べていくと結構面白いものなので是非サンプルを実行しながら学んでみてください。
動作環境
テストにはLinuxでOpenCOBOLの開発環境を用意しましたが、WindowsやUnix系OSでも実行できるようです。
対象者
COBOLの概要を数時間で理解したい方や、COBOLの開発をしたことがない方
COBOLとは?
COBOL(コボル)とは、COmmon Business Oriented Languageの略で、事務処理計算に強いプログラミング言語です。1950年代から使われていて、英語の文章のように記述できるのが特徴です。CODASYL(コダシル)という標準化団体が言語仕様などを管理しています。またメインフレームなどで利用され、最近ではUnixやWindows環境でも開発はされているようです。COBOLは主に、企業の業務計算などに使われるため、他の言語に比べて、インターネット上でのソースコードの普及などは少ないのが現状です。
環境構築
OpenCOBOLからopen-colob-0.23.tar.gzをダウンロードします。その後は以下のコマンドを実行します。
# tar -zvf open-cobol-0.23.tar.gz
# cd open-cobol-0.23
# ./configure
# make
# make install
パッケージのディレクトリ構造
| package | comments |
| cobc | cobol compiler |
| libcob | cobol runtime library |
| lib | static library and common header |
| po | international messages |
| texi | textinfo ifles |
| tests | test suite |
COBOLの仕様
COBOLは40年前から使われている言語であるため、FORTRANと同じく仕様が拡張され続けています。 今回少し仕様を調べて見ましたのでここに記述します。COBOL85からCOBOL2002までの約17年間にいくつ かの仕様改訂があったようですがここでは省略します。
- 1960.04 CODASYL-60
- 1968. ANSI COBOL(COBOL68)第1次規格
- COBOL74 第2次規格
- COBOL85 第3次規格
- COBOL2002 第4次規格
現在、実稼動しているアプリケーションは、少なくともCOBOL85に準拠していると思われるのでこの生地ではこの仕様を基礎に記述したいと思います。
最終目的
COBOL版バイナリクロックを作成します。COBOL言語の文法を理解し、何故40年間も使われてきた言語であるかを学習します。また一般にCOBOLは膨大な行数(ステップ)になると言われていますが何故そのようになるかも調査します。
ルール
FORTRANと同様、固定形式(a rigid format)でソースコードを書かなければいけません。これはパンチカードなのでコーディングされていた名残です。現在のコンパイラやランタイムは固定形式でコーディングする問題はありませんが、あくまで歴史を知る上で、これに準拠しながらこのCOBOL入門を進めます。またCOBOLのコード量が多くなる原因の1つであることが理解できます。固定形式での書き方は以下のようになります。基本的に12-72カラムにソースコードを記述します。
| 行数 | 1-6 | 7 | 8-11 | 12-72 | 73-80 |
| 意味 | ライン番号 | マーキングライン | section,paragraph名定義領域 | コード記述 | パンチカード用予約領域 |
マークキングの種類
- *はコメントです。
- -は1行を続ける時に使用します。
- /は強制ページブランクで、複数行のソースコードを書きたい時に使用します。
- Dはデバック
- $はディレクティブ
コメント
* アスタリスクがコメントです。
コーディング規約
存在しないようです。
基本構造
identification division.
program-id. hello.
author. satoshi okita.
environment division.
data division.
procedure division.
main section.
処理
stop run.
データセグメントとコードセグメントが分離しているためDATA DIVISIONでデータ用メモリ領域を確保します。プログラムはPROCEDURE DIVISIONに記述します。1行をピリオドで終了させる必要があります。
ハローワールド
identification division.
program-id. hello.
author. satoshi okita.
environment division.
procedure division.
main section.
display "Hello World" line 5 column 30.
stop run.
$ cobc hello.cob $ ./hello
データ形式
変数はDATA DIVISIONのWORKING-STORAGE SECTIONに宣言しなければなりません。
77 TEST-VAL PIC X(30)
上記は、30文字をTEST-VALという名前で宣言しています。COBOLにTEST_VALなどのunderlineはつかえません。77はレベルナンバといい、他の変数と結びつかないことを意味します。(推測ですが、一意なポインタにするのではないかと思います。)
1-49はレコードの定義に使われます。 66はprior variable。77は普通の変数に使います。88はsymbolic conditions用です。
簡単に言うと、分からなければ77を使います。COBOLがある程度記述できるようになってから詳細を調べる方が良いと思いますのでここでは詳細を記述しません。
文字の定義は X(n) を記述します。以下がサンプルになります。
77 TESTVAL PIC X(5)
浮動小数点の定義は、S9(arg1)V9(arg2) のような書き方にします。
77 TEST-FLOAT PIC S9(1)V9(1)
整数の定義は S999のような書き方をします。Sはsignの意味で+/-を表すかどうかを指定できます。
77 HOGE-VAL PIC 999. 77 FUGA-BIN PIC S999 COMP. 77 FUGA-BIN PIC S999 DISPLAY.
上記のCOMP,DISPLAYを記述することでDISPLAY命令のフォーマットでもこの形式を利用するように定義しています。
データ形式についてのサンプルを書きましたので各自コンパイルして動作確認してください。
HOGE-VAL3桁の数値。FUGA-INバイナリの3桁Sは符号付(sign)を意味するので(-999 to 999)
$ cat variable.cob
identification division.
*
program-id. vals.
author. satoshi okita
*
environment division.
*
data division.
working-storage section.
*
* pic - PICture mask
* unsigned 1.1
77 price pic 9(1)V9(1) comp value zero.
* signed +1.1
77 price2 pic S9(1)V9(1) comp value zero.
77 price3 pic S9(2)V9(2) comp value zero.
77 price4 pic --9Vb99 value 1.1.
77 price6 pic ---,---9Vb99 display value 1234567890.12345.
77 bar pic x(80) value all "--*".
*
procedure division.
main section.
display space.
display bar line 3 column 1.
display price line 7 column 10.
display price2 line 8 column 10.
display price3 line 9 column 10.
display price4 line 9 column 10.
display price6 line 9 column 10.
exit program.
$ cobc variable.cob
cc1: warning: changing search order for system directory "/usr/local/include"
cc1: warning: as it has already been specified as a non-system directory
$ ./variable
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
0.0
+0.0
+00.00
1. 1
56,7890. 1
演算子
cobolは英語の表記で演算が出来るのためby 1 giving などのように記述します。これもソースコードが多くなる原因の一つです。また通常の+-*/などを使った演算もCOMPUTE文で記述できます。以下のサンプルでは様々な形で演算を記述しましたので確かめてください。
ADD
IDENTIFICATION DIVISION.
PROGRAM-ID. CALCULATION.
AUTHOR SATOSHI OKITA.
ENVIRONMENT DIVISION.
DATA DIVISION.
working-storage section.
77 addval PIC 999 value 100.
77 result PIC 999 value 100.
PROCEDURE DIVISION.
MAIN SECTION.
add addval, 23 to result.
display result line 1 column 5.
STOP RUN.
SUBTRACT
identification division.
program-id. substract.
author satoshi okita.
environment division.
data division.
working-storage section.
77 subval pic S999 value 100.
77 result pic S999 value 10.
procedure division.
main section.
* result = result - subval
subtract subval from result.
display result line 1 column 1.
stop run.
MULTIPLY
identification division.
program-id. multiplya.
author satohsi okita
environment division.
data division.
working-storage section.
77 multival pic S999 value 2.
77 result pic S999 value zero.
procedure division.
multiply multival by 5 giving result.
display result line 1 column 1.
stop run.
DIVIDE
identification division.
program-id. divide-cob.
author satoshi okita.
environment division.
data division.
working-storage section.
77 result pic S999 value 2.
procedure division.
divide 2 into result.
display result line 1 column 5.
stop run.
剰余を求めるにはDIVIDE文を使用します。COMPULTE文では剰余を求めることが出来ません。
identification division.
program-id. divide-cob.
author satoshi okita.
environment division.
data division.
working-storage section.
01 data-a pic 9 value 9.
01 data-b pic 9 value 2.
01 data-c pic 9 value 0.
01 data-d pic 9 value 0.
procedure division.
divide data-a by data-b giving data-c remainder data-d.
display 'data-a:' data-a.
display 'data-b:' data-b.
display 'data-c:' data-c.
display 'data-d:' data-d.
stop run.
COMPUTE
C言語やJava言語のように記号でも演算できます。 identification division.
program-id. compute-cob.
author. saothsi okita.
environment division.
data division.
working-storage section.
77 result pic 999 value 1.
77 testval pic 999 value 50.
77 multival pic 999 value 2.
procedure division.
compute result rounded = result + ( testval * multival / 2).
display result line 1 column 30.
stop run.
配列
OpenCOBOLでは、OCCURS句を利用して配列を記述できます。
以下のサンプルは、一次元配列を定義しています。またCOBOLの場合、配列をindex操作する場合はindexed by インデックス名を記述する必要があります。
[s-okita@localhost cobol]$ cat array.cob
identification division.
program-id. array.
*
environment division.
data division.
working-storage section.
01 one-ary.
05 elements occurs 7 indexed by idx.
10 val pic 99.
*
procedure division.
perform varying idx from 1 by 1 until idx > 7
move idx to val(idx)
display val(idx)
end-perform
stop run.
I/O
制御構造
分岐
サンプル1 identification division.
program-id. ifcob.
author satoshi okita.
environment division.
data division.
working-storage section.
77 cnd-val pic x(5) value "hello".
procedure division.
if 1 = 1 then
display "1=1" line 1 column 50.
if 2 > 1 then
display "2>1" line 2 column 60.
if 'a' = 'a' then
display "a=a literal values" line 2 column 60.
if 'a' NOT= 'b' then
display "NOT=" line 2 column 60.
if ( 2 < 1 ) or ( 1 > 0 ) then
display "numenic" line 2 column 60.
if cnd-val = "hello" then
display cnd-val line 2 column 60.
stop run.
反復
反復処理はPERFORM文で書きます。
perform 関数 [ thru 関数 ] with test [ before | after ] until 条件
[s-okita@localhost cobol]$ cat repeat.cob
identification division.
program-id. repeat.
author. satoshi okita.
environment division.
data division.
working-storage section.
77 val pic 99 value 0.
procedure division.
main section.
perform repeat-func with test before until val = 5.
display 'result='val line 1 column 5.
perform repeat-func with test after until val = 8.
display 'result='val line 1 column 5.
stop run.
*
repeat-func.
add 1 to val.
display val line 1 column 5.
exit.
for loopはPERFORM文で書きます。
perform 関数 varying カウンタ変数 from 初期値 by カウント値 until 終了条件
[s-okita@localhost cobol]$ cat forloop.cob
identification division.
program-id. forloop.
author. satoshi okita.
environment division.
data division.
working-storage section.
77 i pic 99.
procedure division.
main section.
perform view-func varying i from 0 by 3 until i > 10.
stop run.
*
view-func.
display 'hello, i='i line 1 column 1.
exit.
[s-okita@localhost cobol]$ ./forloop
hello, i=00
hello, i=03
hello, i=06
hello, i=09
関数
現在調査中ですが、COBOLでは関数の引数をJava言語やC言語のように渡せないようです。BourneShellのような形のようです。[s-okita@localhost cobol]$ cat paragraphs.cob
000000* a
*
identification division.
program-id. paragraphs.
author. satoshi okita.
environment division.
data division.
working-storage section.
77 test-val pic 99 value 10.
*
procedure division.
main section.
move 34 to test-val.
perform increment-func.
subtract 1 from test-val.
display test-val line 1 column 5.
stop run.
*
increment-func.
add 1 to test-val.
display test-val line 2 column 5.
exit.
API
time関数
[s-okita@localhost cobol]$ cat sysdate.cob
identification division.
program-id. sysdate.
author. satoshi okita
environment division.
data division.
working-storage section.
01 c-time.
03 c-hour pic 99.
03 c-minites pic 99.
03 c-seconds pic 99.
procedure division.
accept c-time from time.
display c-time.
stop run.
その他
全角スペースの判断
identification division.
program-id. eucspace.
author satoshi okita.
environment division.
data division.
working-storage section.
01 wk-moji pic x(2) value ' '.
procedure division.
main section.
if wk-moji = space then
display '1byte space:' wk-moji '.'
else
display 'else:'
end-if.
* 2byte space chek
if wk-moji = ' ' then
display '2byte space:' wk-moji '.'
else
display '1byte space:'
end-if.
stop run.
デバック
OpenCOBOLは、C言語へのトランスレータのためgccと同等のデバックが可能だと思います。実際にコンパイラに触れてみてデバック方法を学習して見てください。
最後に
今回は、参考資料を基にCOBOL版2c(バイナリクロック)を作成するまでCOBOLに触れてみました。インターネット上の情報を調べて感じたことは、JavaやC言語に比べ、情報が非常にベンダ依存している傾向が感じ取れました。また入門サイトが相対的に少なく感じました。歴史的背景があるので当然ですが、COBOLを広めるためにも多くのCOBOL技術者が入門サイトを立ち上げてくれることを望む次第です。
参考資料
The COBOL-85 Turorial, Table of Content. (英語)
http://www.smga3000.com/cobol/COBOL47.HTM
