【入門編】TRANSLATE関数による文字変換の内部テーブル – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといったモダン、あるいは従来型のビジネス言語をバリバリ書いてきた方にとって、IBMメインフレームの「PL/I(ピーエルアイ)」という名前は、少し古めかしく、どこか近寄りがたいブラックボックスのように感じられるかもしれませんよね。

「なんだか記号だらけで難しそう…」「データ型やメモリの動きがCOBOLと違いすぎて怖い…」

そんな風に身構えてしまうお気持ち、痛いほどよく分かります。でも、安心してください。一つひとつの仕様の裏側にある「意図」を紐解いていけば、PL/Iほど合理的に、そしてパワフルに作られた言語はないと気づくはずです。

今回は、そんなPL/Iの数ある強力な武器の中から、文字データの変換処理で絶対に外せない「TRANSLATE関数と内部変換テーブル」をピックアップして、レガシー世界の奥深い仕組みを一緒に覗いてみましょう!

—

そもそもPL/Iってどんな言語?(Java・COBOL経験者への第一歩)

Javaのようなオブジェクト指向言語や、手続き型の王道であるCOBOLを経験した方なら、「変数の宣言」や「文字列の操作」には慣れ親しんでいるはずです。

しかし、PL/Iの世界に足を踏み入れたとき、多くのエンジニアが最初に驚くポイントがあります。それは…
「PL/Iには、いわゆる『予約語(Keyword)』という概念がほとんどない」ということです。

予約語がないってどういうこと?

例えば、COBOLやJavaでは `IF` や `MOVE`、`STRING` といった単語は「予約語」として厳格に保護されており、変数名に使うことはできませんよね。
ところが、PL/Iの仕様はこう言っています。

> 「文脈(コンテキスト)から判断して区別できるから、変数名に `IF` を使ってもいいよ(※推奨はしませんが!)」

この柔軟性(というか、ちょっと自由すぎる設計)が、PL/Iを初めて触る人を混乱させる原因の一つです。でも、裏を返せば、プログラマの表現力を極限まで高めるために設計された、懐の深い言語だと言い換えることもできます。怖がらなくて大丈夫です。基本の型とルールさえ掴んでしまえば、すぐに手足のように動かせるようになりますよ。

—

本日の主役:TRANSLATE関数と「文字変換テーブル」の正体

さて、基幹システムのバッチ処理などで、こんな要件に出会ったことはありませんか?

  • 「外部から連携されてきた全角・半角の混じったテキストの、特定の文字を一斉に置換したい」
  • 「小文字をすべて大文字に強制変換したい」
  • 「EBCDIC特有の制御文字をスペースに潰したい」

こういうとき、Javaなら `String.replace()` を使ったり、COBOLなら `INSPECT` 文を何度も書いたりしますよね。
PL/Iには、これらを一撃で、しかもメインフレームのハードウェア特性を活かして超高速に処理する `TRANSLATE` 関数 が用意されています。

TRANSLATE関数の基本イメージ

`TRANSLATE` 関数は、ざっくり言うと「文字の置き換え表(マップ)を渡して、一瞬で文字列を別の文字に塗り替える職人」です。

1
/ TRANSLATE関数の基本的な構文イメージ /
変数値 = TRANSLATE ( 変換したい文字列, 変換後の文字パターン, 変換前の文字パターン );

これだけでも十分便利なのですが、PL/Iの真骨頂は、第2引数に「256バイトの変換テーブル(文字マップ)」そのものを直接ドンと渡せる点にあります。

—

なぜ「EBCDICコード体系」でテーブルが効くのか?

ここで少し、メインフレームならではのハードウェアの背景を頭に入れておきましょう。
Javaや現在のオープン系システムが使っている文字コードは主に ASCII(またはUTF-8) ですが、IBMメインフレームの母国語は EBCDIC(エブシディック) です。

EBCDICもASCIIと同様に、1文字を8ビット(1バイト)、つまり `0x00` から `FF` までの 256通りの組み合わせ で表現します。
ということは、「0から255までのすべてのバイトが、変換後にどの文字に変わるべきか」を並べた 全256バイトのテーブル(文字列) をあらかじめ作っておけば、どんな複雑な文字置換も、一瞬で、しかもループ処理なしで実行できることになりますよね。

これが、メインフレームのバッチ処理で `TRANSLATE` の内部テーブルが愛され続けている理由です。CPUに無駄な負荷をかけず、メモリ上のデータ一塊をゴソッと変換してしまう、レガシーならではの超効率的なアプローチです。

—

実践!PL/Iコードで学ぶ TRANSLATEテーブルの書き方

