11. 手順書抜粋 — RPG解析編(§6)

IBM i / AS400 解析・リバース — 最良の手順と手法(匿名化公開用)

版 2026-07-22 · 対外公開用 · プロンプト+実践知見+用語集

対外公開版(匿名化済み) — 顧客名・案件名・固有ライブラリ/パス/プログラム名は一般化しています。用語は青点線にマウスオーバーで定義を表示。巻末「用語集」も参照。
この章の位置づけ: 社内キュレーション手順書 v1.1 の §6 RPGILE RPGSQLRPGLE解析を丸ごと収録。 章6の「取り違え防止キュレーション」と併読する。実装は rpg_io_parse.py 側に反映済みの部分と、 今後の厚み付け候補(SQL・インジケーター・エラー処理)が混在する。

6. RPGILE RPGSQLRPGLE解析

6.1 RPG世代と形式の判定

解析前に次を判定する。

種類特徴
RPG II/III非常に古い仕様、位置依存、サイクル依存
RPG/400H/F/E/I/C/O仕様、インジケーター多用
RPG IV固定形式H/F/D/I/C/P仕様、列位置依存
RPG IV混在形式固定形式+/FREE
完全フリーフォームRPG**FREEctl-optdcl-fdcl-s
SQLRPGLE/EXEC SQLまたはexec sqlを含む
ILE RPGモジュール、プロシージャ、サービスプログラム、活動化グループ

固定形式RPGでは、単純に空白を削除したり整形したりしない。列位置そのものが構文の一部である。

6.1.1 固定形式RPGにおける命令コードと空白の扱い

固定形式RPGでは、CHAINREADWRITEUPDATEEXSR等が「予約語として周囲の文字より優先的に認識される」ため動作するわけではない。

コンパイラーは、行内の列位置を基準として、各部分を別の欄として読み取る。

概念的には次のように分かれている。

仕様タイプ | 条件標識 | 演算項目1 | 命令コード | 演算項目2 | 結果フィールド | 結果標識

例えば、等幅フォント上では次のように見えるコードがある。

C     CUSTOMERNO    CHAIN     CUSTOMERF

これは空白文字を単なる区切りとして解釈しているのではなく、CUSTOMERNOCHAINCUSTOMERFが、それぞれ所定の列範囲に置かれているため認識される。

したがって、画面表示、HTML変換、PDF変換、OCR、CSV化等によって空白が詰まり、次のように見えたとしても、

CUSTOMERNOCHAINCUSTOMERF

元のソース上で各文字が正しい列に存在していれば、コンパイル時には別々の欄として解釈される。

この場合の正しい理解は次のとおりである。

> 「書き方として不適切だが、予約語が優先されて動く」のではない。

> 「固定形式の列定義に従った正常な記述であり、表示上は空白が少なく見えることがある」。

自由形式RPGとの違い

自由形式RPGでは、列位置ではなく、空白、括弧、演算子、セミコロン等による字句の区切りが重要になる。

chain CustomerNo CustomerF;

次のように命令コードと識別子を連結すると、通常はCHAIN命令とCustomerNoには分解されない。

chainCustomerNo CustomerF;

これはchainCustomerNoという一つの識別子として扱われるか、構文エラーになる可能性がある。

括弧が字句の境界になる次の記述は解析できる場合がある。

chain(e)CustomerNo CustomerF;

ただし、可読性と保守性のため、次のように空白を入れる。

chain(e) CustomerNo CustomerF;

固定形式か自由形式かを判断する目安

判定項目固定形式自由形式
仕様タイプ行頭付近のHFDICOPctl-optdcl-fdcl-s
列位置構文上の意味を持つ原則として意味を持たない
文末セミコロンを使用しない旧形式が中心セミコロンが必要
命令位置命令コード欄に配置行内の任意位置
空白圧縮ソース破壊につながるトークン境界を保てば影響が小さい
自動整形原則禁止、専用パーサーが必要RPG対応フォーマッターなら可能

AI・変換ツールへ渡す際の必須ルール

