TOPS-20 で使うSNOBOL言語
2018年4月、歴史的に貴重なDEC社 TOPS-20を使用しています。Panda TOPS-20 distribution にSNOBOL言語処理系がインストールされていました。
SNOBOL言語は、1977年に私が大学生のときにDEC社 SYSTEM-20 (TOPS-20)で出会ったすばらしい言語です。4回生のとき、特別研究でシステムプログラムを専攻してBASIC風のインタプリターをSNOBOL言語で作成しました。SNOBOL言語の日本語の解説書などありませんでしたから、図書館からSNOBOL言語を解説した英語の文献を借りてきて勉強しました。
KLH10エミュレーターをインストールしてDEC社 TOPS-20を使う目的のひとつが、懐かしいSNOBOL言語にもう一度触れることでした。
SNOBOLとは
SNOBOLは、1960年代に米国AT&Tベル研究所で開発した「文字列指向の記号言語」
(SNOBOL : StriNg Oriented symBOlic Language)です。
構造化プログラミングが提唱される前の言語なので、分岐指定による GoTo文によるプログラム制御構造しかありません。しかし、パターンマッチングに優れていることや連想配列が使えます。
1977年当時、FOTRAN/COBOL/ALGOL/アセンブラー言語などを使っていました。SNOBOL言語でパターンマッチが簡単に行えることや配列の添え字に文字列を使う連想配列は、カルチャーショックでした。後にAWKスクリプト言語を勉強したときは、SNOBOL言語の知識が役に立ち簡単に修得できました。
SNOBOLプログラムの起動方法
SNOBOLを起動するとプロンプト(SITBOL>)が表示されます。「/EXIT」と入力すると、SNOBOLを終了します。
@SNOBOL SITBOL>/EXIT EXIT
SNOBOLプログラムの起動方法はいくつかの方法があります。
【起動方法1】SNOBOLプロンプト(SITBOL>)で TTY: を指定して直接入力
@SNOBOL SITBOL>TTY: OUTPUT = "Hello, World!" END Hello, World! SITBOL>/exit EXIT
【起動方法2】SNOBOLプロンプト(SITBOL>)でファイル名を指定
@TYPE PROGRAM1.SNO OUTPUT = "Hello, World!" END @SNOBOL SITBOL>PROGRAM1.SNO Hello, World! SITBOL>/EXIT EXIT
【起動方法3】SNOBOLコマンドラインでファイル名を指定
@TYPE PROGRAM1.SNO OUTPUT = "Hello, World!" END @SNOBOL PROGRAM1.SNO HELLO, WORLD! EXIT @
SNOBOL 簡単なプログラム
SNOBOL言語の簡単なサンプルコードを示します。
@type program2.sno * Sample Program LOOP OUTPUT = "Your name? " NAME = INPUT :F(DONE) OUTPUT = " Hello " NAME :(LOOP) DONE OUTPUT = "Finished" END SAYURI HANAKO
SNOBOL言語の書式は、次のようになります。
ラベル △ 式 △ :(分岐先ラベル)
ただし、△は一つ以上のスペースです。
1カラム目 | ラベル |
2カラム目以降 | 代入文 パターンマッチ パターン置換 |
コロンの後ろ | 分岐先ラベル S(成功時) F(失敗時) :(label) :S(label) :F(label) :S(label1) F(label2) |
1カラム目が「*」の行は、コメント行です。
ENDラベルは、SNOBOLプログラムの終わりを示します。
SNOBOLの構文では、スペースは重要です。代入文の “=”の両側にスペースが必要です。また、”+” や “-” などの算術演算子の周りにはスペースが必要です。(例、I = I + 1)
標準入出力はINPUT/OUTPUTという変数に代入処理を行うことで実行されます。
INPUTは、ENDラベルの次の行から入力します。EOFになるとINPUTは失敗し :F(ラベル)に分岐します。
それでは、実行してみます。
@SNOBOL PROGRAM2.SNO Your name? Hello SAYURI Your name? Hello HANAKO Your name? Finished EXIT @
INPUT()関数でファイル入力
SNOBOLは、INPUT()関数とOUTPUT()関数を使用して詳細な入出力制御ができます。
INPUT( ‘name’, ‘device/file’, ‘format option’)
OUTPUT(‘name’, ‘device/file’, ‘format option’)
データをファイルから入力します。
@TYPE PROGRAM3.SNO * Example of INPUT() INPUT('DEV_INPUT', 'DSK:DATA.TXT') LOOP OUTPUT = "Your name? " NAME = DEV_INPUT :F(DONE) OUTPUT = " Hello " NAME :(LOOP) DONE OUTPUT = "Finished" END
INPUT()関数で、変数 ‘DEV_INPUT’にファイル’DSK:DATA.TXT’を割り付けます。
@TYPE DATA.TXT SAYURI HANAKO
実行します。
@SNOBOL PROGRAM3.SNO Your name? Hello SAYURI Your name? Hello HANAKO Your name? Finished EXIT @
DATA.TXTファイルから入力できました。
INPUT()関数 / OUTPUT()関数でTTY:入出力
コンソール出力とキーボード入力を行います。
@TYPE PROGRAM4.SNO * Example of INPUT() and OUTPUT() parameters. * The 'T' format option will prevent a line-feed from OUTPUT('Screen' , 'TTY:' ,'T') OUTPUT('Console', 'TTY:' ) INPUT('Keyboard', 'TTY:') LOOP Screen = "Your name? " NAME = Keyboard :F(DONE) Console = " Hello " NAME :(LOOP) DONE Console = "Finished" END
標準入出力を TTY: に割り付けます。
- Screenは、デバイス TTY: 出力です。’T’オプション(ターミナルモード)で、 出力に改行文字は追加されません。
- Consoleは、デバイス TTY: 出力です。
- Keyboardは、デバイス TTY: 入力です。
実行してみます。
@SNOBOL PROGRAM4.SNO Your name? Sayuri Hello Sayuri Your name? Hanako Hello Hanako Your name? ^ZFinished EXIT @
Screenで、「Your name?」と改行なしで表示します。
Keyboardで、キーボード入力となります。CTRL+Zを入力するとEOFとなります。
Consoleで、「Hello NAME」を表示して改行します。
パターンマッチング
SNOBOL言語の特徴のひとつに強力なパターンマッチングがあります。
■ パターンマッチングステートメントの形式を下記に示します。
Subject Pattern
各フィールドはひとつ以上のスペースで区切ります。
- Subjectは、検査対象文字列
- Patternは、パターン文字列
この文は、Subject文字列の左からPattern文字列をスキャンして出現するか検査し、成功/失敗フラグを設定します。成功/失敗フラグは、分岐文の S(ラベル)/F(ラベル)で参照します。
■ 置換ステートメントの形式を下記に示します。
Subject Pattern = Object
各フィールドはひとつ以上のスペースで区切ります。
- Subjectは、検査対象文字列
- Patternは、パターン文字列
- Objectは、置換文字列
パターンマッチングを行い成功した場合は、Subject文字列の一致した部分文字列をObject文字列に置き換えます。
パターンマッチングの使用例
このパターンマッチング機能を使用して、Word Count (Linuxコマンドの wc)を作ります。
@TYPE WC.SNO CNT_CHARS = 0 CNT_WORDS = 0 CNT_LINES = 0 WORDUAZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" WORDLAZ = "abcdefghijklmnopqrstuvwxyz" WORDNUM = "0123456789" WORD = "'-" WORDNUM WORDUAZ WORDLAZ PAT = SPAN(WORD) . ITEM NEXTL DATA = TRIM(INPUT) :F(DONE) CNT_CHARS = CNT_CHARS + SIZE(DATA) CNT_LINES = CNT_LINES + 1 NEXTW DATA PAT = :F(NEXTL) CNT_WORDS = CNT_WORDS + 1 OUTPUT = ITEM :(NEXTW) DONE OUTPUT = CNT_LINES " lines, " CNT_WORDS " words , " CNT_CHARS " characters" END TOPS-20 version 7 includes all the facilities of previous versions of TOPS-20 and enhancements through autopatch tape 18. It includes the new software capabilities and components listed in this document.
END文の後ろにテストデータを並べます。
それでは、プログラムを説明します。
CNT_CHARS = 0 CNT_WORDS = 0 CNT_LINES = 0
最初に、文字カウンター(CNT_CHARS)、単語カウンター(CNT_WORDS)、行カウンター(CNT_LINES)をリセットします。
WORDUAZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" WORDLAZ = "abcdefghijklmnopqrstuvwxyz" WORDNUM = "0123456789" WORD = "'-" WORDNUM WORDUAZ WORDLAZ PAT = SPAN(WORD) . ITEM
単語のパターン(PAT)を定義します。
単語の構成は、SPAN()関数によりWORD文字列で指定したひとつ以上の任意文字が連続するシーケンスと一致します。そして、パターンにマッチした部分をドット演算子(.)でITEMに設定します。
WORD文字列は、英大文字(WORDUAZ)/英小文字(WORDLAZ)/数字(WORDNUM)/”‘-“です。
NEXTL DATA = TRIM(INPUT) :F(DONE)
標準入力(INPUT)から1行入力します。TRIM()関数で余分な末尾のスペースを削除して変数DATAに設定します。標準入力がEOFになれば、DONEラベルに分岐します。
CNT_CHARS = CNT_CHARS + SIZE(DATA) CNT_LINES = CNT_LINES + 1
文字カウンター(CNT_CHARS)に、変数DATAのサイズを加算します。
行カウンター(CNT_LINES)をインクリメントします。
NEXTW DATA PAT = :F(NEXTL)
変数DATAをパターン(PAT)でマッチングして、一致部分をヌル文字で置換して消去します。一致部分は、変数ITEMに設定します。
パターがマッチしなければ、NEXTLラベルに分岐して次の行を読み込みます。
CNT_WORDS = CNT_WORDS + 1 OUTPUT = ITEM :(NEXTW)
単語カウンター(CNT_WORDS)をインクリメントします。分解した単語を確認するため、変数ITEMを出力します。NEXTWラベルに分岐して、次の単語を探します。
DONE OUTPUT = CNT_LINES " lines, " CNT_WORDS " words , " CNT_CHARS " characters
最後に、文字カウンター(CNT_CHARS)、単語カウンター(CNT_WORDS)、行カウンター(CNT_LINES)を出力します。
パターンマッチングの実行例
テストデータを下記に示します。
TOPS-20 version 7 includes all the facilities of previous
versions of TOPS-20 and enhancements through autopatch tape 18.
It includes the new software capabilities and components listed
in this document.
Word Countを実行します。
@SNOBOL WC.SNO TOPS-20 version 7 includes all the facilities of previous versions of TOPS-20 and enhancements through autopatch tape 18 It includes the new software capabilities and components listed in this document 4 lines, 30 words , 232 characters EXIT @
単語に分解して表示されました。
- 4行
- 30単語
- 232文字
SNOBOL参考資料
ネットで検索すると SNOBOLに関する参考資料がヒットします。
SNOBOL4 PROGRAMMING LANGUAGEの本のPDFがアップされています。英語ですが、この本を読みこなせば SNOBOL通間違いなしです。
THE SNOBOL4 PROGRAMMING LANGUAGE
まとめ
41年ぶりにSNOBOL言語で簡単なプログラミングしました。強力なパターンマッチングにより少ないプログラムステップで目的が達成できます。
もう少し、複雑な処理をSNOBOL言語で書きたくなってきました。
TOPS-20に関するブログ
歴史的に貴重なDEC社 TOPS-20を使うためにKLH10エミュレーターをLinuxにインストールして、TOPS-20を実行することができました。
TOPS-20に関するブログを以下に示します。
ピンバック: DEC社 TOPS-20を使う方法 SNOBOL言語の組み込み関数 編 | ある計算機屋さんの手帳
ピンバック: DEC社 TOPS-20のSNOBOL言語で8080アセンブラを作成(設計編) | ある計算機屋さんの手帳
ピンバック: DEC社 TOPS-20「hello, world」プログラミング(Ⅱ) SNOBOL | ある計算機屋さんの手帳