COBOL とその言語処理系の今昔比較

# 自己紹介

* Haskell プログラマーだけど Haskell あまりわかっていない
* 翻訳好きで、Python とか RWBY とか。でも最近できてないです、ごめんなさい。
* 最近はスタリラというソシャゲにハマり中
* COBOL の言語の特徴と、GnuCOBOL と TypeCobol という処理系について、軽くですが調べましたので発表します
* COBOL を解析するときにありがちな悩みの相談もあります

---

# Java vs COBOL

## Java での開発

* 大量の OSS ライブラリ、大量の技術標準
* Web では避けて通れないがバグを生みやすい並行処理
* 手続き的記述、オブジェクト指向、関数型、dependency injection、なんでもござれ

---

# Java vs COBOL

## COBOL での開発

* 垂直統合による限られた連携製品、少ない文書
* 同一筐体内の DB を使い、バッチはオフラインに限って、並行性バグを顕在化させない
* 徹頭徹尾、命令型 (imperative) の記述
* COBOL 自体は簡単
    * ただし、IMS (IBM のトランザクション処理機能 (DB や MQ)) なども含めたシステム全体を無償で動かすことはできないため学習困難

---

# COBOL は日々進化中！

お客様の中に最新の COBOL 標準をご存知の方はいらっしゃいますか？

* 国際的には COBOL 2014 (ISO/IEC 1989:2014)
* JIS 標準なら COBOL 2002 (JIS X3002:2011)

国際標準は Haskell 2010 より新しいではないですか！

---

# 昔風の COBOL プログラム

サクラエディタが対応している、安心の固定形式正書法 (fixed-form reference format)。COBOL では桁数が超重要なのに、Vim とか Emacs のメジャーな拡張は全角の概念がなさそう。サクラエディタは神。Qiita の CSS は 全角文字のない consolas 優先で指定されているので、コメント右端の * がずれます (単に monospace と指定してほしかった)。

```cobol
      ******************************************************************
      * プログラム名: ハローワールド                                   *
      * 作成者: hanotch                                                *
      * 会社名: ほげほげ株式会社                                       *
      * 更新履歴:                                                      *
      * 19990123 2000年問題対応                                        *
      * 20030304 第二次オンライン化対応改修 OLR-032                    *
      ******************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. HELLOWLD.
       AUTHOR. HANOTCH.
       DATA DIVISION. 
       WORKING-STORAGE SECTION.
       01 HELLO-MSG.
         03 HELLO PIC X(10).
         03 WORLD PIC X(10).
      * 19990123 2000年問題対応 開始。対応者: 佐藤
      *01 YEAR PIC 9(2).
      * 19990123 2000年問題対応 終了。対応者: 佐藤
       01 YEAR PIC 9(4).
       01 THE-ANSWER PIC 9(2).
       01 ANSWER-TO-THE-ULTIMATE-QUESTION-OF-LIFE-AND-THE-UNIVERSE-AND-Ecorrect?
      -   VERYTHING REDEFINES THE-ANSWER PIC 9(2).                      correct?
      LINKAGE SECTION.
      * リンケージなし
      /
       PROCEDURE DIVISION.
      * メインセクション
       MAIN SECTION.
      * ハローワールド表示
ALEXA,     PERFORM S100.
      * 未初期化の変数を読み、運を天に任せる
ALEXA,     IF THE-ANSWER = 42 THEN
             DISPLAY 'I''ve found the answer!'
           ELSE
             NEXT SENTENCE.
ALEXA,     STOP RUN.
      * ハローワールド出力
       S100 SECTION.
ALEXA,     MOVE 'hello' TO HELLO.
ALEXA,     MOVE 'world' TO WORLD.
ALEXA,     DISPLAY HELLO ', ' WORLD '!'.
ALEXA,     EXIT.

SEQNUM*AAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB12345678
```

1959 年に write once, run anywhere の業務用言語なんて、すごくないですか⁉

節や段落の名前に日本語が使えなかったのか、コメントまで見ないとわからないことが多い。しかしコメントはコンパイラーは見ないため、調査しづらい。

上記の例だと

* S100 SECTION の正式な日本語名は、ハローワールド「表示」なのか「出力」なのか？
* OLR-032 という謎の管理番号は何なのか？
* 冒頭には作成者 HANOTCH、ほげほげ株式会社と書かれているが、佐藤さんは何者なのか？
* 全ての変更履歴は2000年問題対応のコメントと同じ開始/終了タグ (?) が使われるのか？

標準では文字列リテラルは二重引用符だけど、実際の処理系はむしろ単一引用符のほうが互換性が高い様子。

EXIT 文に意味はないのだが、よく return みたいなものだと誤解されている。段落中で唯一の完結文 (sentence) でなければならないとされているが、よく上記みたいに最後の完結文として書かれる。

コンパイラーが警告しそうな書き方をしているのに、なぜかそのまま使われていることが多い。


---

# 歴史

| 年         | できごと |
|-----------|-------------|
| COBOL 60   | 最初の版。ALGOL の1年後くらい？ |
| COBOL-68 | ISO と ANSI による最初の標準化。 |
| COBOL-74 | 第二次規格。ファイル編成 (順編成、索引編成など) が追加。 |
| COBOL-85 | END-IF などが追加され、ブロックを使った "構造化" が可能に。 |
| COBOL 2002 | 自由形式 (free form)。A/B 領域撤廃。再帰。オブジェクト指向。 |

