なぜCOBOLパーサーは生成AI前処理に向かないのか?実務視点で解説
はじめに
金融系の基幹システムでは、いまでもCOBOLが現役で動いています。何十年も安定稼働してきたCOBOLのシステムは、ビジネスの根幹を支える一方で、保守担当者の減少やブラックボックス化といった課題を抱えています。
ここ数年、そうした課題に対して生成AIを使ってCOBOLソースを解析する取り組みが少しずつ広がっています。生成AIにCOBOLのソースを読み込ませ、仕様書を自動生成し、Javaなどのモダン言語への変換を支援する、そのようなユースケースが現実的になってきました。
ただし、実際にやってみるとすぐに壁にぶつかります。COBOLのソースはとにかく巨大で、生成AIが一度に扱えるトークン数を簡単に超えてしまうのです。そのため、生成AIに入力する前にCOBOLソースを分割・整形するといった“前処理”が必要になります。
このとき、よく検討対象に挙がるのが「COBOLパーサー」です。構文を解析して構造化できるため、文法に沿って入力加工ができる点が便利ですが、生成AIの入力加工という目的に限って言えば、実はあまりおすすめできません。
本記事では、なぜCOBOLパーサーを使って生成AIの入力を加工するのが得策ではないのか、その理由を具体的に解説します。
プログラムの静的解析手法の比較
プログラムの静的解析で使える技術は大きく、構文解析(パース)、正規表現、生成AIの3つがあります。それぞれ以下のような特徴があります。
| 解析手法 | メリット | デメリット |
|---|---|---|
| 構文解析(パース) | 誤った記述や曖昧な記述があった場合に、文法エラーとして検知が可能 | 文法に沿った記述(コンパイルが通るソース)になってないとエラーが発生し、解析が中断する |
| 正規表現 | 検出したい文字列の条件を効率的に記述でき、実装が容易 | 命令が複数行にわたるケースの解析や、文字列・コメントとの区別を正しく判定するのが難しい |
| 生成AI | プログラミング言語等の複雑なルールに基づく入力データも容易に扱うことが可能 | ハルシネーションが発生し、欠けた出力結果や誤った出力結果が生成されることがある |
構文解析(パース)のデメリットとして、コンパイル可能なソースになってないとエラーが発生するという問題がありますが、COBOLの場合、ソースをコンパイル可能な状態にするための手間は他の言語と比較して大きいという特徴があります。「本番環境で動いているシステムのソースなんだから、コンパイルが通って当たり前じゃないか」と思うかもしれませんが、それがそうでもありません。なぜコンパイルが通るソースにするのが大変なのかについてもう少し詳しく説明します。
COBOLソースをコンパイルが通る状態にするための手間
COBOLソースをコンパイルが通る状態にするためには、COBOLのベンダ固有文法をパーサーに取り込む対応と、COBOL文法規則に沿ったソースにするためのソースの変換・修正作業の2点が必要となります。
1. COBOLのベンダ固有文法をパーサーに取り込む対応
業務で扱うCOBOL言語のソースはCOBOL85という古い規格に沿ったソースが多いのですが、COBOL85では各社で独自の言語拡張を行っており、ベンダ固有の文法が多いという特徴があります。
例えば日本語文字定数を例にとると、COBOL2002では、文字Nに引用符を続けて文字定数を定義するのに対し、COBOL85のベンダ固有の文法では、文字NCに引用符を続けて文字定数を定義する文法が存在します。
COBOL2002規格の日本語文字定数の書き方
03 WS-NAME-DBCS PIC N(4) VALUE N"豊洲太郎".
ベンダ固有の文法による日本語文字定数の書き方
03 WS-NAME-DBCS PIC N(4) VALUE NC"豊洲太郎".
OSSのCOBOLパーサーではこのようなベンダ固有の文法を解析できないことが多く、日本語文字定数を含むソースをパーサーで解析した場合、解析エラーが発生してしまいます。
解析エラーを解消するためには、NCで定義された日本語文字定数を読み込めるよう、OSSのCOBOLパーサーを修正する必要があります。
2. COBOL文法規則に沿ったソースにするためのソースの変換・修正作業
COBOLソースは、仮に本番環境で動作しているプログラムと同じソースであったとしても修正が必要になります。
以下はCOBOLソースをコンパイルし、ロードモジュール(OSがロードして実行可能な形式)を作成するまでの流れです。