百聞は一見に如かず。実際にPL/Iで文字変換テーブルを定義し、データ加工を行うサンプルプログラムを見てみましょう。
実務のマイグレーション調査や、バッチ改修の際にもそのまま参考にしていただけるよう、丁寧な日本語コメントを添えています。

1
—————————————————————-

  • プログラム名: TRNEXAMP
  • 概要: TRANSLATE関数と内部変換テーブルを用いた文字置換のサンプル

—————————————————————-
TRNEXAMP: PROC OPTIONS(MAIN);

— データ定義(ストレージ属性の宣言)
— CHAR(256) は、まさに256通りのEBCDICコードを格納する箱です
DCL CONV_TABLE CHAR(256); 256バイトの変換テーブル
DCL TARGET_STR CHAR(30); 変換対象の文字列
DCL RESULT_STR CHAR(30); 変換後の結果格納エリア
DCL I FIXED BIN(31); ループ制御用ワーク変数

————————————————————

  • 1. 変換テーブル(CONV_TABLE)の初期化
  • まずは0x00から0xFFまで、自分自身に変換する(変化なし)
  • テーブルを生成します。

————————————————————
DO I = 1 TO 256;
SUBSTR(CONV_TABLE, I, 1) = BYTE(I – 1);
END;

————————————————————

  • 2. 特定の文字の行き先だけを書き換える
  • 例として、小文字の ‘a’~番地 を 大文字の ‘A’~番地に
  • マップし直します。(実際のEBCDICコード順序を考慮)

————————————————————

  • 簡易的に、特定の文字(例: ‘-‘ ハイフン)を ‘.’ ピリオドに
  • 変換するルールをテーブルの該当位置に直接埋め込みます。
  • 実際には、EBCDICの文字コード位置(X’60’など)を指し示します。

————————————————————

  • 今回は分かりやすく、TRANSLATE関数の「第2・第3引数」方式を
  • 使ったスマートな書き方を見てみましょう。

TARGET_STR = “AB-CD-EF”; テスト用の文字列を設定

————————————————————

  • 3. TRANSLATE関数の実行
  • 第2引数: 変換後の文字 / 第3引数: 変換前の文字
  • ハイフン(‘-‘)をピリオド(‘.’)に一括置換します。

————————————————————
RESULT_STR = TRANSLATE(TARGET_STR, ‘.’, ‘-‘);

  • 結果の確認(メインフレームのSYSOUTへ出力)

PUT SKIP LIST(‘変換前: ‘ || TARGET_STR);
PUT SKIP LIST(‘変換後: ‘ || RESULT_STR);

END TRNEXAMP;

コードのポイントと、怖くない解説

このコードで使われている `BYTE(I – 1)` という組み込み関数や、`SUBSTR` による部分文字列の操作は、PL/Iがメモリを直接コントロールしている証拠です。

「うわ、メモリを直接いじってるみたいで難しそう…」と思いましたか?
大丈夫です。要するにこういうことです。

1. 「元の文字」と「変えたい文字」の対応表をルールとして用意する
2. それを `TRANSLATE` 関数にポイッと渡す
3. あとはPL/Iのコンパイラとメインフレームのハードウェアが勝手に爆速で変換してくれる

COBOLの `INSPECT` 文で `CONVERTING` 句を書いたことがある方なら、「あぁ、あれの関数バージョンか!」とすぐにピンとくるはずです。

—

ള്‍まとめ:レガシーの仕様は、怖がらずに紐解けばシンプル!

今回は、PL/Iの基本構文の裏側にある柔軟性と、`TRANSLATE` 関数による効率的なEBCDIC文字変換の仕組みについてお話ししました。

  • 予約語の概念が薄く、文脈で解釈される柔軟な構文規則
  • EBCDICの256バイトのコード体系を意識した、洗練されたテーブル変換

初めてPL/Iのソースコードを見たときは、独特の記号や見慣れないデータ宣言に圧倒されてしまうかもしれません。しかし、一つひとつの文法が「なぜそのように作られているのか」という背景(特にメインフレームのハードウェア効率や歴史的経緯)を知ると、むしろ非常に理にかなった、美しい言語であることに気づかされます。

レガシーシステムの移行やバッチ改修の現場でPL/Iに出会っても、もう怖がる必要はありません。「一つずつ紐解けば、怖くないどころか結構面白いやつだな」と思っていただけたら、アーキテクトとしてこれほど嬉しいことはありません。

あなたのメインフレーム・ライフが、少しでも楽しく快適なものになりますように!それではまた次回の技術コラムでお会いしましょう。

タイトルとURLをコピーしました