なぜ正規化が必要か
COBOLソースコードはメインフレーム全盛期の慣習を色濃く残しており、現代のツールでそのまま扱おうとすると様々な困難が生じる。
代表的な問題を挙げると、差分比較ツールが行ラベルの変化に反応してノイズを大量に出力したり、
簡易的な静的解析スクリプトがコメント行を命令と誤認識したりする。
継続行が別行に分断されているためコマンドラインの grep では完全な文字列がヒットしないケースも多い。
こうした問題に対して 正規化(Normalization) を一段挟むことで、後続の解析・移行・差分比較の品質が大幅に向上する。 正規化は「完全なCOBOLパーサーを書く」という重い作業ではなく、 文字列操作と状態機械(ステートマシン)を組み合わせた実用的なアプローチで実現できる。
before / after — 何が変わるか
以下に典型的な変換例を示す。
000100 IDENTIFICATION DIVISION. 000200* このプログラムはサンプルです 000300 PROGRAM-ID. SAMPLE. 000400 PROCEDURE DIVISION. 000500 MOVE 'HELLO WOR- 000600- LD' TO WS-MSG. 000700 DISPLAY WS-MSG. STOP RUN.
IDENTIFICATION DIVISION. PROGRAM-ID. SAMPLE. PROCEDURE DIVISION. MOVE 'HELLO WORLD' TO WS-MSG. DISPLAY WS-MSG. STOP RUN.
変換の内訳は次のとおり。
- 列1〜6の 行ラベル(シーケンス番号) を除去
- 列7が
*の コメント行 を削除 - 列7が
-の 継続行 を前行に結合(文字列リテラルも正しく連結) - 連続スペース を間詰め
- ピリオドを区切りとして 1行1命令 に分割(
DISPLAY WS-MSG. STOP RUN.→ 2行に分解)
正規化の対象を整理する
* または / の行。静的解析・差分比較では不要なため削除する。- の行は前行の続き。文字列リテラル継続の場合は引用符の扱いに注意が必要。END-xxx スコープ終端を区切りに分割。文字列中・PIC句・数値リテラルのピリオドを誤検出しないようステートマシンで処理する。⚠️ 完全なCOBOLパーサーではない
本シリーズの実装はすべての方言・拡張に対応する完全パーサーを目指すものではない。 主要な固定形式COBOLを対象とした実用的な正規化ツールとして設計する。 本番適用前には対象プロジェクト固有の特殊記法を必ず確認すること。
シリーズ構成
全8回で段階的に実装を積み上げる。
✅ 次の章では…
PART 02 では正規化の前提知識として COBOL 固定形式フォーマットの列定義を詳解する。 列番号を知らずに文字列操作を行うと行ラベルを命令と誤認するなど深刻なバグにつながるため、必ず読んでほしい。