ここで注意しておきたいのは、COBOL文法規則に沿った状態になるのは、プリコンパイルが終わった時点である、ということです。
以下は、マクロを利用したCOBOLソースの例です。COBOLにおけるマクロとは、定型的なコードの繰り返し記述を簡略化する機能で、特定の手順やコードブロックを名前で呼び出せるようにするものです。
以下のCOBOLソースは筆者が実際に経験したマクロ展開起因の解析エラーを再現したものです。++PROCというマクロがありますが、COBOLソースをCOBOL文法に沿って解析した場合、++PROCという記述はCOBOL文法規則には存在せず、またPROCEDURE DIVISIONがなく手続き部が開始されているため、解析エラーとなります。解析エラーを取り除くためには、プリコンパイル後のソースが含まれるコンパイルリストを入手してCOBOLソースに変換するか、++PROCという文字列をPROCEDURE DIVISION.に変換するマクロ展開処理を独自に実装する必要があります。
01 PARM-AREA.
03 PA-1 PIC X(010).
03 PA-2 PIC X(010).
*
* ++PROCは PROCEDURE DIVISION. に展開するマクロ
++PROC
*****************************************************************
* 初期化 セクション
*****************************************************************
INIT SECTION.
PERFORM INIT THRU INIT-EXIT.
PERFORM MAIN THRU MAIN-EXIT
UNTIL SW-END = 'ON'.
PERFORM FIN THRU FIN-EXIT.
STOP RUN.
また、ソースを抽出する際も注意が必要です。各システムのソースコード管理の仕組みにもよりますが、メインフレームで動いているシステムのCOBOLソース自体もメインフレームの文字コードであるEBCDICが使われているケースがあります。
EBCDICは1バイトの文字コードであるため、日本語を表現する際は、1バイトの文字コード(EBCDIC)と2バイトの文字コード(IBM漢字コード、JEF等)を切り替えることにより表現し、この切り替えにSO(Shift-Out, 0x0E)、SI(Shift-In, 0x0F)という制御コードが用いられます。そのため、日本語が含まれるソースコードをオープン系で使われている文字コード(Shift_JIS、UTF-8)に変換した場合、Shift_JIS、UTF-8はSO/SIがなくても英語と日本語を両方扱えるため、SO、SIは削除されてしまいます。その結果、COBOLではプログラムとみなされない73桁目以降(見出し領域)が左にずれ、71桁目まではみ出すことにより解析エラーが起こることがあります。
以下は実際に筆者が経験したことのある例を再現したものです。この例では、ソースコードは基本的に2バイト文字を使わず英数字や半角カナを使うシステムのようでしたが、1~6桁目に意図せず全角空白が含まれてしまったことにより、Shift_JIS/UTF-8に変換した際に73桁目以降が2桁左にずれてしまい、解析エラーが生じた、というものです。
メインフレームで表示した際のCOBOLソース (◎は全角空白、_はSO・SIを表す)
* ショキカショリ 12345678
_◎_ MOVE 0 TO WK-D-RESULT1. 12345678
MOVE 0 TO WK-D-RESULT2. 12345678
Shift_JIS/UTF-8に変換した後のCOBOLソース(◎は全角空白を表す)
* ショキカショリ 12345678
◎ MOVE 0 TO WK-D-RESULT1. 12345678
MOVE 0 TO WK-D-RESULT2. 12345678
上記は一例ですが、このようにCOBOLソースをCOBOL文法規則に沿ったソースにするためには修正の手間が発生することがわかります。
生成AIの事前処理で利用する用途での比較
COBOLソースを生成AIに入力する前に加工したい場合、生成AIを事前処理に使えない事情があると考えられるので、代わりに使える方法は構文解析(パース)か正規表現のどちらかになります。
前述の通り、COBOLソースを構文解析(パース)可能な状態、つまりコンパイルが通る状態にするには大きな手間がかかるため、入力のCOBOLソースを加工するにあたって正規表現で実現できる場合は正規表現を使うべき、ということになります。筆者が経験した限り、生成AIで事前処理が必要になったケースは以下2点となりますが、いずれも正規表現で実現できるレベルの加工処理なので、構文解析(パース)のデメリットを考慮すると正規表現で対応するのが適切でしょう。
| COBOLソースを事前処理したい理由 | 正規表現での実現手段 |
|---|---|
| COBOLソースが大きいので、SECTIONで分割したい | コメントや文字列を取り除いた状態で、"PROCEDURE DIVISION"、"SECTION"にマッチする正規表現を書いてソースを分割する |
| コメントアウトされたコードが解析に悪影響を及ぼすので削除したい | コメント(7桁目が*もしくは/の行)を取り除く処理を正規表現で書く |
まとめ
本記事では、生成AIに入力するCOBOLソースを加工する際にCOBOLパーサーをおすすめしない理由をご紹介しました。COBOLソースを構文解析(パース)可能な状態に整えるには、ベンダ固有の文法やマクロ展開、文字コード変換などへの対応が必要で、大きな手間がかかります。そのため、多くの場合は正規表現による軽量な事前処理の方が適切です。
生成AIの登場により、開発での活用において従来実現できなかったようなモダナイゼーションを実現できる可能性が高くなってきました。引き続きCOBOLのシステムに対する生成AI適用の取り組みを進め、従来解決が難しかった保守担当者の減少やブラックボックス化といった課題に取り組んでいきたいと思います。
NTT DATA公式アカウントです。 技術を愛するNTT DATAの技術者が、気軽に楽しく発信していきます。 当社のサービスなどについてのお問い合わせは、 お問い合わせフォーム nttdata.com/jp/ja/contact-us/ へお願いします。