固定形式の列定義
COBOL の固定形式(Fixed Format)では1行を80文字として次のように領域が分割される。
| 列番号 | 名称 | 用途 | 正規化での扱い |
|---|---|---|---|
| 1〜6 | シーケンス番号 | 旧来のカード管理用の通し番号。現代の多くのエディタが自動採番する。 | 除去 |
| 7 | 標識列(Indicator) | *: コメント、/: ページ送りコメント、-: 継続行、空白: 通常行、D: デバッグ行 | 判定に使い本体は除去 |
| 8〜11 | Area A | DIVISION・SECTION・段落名・FD・01レベルなどが開始できる位置 | 命令本体として保持 |
| 12〜72 | Area B | 命令文・条件・データ定義の本体 | 命令本体として保持 |
| 73〜80 | 識別領域 | プログラム名や連番を記入する慣習。命令とは無関係。 | 除去 |
💡 80文字制限は必須ではない
現代のコンパイラの多くは80文字超の行を受け付ける設定を持つ。 しかし旧来のソースは厳密に80文字で管理されていることが多いため、本シリーズでは80文字前提で処理する。 73〜80列が全て空白の場合も識別領域として切り落とす。
標識列(列7)の詳細
列7は1文字だけだが意味は多岐にわたる。正規化で特に重要なのは次の3つだ。
| 値 | 意味 | 処理方針 |
|---|---|---|
' '(空白) | 通常の命令行 | Area A〜B(列8〜72)を命令として処理 |
* | コメント行 | 行全体を削除 |
/ | ページ送りコメント行 | 行全体を削除(* と同様に扱う) |
- | 継続行 | 前行に連結する(PART 04 で詳説) |
D | デバッグ行 | 通常は削除(WITH DEBUGGING MODE が宣言されている場合を除く) |
Area A / Area B の使い分け
Area A(列8〜11)には DIVISION 名・SECTION 名・段落名・FD(ファイル定義)・01レベルのデータ項目などを記述する。 Area B(列12〜72)には命令文やデータ項目の下位レベルを記述する。 正規化の観点からは両者を区別する必要はなく、列8〜72を命令本体として一括して扱えばよい。
* 列番号: 1234567890123456789012345678901234567890
* | | | |
* 1 7 11 12 Area B 開始
000100 PROCEDURE DIVISION. ← Area A にある
000200 MOVE 'ABC' TO WS-VAR. ← 命令は Area B から
000300 IF WS-VAR = 'ABC' ← IF も Area B
000400 DISPLAY 'MATCH' ← 継続命令は Area B
000500 END-IF.
Pythonで各領域を切り出す
Pythonのスライス(0始まり)で各領域を切り出す基本的な書き方を示す。
def parse_cobol_line(line: str) -> dict:
"""
COBOL固定形式の1行を各領域に分解する。
Pythonのスライスは0始まりなので列番号から1を引く。
"""
# 行末の改行を除去してから処理
line = line.rstrip('\n').rstrip('\r')
# 80文字に満たない場合でも安全に扱えるよう右パディング
padded = line.ljust(80)
return {
'sequence': padded[0:6], # 列1〜6 シーケンス番号
'indicator': padded[6], # 列7 標識
'area_a': padded[7:11], # 列8〜11 Area A
'area_b': padded[11:72], # 列12〜72 Area B
'ident': padded[72:80], # 列73〜80 識別領域
}
# 使用例
sample = "000100 PROCEDURE DIVISION. PROG01 "
parsed = parse_cobol_line(sample)
print(f"sequence : '{parsed['sequence']}'") # '000100'
print(f"indicator : '{parsed['indicator']}'") # ' '
print(f"area_a : '{parsed['area_a']}'") # 'PROC'
print(f"area_b : '{parsed['area_b']}'") # 'EDURE DIVISION. ...'
print(f"ident : '{parsed['ident']}'") # 'PROG01 '
💡 ljust(80) でパディングする理由
実際のCOBOLソースには末尾の空白が省略されていたり、エディタの設定によって72文字や79文字で終わる行が混在する。
ljust(80) で常に80文字にパディングすることで、スライスの範囲外エラーや識別領域の切り出し漏れを防ぐ。
固定形式ならではの罠
⚠️ 罠①: 行ラベルのない行が混在する
古いソースを近年のエディタで保存し直した場合、一部の行でシーケンス番号が省略されていることがある。 この場合でも列7の標識は有効なので、「行長が7文字未満」でなければ列7は常に読める。 行長が6文字以下の場合は標識列なし(通常行)として扱うのが安全だ。
⚠️ 罠②: タブ文字が混入している
本来 COBOL 固定形式にタブ文字(\t)は存在しないが、
VSCode などのエディタ経由で開いて保存した場合にタブが混入することがある。
処理前に line.expandtabs(8) でタブを空白8文字に展開しておくと安全だ。
⚠️ 罠③: 自由形式(Free Format)との混同
COBOL 2002 以降では列制限のない「自由形式(Free Format)」が標準化されている。
コンパイルオプションや先頭行のディレクティブ(>>SOURCE FORMAT FREE)で判定できる場合もあるが、
本シリーズでは固定形式のみを対象とする。
✅ 次の章では…
PART 03 では固定形式の理解をもとに、最初の正規化ステップである 行ラベル除去・コメント行削除・識別領域除去 を実装する。