固定形式RPGを解析、変換、検索、AI投入する場合は、次を守る。

  1. 元ソースの1行を固定長のまま保存する。
  2. 行頭からの列番号を保持する。
  3. タブ文字へ変換しない。
  4. 連続空白を1文字へ圧縮しない。
  5. 行頭・行末の空白を自動削除しない。
  6. 比例フォント表示だけを根拠に構文を判断しない。
  7. OCR結果だけで解析を確定しない。
  8. HTMLではwhite-space: preまたはpre-wrapを使用する。
  9. Markdownではコードフェンス内に原文を保持する。
  10. CSV化する場合も、元行、列開始位置、列終了位置を別途保持する。
  11. 自由形式へ変換する場合、変換前後をコンパイルし、外部記述、標識、命令拡張子を比較する。
  12. 元ソースと「人間向けに整形した表示用ソース」を別ファイルとして管理する。

推奨する固定形式の構造化データ

{
  "sourceLineNumber": 245,
  "rawLine": "C     CUSTOMERNO    CHAIN     CUSTOMERF",
  "specificationType": "C",
  "factor1": "CUSTOMERNO",
  "operationCode": "CHAIN",
  "factor2": "CUSTOMERF",
  "resultField": "",
  "resultIndicators": [],
  "parserMode": "FIXED_FORMAT",
  "columnLayoutVersion": "RPG_IV"
}

rawLineは整形せず、抽出した原文をそのまま保存する。

列ずれを疑う条件

次の場合は、ソースの破損または変換ミスを疑う。

列ずれが疑われる場合は、ソース物理ファイルの元メンバー、コンパイルリスト、SEUまたはRDi上の列ルーラーを基準に再確認する。

6.2 解析単位

各プログラムについて、次を作成する。

プログラム概要
入力
出力
更新ファイル
参照ファイル
呼出元
呼出先
外部API
画面
帳票
メッセージ
データエリア
データキュー
IFS
コミット単位
例外処理
業務ルール
日付処理
文字コード処理
並行実行・ロック
性能上の注意
未確定事項

6.3 制御仕様

確認対象:

DFTACTGRP
ACTGRP
OPTION
BNDDIR
THREAD
CCSID
DATFMT
TIMFMT
DECEDIT
SRTSEQ
LANGID
ALWNULL
DEBUG
COPYNEST
EXPROPTS
MAIN
NOMAIN

確認観点:

6.4 ファイル仕様

ファイルごとに次を抽出する。

RPG上のファイル名
外部記述/プログラム記述
入力/出力/更新/組合せ
キー付き/キーなし
DISK/WORKSTN/PRINTER/SPECIAL
USROPN
EXTFILE
EXTMBR
RENAME
PREFIX
IGNORE
INCLUDE
COMMIT
INFDS
INDDS
RECNO
SFILE
MAXDEV
HANDLER

ファイル利用表

項目
RPGCUSTL1
宣言名CUSTL1
コンパイル時ライブラリーDBLIB
オブジェクトタイプLF
レコード様式CUSTR
利用方法READ、UPDATE
キーCUSTOMER_NO
実行時オーバーライド有/無/不明
実行時実体TESTLIB/CUSTL1
根拠DSPPGMREFOVRDBF+ジョブログ
信頼度確定

6.5 データ定義

抽出対象:

DCL-S
DCL-C
DCL-DS
DCL-PR
DCL-PI
DCL-PARM
DCL-SUBF
LIKEDS
LIKEREC
LIKE
QUALIFIED
TEMPLATE
DIM
OCCURS
BASED
POINTER
OBJECT
VARYING
CONST
VALUE
OPTIONS(*NOPASS:*OMIT:*VARSIZE)
INZ
STATIC
EXPORT
IMPORT
CTDATA
FROMFILE

確認観点:

6.6 制御フロー

抽出対象:

IF / ELSEIF / ELSE
SELECT / WHEN / OTHER
DOU / DOW / FOR
ITER / LEAVE
MONITOR / ON-ERROR
RETURN
GOTO / TAG
EXSR / BEGSR / ENDSR
CALL / CALLP
プロシージャ呼出

作成するもの:

6.7 ネイティブI/O