強い型付けが導入されたのも COBOL 2002？

[Wikipedia 英語版](https://en.wikipedia.org/wiki/COBOL#History_and_specification)を参考にしました。[日本語版](https://ja.wikipedia.org/wiki/COBOL#CODASYL_COBOL%E3%81%AE%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%AE%E5%A4%89%E9%81%B7)と異なる部分について事実関係の確認はできませんでした。

---

# 最近の COBOL プログラム

自由形式正書法 (free-form reference format) で書いてみたけど、この形式に対応しているエディター拡張あるのだろうか。

```cobol
program-id. hello.
data division.
working-storage section.
01 hello-msg.
  03 hello pic x(10).
  03 world pic x(10).
01 filler.
  03 the-answer pic 9(2).
  *> free-form なら行の継続方法で悩まない
  03 answer-to-the-ultimate-question-of-life-and-the-universe-and-everything redefines the-answer pic 9(2).
procedure division.
main section.
perform message-output.
if the-answer = 42 then *> 未初期化の変数を読み、運を天に任せる
  display "I've found the answer!"
else
  continue *> 何もしない文。C 言語で文がないことを明記するときの ";" みたいな存在。
end-if.
message-output section.
move 'hello' to hello.
move 'world' to world of hello-msg. *> of で修飾する例。Java なら hello-msg.world 的な。
display hello ', ' world '!'.
```

最近は FUNCTION も使いやすく、[Wikipedia 日本語版の Fizz Buzz](https://ja.wikipedia.org/w/index.php?title=COBOL&oldid=69566743#%E5%AE%9F%E4%BE%8B4_(Fizz_Buzz)) は積極的に使った例。

豆知識: [paiza](https://paiza.io) はこの形式が設定されているので、fixed-form を使いたいなら冒頭に以下のように書く。この翻訳指示語 (compiler directive) は標準準拠で、両形式を切り替えつつ記述できる。

```cobol
>> SYNTAX FIXED
```

---

# COBOL の言語処理系の紹介 (2つだけ)

---

# GnuCOBOL (以前の OpenCOBOL)

* COBOL コンパイラーで、もとは西田圭介さんの作。
* C への変換といわれることもあるが、詳しい方から LLVM 出力もできるみたいに聞いたことがある。
* opensouce COBOL という、日本の OpenCOBOL 派生ソフトもある
    * GnuCOBOL 3.0 ではどうか知らないけど、全角文字が半角2文字分だとわかってくれる、ありがたい実装。

---

# TypeCobol

* COBOL-85 の incremental parser (+ COBOL 2002 の TYPEDEF)。
    * LSP などでコードの一部だけ更新された場合、素早く解析できる
    * ユーザーが拡張して、案件のコーディング規則に合致しているかチェックできる
* または、COBOL-85 拡張言語の名前。TypeScript と JavaScript の関係と同じで、COBOL-85 に変換可能
    * COBOL 2002 に似た型システム (Boolean, Date など)
    * 手続き (procedure) を普通の言語の関数っぽくした。手続きはオーバーロードでき、引数の型が一致しているものが呼ばれる。
    * OF とか IN とかは外国人でも使いにくかったらしく、:: という演算子が追加
* [ライセンス](https://github.com/TypeCobolTeam/TypeCobol/wiki/License)を見ると、主要開発者はフランス人っぽい。

---

# GnuCOBOL と TypeCobol の言語処理機能周りの比較

| 機能 | GnuCOBOL | TypeCobol |
|---|---|---|
| リリース | [2002 年度](https://www.ipa.go.jp/jinzai/esp/mitoipedia/spc/year/2002ysc.html)[^1] | 2017年 |
| 連携 | GCC フロントエンド | RDz (Eclipse) プリプロセッサ |
| build tool | Automake | Visual Studio |
| 言語 | C | C# |
| parser generator | bison & flex | ANTLR & C# CUP  |
| パース単位 | 一括 | incremental |

[^1]: OpenCOBOL のリリース年度

---

# 悩み

* 標準準拠のコードばかりではなく、方言が多い。ベンダーのマニュアルで禁止された構文が使われることさえある。なぜパースできてしまったのか。
* Automake や C# など、既存実装の開発で使われた技術に関する知識がないと、言語解析基盤がどう使われているかイメージしづらい。技術選定や実用には、幅広い知識が必要そう。
* 言語処理系を学ぶ場合、どこから手を付ければ挫折しないのか。Visual Studio Code の拡張あたりが良い？
* COBOL は案件ごとに決まった形式のコメントでバージョン管理され (?)、JCL (Job Control Language というシェル スクリプトみたいなやつ) から呼ばれ、埋め込み SQL を発行するプログラムもある[^2]。最近 Spring にも関心があるのだけど、もしかして一般的に言語またぎの解析が必要とされることは多い？

[^2]: 埋め込みについては [TypeCobol の FAQ でも言及がある](https://github.com/TypeCobolTeam/TypeCobol/wiki/FAQ#are-you-planning-to-include-embedded-sql--cics-into-your-compiler)