抽出対象:

CHAIN
SETLL
SETGT
READE
READPE
READ
READP
WRITE
UPDATE
DELETE
EXCEPT
OPEN
CLOSE
UNLOCK
FEOD

各命令について記録する。

対象ファイル
対象レコード様式
キー値
キー項目順
部分キーか完全キーか
昇順/降順
検索開始位置
ループ条件
%FOUND
%EOF
%EQUAL
%ERROR
レコードロック
例外拡張子(E)
結果インジケーター
更新対象項目
コミットメント制御

setll (CustomerNo) CustL1;
reade (CustomerNo) CustL1;
dow not %eof(CustL1);
   // 処理
   reade (CustomerNo) CustL1;
enddo;

このコードを解析するときは、次が必要になる。

  1. CustL1の実体。
  2. LFのキー順。
  3. 複合キーのどこまで指定しているか。
  4. SELECT/OMIT条件。
  5. アクセスパスの昇降順。
  6. レコード様式名。
  7. オーバーライドの有無。
  8. ジョブのライブラリー・リスト。
  9. ロック待ち時間。
  10. 読取後の更新有無。

6.8 SQL解析

抽出対象:

SELECT
INSERT
UPDATE
DELETE
MERGE
CALL
VALUES
SET
DECLARE CURSOR
OPEN
FETCH
CLOSE
PREPARE
EXECUTE
EXECUTE IMMEDIATE
COMMIT
ROLLBACK
SAVEPOINT
CONNECT
SET OPTION
GET DIAGNOSTICS
WHENEVER

各SQLについて記録する。

静的SQL/動的SQL
対象スキーマ
対象表・ビュー
列
JOIN
WHERE
GROUP BY
HAVING
ORDER BY
分離レベル
コミット
カーソル
ロック
ホスト変数
NULL処理
SQLCODE
SQLSTATE
GET DIAGNOSTICS
動的に生成される部分
実行計画取得可否

特に注意すること

6.9 呼出関係

区別して記録する。

呼出方式名前解決
外部プログラム静的名称CALLP SomePgm(...)EXTPGM('ABC')実行時ライブラリー検索
動的プログラム名変数、API、コマンド文字列実行時のみ確定
バインド済みプロシージャEXTPROCバインド情報
サービスプログラムBNDDIR、BNDSRVPGMバインド時
コマンド実行QCMDEXC、system()文字列解析が必要
SQLプロシージャCALL schema.procSQLパス・命名規則
APIQSYS API等パラメーター形式も解析

動的呼出候補の抽出

6.10 インジケーター

古いRPGでは、次を一覧化する。

*IN01~*IN99
*INLR
*INRT
*INH1~*INH9
*INKA~*INKY
ファイル状態インジケーター
結果インジケーター
制御レベル
表示ファイル応答インジケーター

インジケーター表

番号設定箇所解除箇所参照箇所DDS用途意味信頼度
03検索エラー時初期化時画面出力前ERRMSG表示顧客未登録確定
12不明不明EXSR条件なし未確認未確定

6.11 日付・時刻・数値・文字列

確認対象:

UDATE
*DATE
%DATE
%TIME
%TIMESTAMP
%DIFF
%SUBDT
%YEARS等
MOVE / MOVEL
TEST(D/E/T)
TIME
日付8桁・6桁
和暦
年度
締日
ゼロ日付
数値化日付
CCSID変換
EBCDICゾーン
外字
全角・半角
末尾空白

特に古いRPGでは、日付が数値・文字列・ゾーン10進数で管理されることがある。項目名だけで日付と断定せず、利用箇所と値例を確認する。

6.12 エラー処理

抽出対象:

MONITOR / ON-ERROR
(E)拡張
%ERROR
INFDS
PSDS
INFSR
*PSSR
SQLCODE
SQLSTATE
GET DIAGNOSTICS
SNDMSG
SNDPGMMSG
QMHSNDPM
RETURN
SETON LR
ROLLBACK

確認する情報:


← 10. 手順書との差分・いま採る最短路12. 手順書抜粋 — 収集・依存・実行時 →