Rev.03 1997/04/23 風つかい Rev.02 1997/02/10 風つかい Icon入門講座 Rev.01 1996/12/08 風つかい --- AWKerのためのIcon入門 --- (TRA11936@biglobe.ne.jp) (PFF01531@niftyserve.or.jp) (This textbook is in the public domain.) ■ Icon > Icon入門講座なんぞをはじめようかな 風つかい 近頃、2行以上のスクリプトを書く必要がある場合は、awkの替わりに Icon (アイコン)というテキスト処理言語を使っています。 sed や awk の1行野郎で済むものは、sed, awk ですましますが、ちょっと 頭をひねる必要のあるものは、Iconで書いています。 Iconは、なかなかユニークな特徴を持った言語で、もっと使われていいので はと思いますが、vanやnifのテキスト処理の会議室ではあまり話題には 上っていません。 興味をもたれる人が増えるといいなということで、私も使いこなせている訳 ではありませんが、入門講座なんぞをはじめてみようかと思います。 awk との比較みたいなかっこうで説明できるといいんですけれど、どうなる ことやら。 尚、Iconは PDSですので、私の文章もならって転載・編集等(そんな人い るかいな?)自由とします。 目次 第1回 Iconって何? 1.Iconって何? 2.Iconってフリーソフト? 3.資料はありますか? 第2回 Iconの入手方法は? 1.取り敢えずIconを動かしてみたい。 2.hello worldはどうやって動かすの? 第3回 Iconの特徴は?(1) 1.Iconの特徴は? 1)テキスト解析言語とでも 2)awkの処理の基本 第4回 Iconの特徴は?(2) 3)テキストファイルの読み込み 第5回 Iconの特徴は?(3) 4)パターンマッチの考え方 5)データ構造 第6回 Iconの特徴(4)制御構造 6)プログラム制御構造 第7回 Iconの特徴(5)スキャン 7)文字列走査 第8回 Iconの特徴(6)スキャン(続) 8)文字列走査(続) 第9回 データ構造 set 第10回 データ構造 list 第11回 データ構造 table 第12回 procedure/scope 第13回 procedure/scopeサンプル 第14回 type変換、他 第15回 エスケープ文字、他 第16回 wild.icn 第17回 Test Driver for wild 第18回 iyab.icn 第19回 vanlog.icn 第20回 むすび。 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) (icon_00.txt 1996/11/17 PCVAN PIG) ■ Icon > Icon入門講座(1) Iconって何? 風つかい 1.誰が作ったの? Icon(アイコン)は、米国アリゾナ大学のGriswold教授(のグループ) が、コンピュータ研究の際に作った、テキスト処理に重点をおいたプログ ラム言語です。 そして現在もGriswold教授のグループでサポートされています。 Griswold教授は、SNOBOL(スノーボウル)という強力なテキスト処理言 語をその前に作って作っています。(私は使ったことは無いのですが。) しかし、SNOBOLは今風の構造化プログラム対応ではないので、とっつ きにくいため、全面的に作り替えたというふうなことをおっしゃっていま す。 今は、テキスト処理結果をグラフィック化処理して分かりやすく見 せための機能拡張が行われつつあります。 Griswold教授は、学生へのプログラミング教育の教材にも使われていま す。 アリゾナ大学には、Icon言語のサポートグループ(icon-project)があり ます。質問等は、icon-project@cs.arizona.edu に送ると答えてもらえます。 (勿論、英語でないと分からないと思いますが。) 2.Icon ってフリーソフト? Iconは、Griswold教授(とそのグループ)が行っている研究の副産物と いうことで、PDS(Public Domain Software)とされています。 実行形式と共に、ソースファイルも公開されています。またライブラリー も公開されています。 誰でも、自由に使用や配布をして良いし、またソースをいじって、機能 追加・変更等を行ってもかまわないということです。 ということで、フリーソフトの細かい定義は別として、フリーソフトと いうことです。 尚、icon-projectはアリゾナ大学としては非公式な組織の扱いとなって いるそうです。 3.資料はありますか? 1)WWW icon-project では、WWWでIconの情報を公開しています。ここで殆ど全て の情報(と情報源)がわかります。 urlは http://www.cs.arizona.edu/icon/index.html です。 ここがIconのメインメニューとなっていまして、更に ・プロジェクト状況 ・入門ドキュメント ・プログラム ・ライブライリー ・ドキュメント 等を見たり、ファイルを入手したりできます。 メニュー次に載せます。(96/11下旬頃のもの) The Icon Programming Language Icon is a high-level, general-purpose programming language with a large repertoire of features for processing data structures and character strings. Icon is an imperative, procedural language with a syntax reminiscent of C and Pascal, but with semantics at a much higher level. Book Sale! Status Report Language Information Dave Hanson's Brief Introduction John Shipman's Tutorial An Overview Reference Information Programming Corner Implementations Versions Version 9.1 FTP Area for Binaries FTP Area for Source Program Library Indexes Technical Report Submission Guidelines FTP Area Documentation Frequently Asked Questions Technical Reports The Icon Newsletter The Icon Analyst Third Edition of the Icon Language Book Graphics Book Other Documents 2)本 The Icon Programming Language という本が発行されています。 現在は第2版を購入できます。 今は第3版の発行準備中です。予定は今年の11月中旬となっていますが 今日現在のところ発行されたというアナウンスはありません。 (現在は、もう発行されています。 追記 1997/01/07) 3)Newsletter Newsletterが年2回発行されています。 以前はもっと頻度が高かったのです が、WWWで情報公開できるようになったので、回数が削減されてきています。 (そのうち無くなるかも?) NewsletterもWWWにて、公開されているため、現在はWWWが無い環境の方のため という意味合いになってきています。 (以前は郵送料も含め無料だったのですが、今は有料。といっても印刷代 +郵送料程度。) 4)Icon Analyst 年6回、プログラミングテクニックとか応用とかについて技術サポート 資料が発行されています。(有料。と言っても印刷費+郵送料程度) 尚、どんなものか試してみるだけなら、WWWから手に入る資料で十分です。 じゃ、第1回はこの辺で。(後が続くのだろうか?) 【転載・編集自由】 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) (icon_01.txt 1996/11/17 PCVAN PIG) ■ Icon > Icon入門講座(2) Iconの入手方法は? 風つかい 1.Icon(アイコン)を、とりあえず動かしてみたいが? Iconは色んなマシン上で動きますが、Windows3.1/95の DOS窓で動くもの(386バージョン)を入手するとして説明します。 (私がこのバージョンしか動かしたことが無いもので....) 1)パッケージの入手 ・ftp://ftp.cs.arizona.edu/icon/packages から入手できます。 そこに使用環境毎のディレクトリーがあります。 acorn 13-Jun-96 13:43 - amiga 22-Jun-96 16:17 - atari 21-Mar-96 00:00 - macintosh 21-Mar-96 00:00 - msdos 24-Mar-96 00:00 - mvs 24-Apr-96 00:00 - os2 21-Mar-96 00:00 - README 20-Mar-96 00:00 1K unix 21-Mar-96 00:00 - vms 21-Mar-96 00:00 - で、ここで、msdosを選ぶと 9.0 24-Mar-96 00:00 - de.lzh 24-Mar-96 00:00 339K de386.lzh 24-Mar-96 00:00 264K ds.lzh 01-Mar-96 00:00 1.4M README 24-Mar-96 00:00 1K と、msdos用のファイルが現れますので de386.lzhを選んでダウンロードします。 (その他の環境の方は該当の機種のディレクトリーから入手して下さい。 尚、msdosでEMS無しの環境の方は、de.lzhです。 また、1.4Mの大きなds.lzhはCで書かれたソースファイルです。) 圧縮に吉崎さんのLHAを使ってくれているのを見るとうれしいですね。 日本のフリーソフトが世界で使われているのだと実感できます。 2)ファイルの解凍 ・ファイルの拡張子がLZHですので、LHAで解凍して下さい。 ・すると以下のファイルができます。これをまた解凍します。 Listing of archive : DE386.LZH Name Original Packed Ratio Date Time Attr Type CRC -------------- -------- -------- ------ -------- -------- ---- ----- ---- DOCS.LZH 23078 23078 100.0% 96-03-24 08:58:46 a--w -lh0- 593D ICON.LZH 245336 245336 100.0% 96-03-24 08:14:40 a--w -lh0- 0A1A README 1069 587 54.9% 96-03-24 08:17:08 a--w -lh1- 84A2 SAMPLES.LZH 1456 1448 99.5% 96-03-24 08:10:44 a--w -lh1- D10E -------------- -------- -------- ------ -------- -------- 4 files 270939 270449 99.8% 96-05-06 00:02:38 ・DOCS.LZHからは、ドキュメントがでてきます。 (英文です。はい。) ・IPD248 :MSDOS 32ビット版の使い方 ・IPD266 :Icon Ver9.1の概要 ・IPD267 :Ver8.0からの変更内容 ・IPD46 :トラブルレポート用紙 Listing of archive : DOCS.LZH Name Original Packed Ratio Date Time Attr Type CRC -------------- -------- -------- ------ -------- -------- ---- ----- ---- IPD248.DOC 11950 4875 40.8% 96-03-24 08:57:52 a--w -lh1- D0F9 IPD266.DOC 19190 7364 38.4% 96-03-24 08:57:54 a--w -lh1- 4621 IPD267.DOC 26971 10259 38.0% 96-03-24 08:57:56 a--w -lh1- 91A0 IPD46.DOC 786 444 56.5% 96-03-24 08:57:56 a--w -lh1- 580D -------------- -------- -------- ------ -------- -------- 4 files 58897 22942 39.0% 96-03-24 08:58:46 ・ICON.LZHからは、 ・icont.exe :Iconのコンパイラ(中間言語への変換) ・iconx.exe :実行モジュール(中間言語インタープリータ) が、でてきます。 Listing of archive : ICON.LZH Name Original Packed Ratio Date Time Attr Type CRC -------------- -------- -------- ------ -------- -------- ---- ----- ---- ICONT.EXE 144097 78446 54.4% 96-03-24 08:13:28 a--w -lh1- 4CAD ICONX.EXE 291422 166823 57.2% 96-03-24 08:13:30 a--w -lh1- 0B06 -------------- -------- -------- ------ -------- -------- 2 files 435519 245269 56.3% 96-03-24 08:14:40 ・SAMPLES.LZH からは、サンプルプログラムがでてきます。 Listing of archive : SAMPLES.LZH Name Original Packed Ratio Date Time Attr Type CRC -------------- -------- -------- ------ -------- -------- ---- ----- ---- CROSS.ICN 700 362 51.7% 85-09-08 05:54:04 a--w -lh5- 085D HELLO.ICN 85 61 71.8% 86-09-28 00:24:08 a--w -lh5- 3952 MEANDER.ICN 803 394 49.1% 85-09-10 15:02:26 a--w -lh5- 1D26 ROMAN.ICN 612 343 56.0% 85-09-08 05:54:44 a--w -lh5- 25F4 CROSS.DAT 56 52 92.9% 85-09-08 05:55:08 a--w -lh5- 97B0 MEANDER.DAT 23 23 100.0% 85-09-10 15:02:40 a--w -lh0- C092 -------------- -------- -------- ------ -------- -------- 6 files 2279 1235 54.2% 96-03-24 08:10:44 hello.icn が、よくある hello world プログラムです。 Iconのプログラムは拡張子にicnを使います。 2.hello world はどうやって動かすの? サンプルの中のhello.icn は次のようなものです。 バージョン表示、対象ホスト表示と hello world を表示するものです。 -----^ HELLO.ICN ( date:86-09-28 time:00:24 ) -------------- hello.txt を実行しますと、結果は次のようになります。 -----^ HELLO.TXT ( date:96-11-17 time:01:47 ) -------------- Icon入門講座(3) Iconの特徴は?(1) 風つかい あれれ、ヘッダーを間違えていましたね。 Iocn じゃなくて Icon です。 ~~ ~~ (追記: 当初ヘッダーのIconの綴りを間違えていたのです。) 両手でタイプしていると、右手と左手の同期がとれなくて、字が入れ違って しまうのが良くあります。 というか、左手が遅いので、右手で打つ次の文字 が先に来てしまうんですね。 それをまたコピーして使うと軒並み間違ってしまうんですね〜。 ま、いっか。 Icon入門講座の方はつづりが合っていたので。 Iconって何なんだと聞かれてましたが、なんといったらいいんでしょうね〜。 テキストデータ処理の中でも、【テキスト解析言語】とでもいったらいいの かな〜?。 ヘッダーの間違いだけで書き込むのもナンですので、 次の週末に予定して いた分からのうち少し書いてアップしましょう。 さて、第3回です。 1.Icon(アイコン)の特徴は何? 1)テキスト(文章)解析言語とでも Iconは、テキストデータ処理の中でも、テキスト(文章・文書)解析 向けに考えられたようです。 文章が、どういう構成になっているかなんかの解析(構文解析)は得意 の分野です。(でも私はその辺が良くは理解できていませんので...) 2)awk の処理の基本 まず、awk と比較できるところから説明したいので、 awkの処理の基本 事項をあげてみます。 (1) 1行づつ awkが、テキストファイル(デフォルト:標準入力) から読み込んで (2) その行を awkが、FS(Field Separator)に従って、分割し $1,$2,...へセットしてくれる。 $0へは、行全体がセットされる。 (3) スクリプトにて、$0,$1,$2...に対するマッチングパターンを 指定し、一致が取れたとき(/取れないとき)のアクション 指定する。 (4) マッチングパターン指定には、正規表現を使う。 (5) 組み込みデータ構造としては、連想配列がサポートされている。 (6) プログラム制御構造としては、 ・順次処理 ・・・順番にという当たり前の処理 ・if ... then ... else ・while ・for ・do ・&& ・|| ・ユーザー関数 ・組み込み関数 というようなところでしょうか。 この中で、連想配列は、うまく使うとプログラムとても簡潔になり、 世の中に、こんなにすばらしいものがあったのだ!。と【感動】した 覚えがあります。 今日、AWK についてあんましうろ覚えで書くのもナンだからと AWK教典 (プログラム言語 AWK)を読み返していましたら、エピローグのところ に、連想配列はSNOBOLの表から思い付いたと書いてありました。 ふむ、ふむ。だから、awk にも、Iconにも連想配列(Iconではテーブル) があるんだと納得しました。 この後に、Iconとの違いを書く予定ですがそれは、週末に... ほんじゃ、第3回はこの辺で。 (後が続くのだろうか? ・・・酒とタバコと音楽さえあれば...) 【転載・編集自由】 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) BGM: 愛よりも激しく、誰よりも愛しく/Favorite Blue BGD: 薩摩白波5:5お湯割り <- D: Drink BGS: Mild Seven Menthol <- S: Smoke (icon_03.txt 1996/11/18 PCVAN PIG) ■ Icon > Icon入門講座(4) Iconの特徴は?(2) 風つかい ううっ。また、前回の講座で、1か所Iocnになっていた。 ・・・と嘆きつつも、メゲずに第4回です。 (追記 このテキストでは、もう直っています。) 週1のペースでは、今年中に終わりそうもないので、少しペースをあげます。 前回あげた awkの処理の基本項目について、Iconとの違いをみていきましょう。 いずれの項目も 幾ばくか...大幅か...程度は色々ですが、違いがあります。 3)テキストファイルの読み込み awkで処理対象のテキストファイルを読み込むとすると、コマンドラインから (1) jgawk -f nantara.awk kantara.txt とするか (2) jgawk -f nantara.awk < kantara.txt とすれば awk は賢く、kantara.txtを1行づつ読み込んで、nantara.awkで処理しやすい ように、その行を、FS(Field Separator デフォルト:" ")の指定に従って、 欄(カラム)へ分解し、$1〜$nにセットしてくれます。 で、Iconでは、 nantara.icn をコンパイルした、nantara.exeがあったとします。 (2)のように、 nantara < kantara.txt とやれば、nantara.icnで処理でき ます。(nantara.icnにファイル読み込み関数を使うのですが。) しかし、(1)のようにコマンドラインパラメータ指定しても自動的には読み込 みは行われません。(nantara.icnの中でコマンドラインパラメータを解析し てファイルオープン手続きを行えば可能なのですが。) 更に、読み込んだ行を走査して自動的に欄に分解するような事もしません。 で・・・、自分でやるのです。そのための行解析の手段が提供されています。 その手段は、データタイプの説明をした後でないと説明が難しいので、その後 にします。 (2)の形式の 標準入力からファイル読み込みを行い、標準出力に出すプログ ラムは以下のようになります。 -----^ SAMP_01.ICN ( date:96-11-20 time:23:35 ) ------------ Icon入門講座(5) Iconの特徴は?(3) 風つかい Iconを手入れたいと思ったのは、BYTEの94/5月号の The Icon Programming Language A new way to deal with strings and structure Ralph E Griswold という記事を読んでからでした。 awkよりいろんな機能が組み込まれているし、なかなか変わった言語だな〜。 ちょうどperlに挫折しかけていたので、これなら頭の切り替えができて勉強しやすい。 ということで、使いはじめました。(その代わりperlは完全に挫折しましたが。) 現在は、この記事はWWWでみることができます。urlは次の場所です。 http://www.byte.com/art/9405/sec12/art2.htm http://www.byte.comのサーバには、過去の記事の検索機能がありますので、 とにかくアクセスして、Icon programming で検索されても見つかると思います。 では、第5回をはじめます。 ひき続き awkとIconとの違いです。 4)パターンマッチの考え方 awkの場合は (1) awkが、読み込んだ行を、先頭から走査して、 (2) FSを探してFS以外の部分を順次 $1〜$nにセットします。 (3) 更に、 awkはスクリプトで指定した $1〜$n とパターンの照合指定に 従って照合し (4) アクションを決定します。 awkでは、(1)、(2)は自動的にやってくれる訳で、プログラマーは (3)以降を プログラムするのですが、 Iconの場合は (1)、(2)の部分からプログラムできます。 (逆にやらないといけない訳です。) そのせいか、正規表現を使った照合機能はIcon自体には組み込まれていません。 (ライブラリーにはありますので、必要なら使えます。) 次のデータ構造の話をしないと、Iconが、(1)、(2)のあたりのサポートのため にどんな機能を持っているか説明しづらいので、早々に次にいきます。 5)データ構造 awkは、データタイプとして、次のタイプがある(と思います)。 ・数 整数 実数 ・文字列 ・連想配列 −−−−−−−−−−−−これ以降はIconに比較してデータタイプといえる だろうというものです。 ・正規表現文字セット :[a-z]の様な文字の集合。 パターン指定にのみ使用可能。 Iconではcset ・正規表現文字列集合 :^#[0-9]+\/[0-9]+の様な文字列集合。 パターン指定にのみ使用可能 Iconにはありません。 ・ファイル ・関数 Iconでは次のデータタイプがあります。 ・null :awkでは不要。 ・数 整数 integer :awkと同じ 実数 real :awkと同じ ☆文字 cset :文字(の集合) ・文字列 strings :awkと同じ ☆集合 set :(何かの)集合 ☆リスト list :なんて説明しようか ・テーブル table :awkの連想配列相当 ・ファイル file ・procedure procedure :awkの関数相当 ☆(訳不明) co-expression :よくわかりません では、 私がわかるものを、おおまかに説明します。 ・null これは、 awkでは無いというより不要といった方が良いと思います。 awkでは、変数を使っても特に初期化をする必要はありません。 初期値は、0 か ""(空の文字列)のどちらかの適当な方に解釈され ます。 Iconでは、初期値はnullです。というか初期化されていない状態を nullというんでしょうね。 最初に代入されたときにタイプが(大抵 ・・・あんまし自信がありません。)決まります。 awkでは、たとえばカウンターを使う時、初期値 0は特に設定しなく てインクリメントしてもよいのですが、Iconでは、初期値をセットし ないと、nullに演算したといって怒られます。 ・数字は特に違いは無いと思います。 ・cset 文字の集合です。ここでいう文字とは、1バイトのキャラクターを意味 します。 これに相当するものは、 awkにもあります。 正規表現で、 [a-z]と書いたときには、アルファベットの小文字は全て適合するので アルファベットの小文字の集合と言えると思います。 それと同じもの です。 awkでは照合パターンの指定にしか使えませんが、Iconでは何時 でも使えます。 'abcdef1234' というような表記をします。これはアルファベットの aから fまでも文字 と 1から4までの数字の集合です。 よく使う文字セットには予め用意されています。 &ucase 英字大文字 A-Z &lcase 英字小文字 a-z &ascii ascii文字 &letter a-zとA-Z &digits 0-9 &cset 全文字(256個) でも何に使うんだろう? cset同士で演算ができます。 和 c1 ++ c2 差 c1 -- c2 積 c1 ** c2 ・string 文字列です。 これは awkと同じです。 "ABCDE" というように表します。 string同士の接続ができます。 接続 s1 || s2 部分文字列を切り出せます。 文字の位置指定にて行います。 位置は文字と文字の間を表しています。 ・先頭の文字の手前が 1で順に数えます。 ・末尾の文字の後ろは 0とも表示できます。 ・後ろからも指定できます。 マイナス側に数えます。 ・1文字だけ指定する場合は、後ろの指定は不要です。 s[n:n+1] は、s[n]という表記でかまいません。 例 "ABCDE"[1:3] は"AB" "ABCDE"[4:6] は"DE" "ABCDE"[4:0] は"DE" "ABCDE"[-2:0] は"DE" "ABCDE"[3:4] は"C" "ABCDE"[3] は"C" ・set 集合です。なにかの集まりを示します。要素は制限がありません。 csetでもstring でもlistでもsetでも。また混在しても構いません。 setは、空の setを生成して、要素を挿入するか 次に述べる listを setへ変換して生成するかで作成します。 ・list 順序つけされた、なにかの集まりです。これも要素は制限ありません。 csetでもstring でもlistでもsetでも。また混在しても構いません。 これは空のリストを定義して要素を追加するか、次の様に表記します。 ["ABCD",123,["abc"]] 文字列 "ABCD"と 数 123と "abc"を要素に持つリスト を要素に 持つリストの例です。 リストの要素は位置指定ができます。 ちょっと説明が面倒なので、 別変数に代入して説明します。 L := ["ABCD",123,["abc"]] L[1] は "ABCD" となります。 L[2] は 123 です。 L[3] は ["ABC"] です。 L[3][1] は "ABC" です。 L[1:3] は ["ABC",123] です。 リストには、先頭への要素の追加、先頭からの削除(兼取り出し) 末尾への要素の追加、末尾からの削除(兼取り出し) ができます。 ・table awkの連想配列と同じですが、生成指示が必要です。 T := table() とかで生成します。()には初期値が指定できます。(指定しないと nullが初期値) T["abcd"] := 123 と表記しますと、"abcd" をキーとして、データ 123をセットした ことになります。 ・file ファイルへの入出力の時に使うファイルハンドルです。 下記はキーワード指定できます。 &output ファイル出力のデフォルト指定なので 通常は指定不要。 write(line) は write(&output,line)を 意味します。 &input ファイル入力のデフォルト指定なので 通常は指定不要。 read() は read(&input)を意味する。 &errout 標準エラー出力指定。 write(&errout,line)の様に使います。 ・procedure なんでこれがタイプに分類されるのかよく理解していません。 ・co-expression これは全く理解できていません。 ふ〜。やっとデータ構造の所まできました。 あと制御構造をやったらパターン マッチングの説明ができるようになって、それでIconの特徴の説明はおしまいとなり ます。 ほんじゃ、第5回はここらで。 【転載・編集自由】 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) BGM: MOSAIC/遊佐未森 BGD: かりん酒5:5お湯割り BGS: Mild Seven Menthol (icon_05.txt 1996/11/22 PCVAN PIG) ■ Icon > Icon入門講座(6)Iconの特徴(4)制御構造 風つかい おっと〜。 またやってしまった。 前回のcsetの説明の中で、&ucase と &lcase の補足が逆です。 a-z とA-Z を逆に書いていました。 (追記 このテキストでは直っています。) では、第6回をはじめます。 しつこく awkとIconとの違いです。 6)プログラム制御構造 Icon は、制御構造として、次のものがあります。 ・順次処理 :順番にという当たり前の処理 ・if ... then ... else :awkとほぼ同じ。 ☆case :分岐、選択。 ☆every :全ての要素に対して、繰り返す。 ☆repeat :繰り返す。 ☆until :条件が成功するまで繰り返す。 ・while :awkとほぼ同じ。 ・& :両方が成功したら成功。 ・| :いずれかが成功したら成功。 ・関数 :awkの関数とほぼ同じ。組込みprocedure ・procedure :awkの関数とほぼ同じ。ユーザ関数。 ☆fail :強制的に失敗させる。 ・if ... then ... else は、次の様に使います if ss == "TOKYO" then write("東京") # == は文字列の照合記号 else write("不明") ssの場所にも、write("TOKYO")の場所にも、write("不明")の場所にも 式が使えます 上の例は次の様に書けます。 write(if ss == "TOKYO" then "東京" else "不明")) ・case は、次のように使います。 case ss of { "TOKYO" : write("東京") "YOKOHAMA" : write("横浜") default : write("不明") } ss という変数が、 "TOKYO" だったら、"東京"と出力し "YOKOHAMA" だったら、"横浜"と出力し それ以外だったら、 "不明"と出力します。 ssの場所にも、"TOKYO"の場所にも、write("東京")の場所にも式が使えます。 上の例は、if ... then ... else と同様に、 write( case ss of { "TOKYO" : "東京" "YOKOHAMA" : "横浜" default : "不明" } ) と書いても同じです。プログラム例を次にあげます。 -----^ SAMP_05.ICN ( date:96-11-22 time:23:19 ) ------------ Icon入門講座(7)Iconの特徴(5)スキャン 風つかい 2〜3回で、Iconの特徴を述べる予定でしたが、もう7回目になってしまいました。 説明するって大変なんですね〜。 やっと今回の文字列走査(string scanning)で おしまいになる予定です。 これを早く説明したかったのですが、その前に説明して おかないといけないことが沢山あって... でも、これでも awkの知識をお持ちの 方を前提にしていますので、まだ楽なんで、 awkの知識が無い方をターゲットに説明 するのだともっと大変でしょう。 では、第7回をはじめます。 7)文字列走査(string scanning) まず、サンプルプログラムを。 スペースで区切られた文字列を順に出力する ものです。 -----^ SAMP_08.ICN ( date:96-11-24 time:18:12 ) ------------ Icon入門講座(8)Iconの特徴(6)スキャン 風つかい byte.com の記事検索は便利ですね。雑誌を購読していても古い雑誌の処分には悩み ます。 雑誌社の方でああいう仕掛けを持っていてくれると助かります。 国内の雑誌では無いですよね。 雑誌社と記事の著者との契約の問題だと思うのです が日本でもやってくれると、古い雑誌が捨てることができて助かるんですが。 さて、前回でIconの特徴を終わらせるつもりでしたが、stringでのスキャン処理が あふれてしまいましたので、続きです。 文字列から文字列を検索するための関数として、findと matchが用意されています。 ・match は、 awkの matchとほぼ同じです。(少し機能が多いのですが、私は同じ 使い方しかやっていないもので...) ・findは、uptoを string対応にしたものです。 find(s1,s2)は、文字列 s2を走査し、s1が見つかると成功しs1の開始位置を 値として持ちます。 簡単なサンプルを次に。 -----^ SAMP_11.ICN ( date:96-11-24 time:21:35 ) ------------ Icon入門講座(9) データ構造 set 風つかい 前回までで、Iconの特徴を awkと比較して説明したつもりだったのですが、読み返し てみると、データ構造のあたりで、使い方をだいぶ はしょってありますね〜。 set,list,tableについて補足をしようと思います。 というところで、第9回、いきま〜す。 set は、集合ですが、関連の関数の説明を。 ・set(L) 集合を生成するのは、set(L)関数を使います。 Lはリストです。 指定した リストの要素を持つ集合を生成します。 S := set() で空の集合ができます。 ということは、()に何も指定しない と、デフォルトでは、空のリスト[]が使われるということですね。 ・insert(S,x) 集合 Sに、要素 xを追加します。 xが既に Sに含まれるときは、Sは変化しま せん。 常に成功して、Sを値とします。 ・delete(S,x) 集合 Sから、要素 xを取り去ります。常に成功して、Sを値とします。 ・member(S,x) 集合 Sに、 xが含まれるかのチェックです。 成功すれば、xを値とします。 ・sort(S) 集合 Sをソートされた順に並んだリストに変換します。 ・演算 csetと同じように、和、差、積の演算ができます。 和 S1 ++ S2 差 S1 -- S2 積 S1 ** S2 set は、私は実用に使ったことがありませんので、良い例は出せないのですが、 Icon Newsletter に載っていた例に、若干手を入れたのがありますので、サンプルに。 【エラトステネスのふるい】というのを覚えておいでですか? 素数を洗い出す手続きですが、これをそのままプログラムして、ふるいをかける様子 を出力するプログラムです。 -----^ SIEVE.ICN ( date:96-11-26 time:00:32 ) -------------- Icon入門講座(10)データ構造 list 風つかい 今回は、listです。 awkでは、連想配列に【感動】しましたが、Iconでは、このlist に【感動】しました。 なんせ便利なんですね〜。 しかし考えてみると、データ構造 が載っている本や雑誌には、必ずでてくるリスト構造が、 プログラム言語で標準的に サポートされていないなんて、とんでもないですよね〜。 市販の本に載っているよう なデータ構造とアルゴリズムは言語でサポートして欲しいな〜。 というところで、第10回、いきま〜す。 list は、 setや table(awkの連想配列)と異なり、要素の間に順番がついています ので、色んな取り扱いが必要です。 そこで支援関数も沢山あります。 ・list(x,i) リストを生成するには、いきなり L := ["AA","BB",12,34,["DD","EE"]] という風に書いてしまうか、このlist生成関数を使います。 この関数は、 xを i個分だけ要素に持つリストを生成します。 ただし私は使ったことがありません。 というのは、最初に空のリストを作っ て、そのリストに順次追加していく使い方をするもので、新規リスト生成は L := [] で間に合うためです。 ・リストへの追加・取り出し関数 put/get,push/pop,push/pull のペア関数があります。(pushはだぶって いますが。) 要素の順番が問題になりますので、次の3要素のリストにて説明します。 L := ["AA","BB","CC"] このリストは3要素のリストで、先頭が "AA"、次が "BB"、最後が "CC"と という構成です。 【個別アクセス】 このリストの要素へは、いきなり、L[1]、L[2]、L[3]と指定して アクセスできます。 (先頭) (末尾) ------ ------ ------ リスト L | "AA" | --- | "BB" | --- | "CC" | ------ ------ ------ ↑ ↑ ↑ 要素へのアクセス法: L[1] L[2] L[3] 【末尾へ追加し、先頭から取り出す】(QUE,FIFO方式) 追加要素は末尾の後ろへ追加し、取り去るときは先頭から取り去る場合は put/get のペア関数を使います。 ・put 末尾の要素の後ろへ要素を追加します。 put の値は、要素が追加されたリストなります。 ・get 先頭の要素をリストから取り出す(取り去り)ます。 get の値は、取り出した要素になります。 (先頭) (末尾) ------ ------ ------ リスト L | "AA" | --- | "BB" | --- | "CC" | ------ ------ ------ ↓ ↑ get 先頭から取り出し put 末尾へ追加 ------ ------ | "AA" | | "DD" | ------ ------ 【先頭へ追加し、先頭から取り出す】(Stack,LIFO方式) 追加要素は先頭の前へ追加し、取り去るときも同じく先頭から取り去る場合は push/pop のペア関数を使います。 ・push 先頭の要素の前へ要素を追加します。 push の値は、要素が追加されたリストなります。 ・pop 先頭の要素をリストから取り出す(取り去り)ます。 pop の値は、取り出した要素になります。 (pop は getと同じです。) (先頭) (末尾) ------ ------ ------ リスト L | "AA" | --- | "BB" | --- | "CC" | ------ ------ ------ ↑ ↓ push 先頭へ追加 pop 先頭から取り出し ------ ------ | "DD" | | "AA" | ------ ------ 【先頭へ追加し、末尾から取り出す】(QUE,FIFO方式) 追加要素は先頭の前へ追加し、取り去るときは末尾から取り去る場合は push/pull のペア関数を使います。 put/getと逆方向の使い方です。 ・push 先頭の要素の前へ要素を追加します。 push の値は、要素が追加されたリストなります。 ・pull 末尾の要素をリストから取り出す(取り去り)ます。 pull の値は、取り出した要素になります。 (先頭) (末尾) ------ ------ ------ リスト L | "AA" | --- | "BB" | --- | "CC" | ------ ------ ------ ↑ ↓ push 先頭へ追加 pull 末尾から取り出し ------ ------ | "DD" | | "CC" | ------ ------ ・sort(L) リスト Lからソートされた順に並んだリストを生成します。 ・sortf(L,i) リスト Lの i番目のフィールドにてソートしたリストを生成します。 あ、そうそう、基本的なことを忘れていました。リストは演算子で連結ができます。 L1 ||| L2 で、リストを連結できます。 また、部分リストは部分文字列と同じように指定できます。 L := ["AA","BB","CC"] として L[1:3] は、["AA","BB"] です。 L[2:0] は、["BB","CC"] です。 では、以上のサンプルプログラムを。 -----^ SAMP_12.ICN ( date:96-11-27 time:18:25 ) ------------ Icon入門講座(11)データ構造 table 風つかい 今回は、table です。 table は、 awkの連想配列と同じものです。awkより若干、 支援関数が多くなっています。 さて、第11回を始めます。 では、table の支援関数の説明を。 ・table(value) table を生成するには、table()関数を使います。 T := table() で空の tableができます。 ()内には初期値を指定できます。 生成した後は、いきなり、 T["TOKYO"] := "東京" とか T["中山美穂"] := [1970,3,1,"O",158,80,60,84,45,"東京都小金井市"] とか key/value のペア形式でデータを挿入できます。 ・insert(T,key,value) table Tの、key に対する valueを追加します。keyが既に Tに含まれるとき は、keyに対する valueが更新されます。 Tを値とします。 ・delete(T,key) table Tから、key を取り去ります。 Tを値とします。 ・member(T,key) table Tに、keyが含まれるかのチェックです。成功すれば、keyを値とします。 ・key(T) table Tの keyを生成します。(ジェネレータ) ・sort(T,i) table Tをソートされた順に並んだリストに変換します。 i の値によって、リストの作り方とソートのやり方が違います。 i = 1 i = 2 [[key1,value1],[key2,value2],.....,[key_n,value_n]と連なったリスト keyでsort valueでsort i = 3 i = 4 [key1,value1,key2,value2,....,key_n,value_n]と連なったリスト keyでsort valueでsort では、サンプル、いきます。 -----^ SAMP_13.ICN ( date:96-11-28 time:02:30 ) ------------[[key1,value1]...]") show_wl(sort(T3,1)) write("value sort ->[[key1,value1]...]") show_wl(sort(T3,2)) write("key sort ->[key1,value1,key2,value2...]") show_sl(sort(T3,3)) write("\nvalue sort ->[key1,value1,key2,value2...]") show_sl(sort(T3,4)) end procedure show_st(T) # table を key : value ペアで出力 every s_key := key(T) do write(s_key," ",T[s_key]) return end procedure show_wt(T) # valueがリストの table を key : value ペアで出力。 every writes(s_key := key(T)," :") do { every writes(" ",!T[s_key]) write() } return end procedure show_sl(list) # リストの内容表示(テスト/表示用) every writes(" ",!list) write() return end procedure show_wl(wlist) # 2重リストの内容表示(テスト/表示用) every list := !wlist do { every writes(" ",!list) write() } write() return end -----$ SAMP_13.ICN ( lines:80 words:159 ) ------------------ Icon入門講座(12)procedure/scope 風つかい また、やってしまった。table(value)の説明で、T := set なんてやってしまって います。(追記 このテキストでは直っています。) setと同じ関数名が多いので、setの説明を修正して書いたんですが、修正がもれて しまいました。 さて、前回までは、データ構造の補足でしたが、 次は プログラム制御構造の補足です。 さて、第12回いきます。 今回は、procedure関係の補足です。 和訳すると手続きですが、awkの関数と同じ ものです。 いずれも、プログラムの構造化を支援するものです。 Iconでは組込み のものを関数(function)、ユーザが作ったものを手続き(procedure)と呼んでいます。 Iconではプログラムには、1つ(だけ)main() procedureが必要です。 その中 には、ユーザ定義のprocedureを含むことができます。 そのユーザ定義のprocedure の中にもユーザ定義のprocedureを含むことができます。 --------------------------------------------- |procedure main() | | ........... | | aaa := nantara("AA","BB") | | ........... | | bbb := kantara("CC","DD","EE") | | ........... | | end | | | | --------------------------------- | | |procedure nantara(s1,s2) | | | | .......... | | | | return ... | | | |end | | | --------------------------------- | | --------------------------------- | | |procedure kantara(s1,s2,s3) | | | | .......... | | | | aaa := dotara("FF","GG") | | | | .......... | | | | return ... | | | |end | | | --------------------------------- | | | | --------------------------------- | | |procedure dotara(s1,s2) | | | | .......... | | | | return ... | | | |end | | | --------------------------------- | --------------------------------------------- 1)変数のスコープ 前の図の例で、aaaという変数を、mainの中でもkantaraの中でも使っていますが それぞれの有効範囲(scope)は各々のprocedureの中だけです。 scope はIconでは2種類設定できます。 local そのprocedureの中だけで有効。 特に指定しなければlocalと見なされます。 global 全procedureの中で有効。 2)procedure間のデータ受け渡し 前の図の例で、mainは、nantaraを使うときに、 nantara("AA",BB") という風に、2つのデータを渡しています。 nantara側で、このデータを使うときは、 procedure nantara(s1,s2) と書いておくと s1 := "AA" ; s2 := "BB" と解釈されます。 s1,s2という名前はどういう名前を使っても構いません。 引数の数が一定しない場合や多い場合はリスト渡しをします。 nantaraを使うときに、 nantara(List) という風に、リスト渡しをして、呼ばれる側で procedure nantara(args) として args[1]から順に使っていくというやり方です。 argsという名前は、どういう名前を使っても構いません。 nantaraは通常はmainに値を返さなければなりません。 return 式 という格好で返します。 式を書かなかった場合やnantaraが失敗した場合は nullが返ります。(というか、返らない場合はnullというのが正しいのかな) 3)もう1つの返し方 あるprocedureが呼んだprocedureに値を返すやり方には return 式 というやり 方の他に suspend 式 という返し方があります。 これは、式がジェネレータの場合に使います。 例えば、 suspend (1 | 2 | 3) と書くと、このprocedureは、呼ばれる度に順に 1、2、3の値を返します。 【済みません! 私は、このsuspendは使いこなせません。】 私はプログラムを構成するときには、そういう場合はすぐリストにして return [1,2,3] というような返し方にして、呼んだ側で順に処理するような処理をします。 じゃ〜、どういう場合に使うのかというと、Iconにはバック・トラッキング(ある 処理をやっていて、結果が失敗になると別の条件で試してみる)というプログラム の組み方をサポートしています。 そういう場合に役に立つ受け渡しのやり方らし いのですが... 前の例では、1というデータを呼んだ側が試してみてだめで失敗すると、2のデー タを試して、それもだめなら 3のデータで試す というような動きをサポートする ためらしいです。 (この項の話はあまり信用しないで下さい。) 4)main の引数 main の引数はコマンドライン引数がセットされます。コマンドライン入力の 引数は、次のように使います。 nantara AAA BBB CCC とした場合、nantara.icn にて procedure main(args) と書いておけば args[1] には、"AAA" args[2] には、"BBB" args[3] には、"CCC" がセットされます。 5)引数の省略 組み込み関数では、引数が省略できて、その時はデフォルト値が使われるものが あります。 引数が3個あるもので、2個しかセットされずにprocedureが呼ばれた場合には 呼ばれた側では、3番目の引数がセットされていないことになります。すなわち nullとなります。 そこで、実現方法としては、引き数がnullかどうかのチェックをすれば良い訳 です。 nullチェックは、第7回の split.icnの中で使っています、 /c := ' \t' の所です。 cがnullなら、' \t'をセットするという処理 となります。 尚、nullでなければ...というのは、\c := ... という表現になります。 5)1度だけよ! main 以外の procedure でも、最初に呼ばれた時だけ実行したい処理がでてくる 時があります。 初期設定処理です。 そういう処理は initial { ....... ....... } という書き方をすると、最初に呼ばれた時だけ実行するようにできます。 6)忘れたくない。 main 以外の procedureでは、initialで指定した以外の部分の処理は呼ばれる度 に実行されます。 前回呼ばれたときの事は忘れています。 しかし、でも、ある変数の値は保持しておきたい場合があります。 global指定をすれば可能ですが、構成が美しくありません。 そういう場合は static 指定をすれば、値は保持されます。 7)分割コンパイル 共通的に使うprocedureやデータは、ファイルとしても別にしておいて、それを 引用したいですよね。 Iconでは、2つのやり方があります。 ・$include "abcd.def" こういう指定をプログラム先頭にて行うと、"abcd.def"ファイルはその プログラムのソースファイルの一部として扱われます。 ・link common こういう指定をすると、common.icnは、そのプログラムの一部として 組込まれます。 commonを組み込むためには、common.icnを中間言語形式にコンパイルして おく必要があります。 icont -c common.icn という風にコンパイル指定を行うと、common.u1 common.u2 というファイル ができます。 これが中間言語形式のファイルです。 icon-projectにより、汎用的に使えそうな procedure や データを集めたものが ライブラリーとしてまとめられています。 ・bipl グラフィック以外のライブラリー ・gipl グラフィック関係のライブラリー(giplを引用している) urlは以下の通りです。 ftp://ftp.cs.arizona.edu/icon/library/bipl.lzh ftp://ftp.cs.arizona.edu/icon/library/gipl.lzh 各々1M強のファイルサイズです。 で〜。第12回はこの辺で。 【転載・編集自由】 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) BGM: モモイズム/遊佐未森 BGD: 大関のものも BGS: Mild Seven Menthol (icon_12b.txt 1996/11/30 PCVAN PIG) ■ Icon > Icon入門講座(13)procedure/scopeサンプル 風つかい 前回の procedure/scopeで書いた内容をサンプルプログラムで動作確認をしてなか ったので気になってやってみましたら、案の定、私が誤解していたころがありました。 削除して訂正版をアップしました。 2度読まれた方にお詫びします。 (追記 このテキストでは直っています。) さて、今回は前回の講座の補足として、サンプルプログラムをアップします。 -----^ SAMP_14.ICN ( date:96-11-30 time:00:52 ) ------------ Icon入門講座(14)type変換、他 風つかい Iconの特徴の項で、やり残した説明を補足してきました。一応、今回でそれも終わる 予定です。 さて、今回はデータのtype変換あたりを補足説明したいと思います。 では、第14回、いきま〜す。 1)type変換 Iconでは、データ構造のところで説明しましたような色んなデータタイプがあり ます。 このデータタイプは、自動変換される場合と、意識的に変換してやらない といけない場合があります。 ・nullには、どんなデータタイプも代入できます。 変数は初期値は nullですが、そこには、数字でも stringでもでもlistでも 代入できます。 ある procedureの中で初めて使うのであれば、 いきなり no := 0 name := "辛島美登里" WINK := ["相田翔子","鈴木早智子"] とかできるわけです。 ・違うtype同士のデータの演算はできません。 上の例に引き続き xxx := no + name とか WINK +:= 1 (WINK := WINK +1 の略記) をしようとすると、実行時エラーになります。 また、いきなり、typeの決まっていない変数を使って演算しようとすると やはりエラーになります。 数字のrealとintegerは演算できます。これはできないとね。 ・組み込み関数の引数では、できる範囲は自動変換されます。 write(no) とやると、数字の 0は、文字 "0"へ変換されます。 cset,integer,real,string間ではできる範囲はやってくれるみたいです。 私は、エラーがでたら、きちんと変換するといういい加減なやり方をして います。ハイ。 以下に type変換関数をあげます。 これもできる範囲しかできないわけですが。 ・string(x) 文字列へ変換 ・numeric(x) 10進数へ変換(10進数表記文字列のみ) ・cset(x) 文字セットへ変換(文字とは1バイトキャラクタ) ・integer(x) 10進整数へ変換(10進数表記文字列のみ) Iconでは、ある変数がどういうtypeかチェックする関数があります。その名は ずばり、 type(x)です。 これを使うと、引数のデータタイプによって処理を 分ける procedureが作れます。 2)照合 Iconではデータの照合記号がデータによって異なります。 等号 不等号 比較 比較 比較 比較 数字では、 = ~= < <= > >= 文字(列)では、 == ~== << <<= >> >>= 一般的な値比較は、=== ~=== です。 すみません。 ===の使い方はよく理解していません。 尚、照合式も値を持ちます。 式1 照合記号 式2 が成功しますと、式2の値を もちます。 例えば、 20 > nn は成功すれば、nnの値を持ちます。 比較記号と 代入記号:= をつなぐと比較結果を、代入できます。 例えば、 nn >:= 5 は、成功すると、nnに 5が代入されます。 3)文字発生/文字番号 Iconでいう文字は、1バイトで表せるものということで、256通りの文字が ありえます。256文字全体を含んだ文字セットとして、&csetというキーワード があります。(&csetは、どう使うのかわかりません。) で、16進コードの 00からFFまでの256文字には、0〜255まで番号が つけられていて、この番号指定で文字を指定できます。 ・char(n) n番目の文字を生成します。 ・ord(c) 文字 cの番号を生成します。 4)文字列整形 以下の関数により文字列の整形ができます。 ・right(s1,i,s2) s1を i桁に右寄せで整形する。余りには、s2が詰められる。 ・left(s1,i,s2) rightの左寄せ版 ・center(s1,i,s2) i文字列として、真ん中寄せ。余りには、s2を使う。 s2のデフォルトはスペース。 ・trim(s,c) 末尾の文字(c)を取り去る。(末尾のスペースを取り去るのによく使う) cのデフォルトは、スペース。 ・entab(s)/detab(s) スペースをタブコードにしたり、タブコードをスペースへ変換します。 5)文字変換 map(s1,s2,s3) s1の中の文字を、s2:s3の変換テーブルで、変換します。 s2,s3のデフォルト は、&ucase(英字大文字)、&lcase(英字小文字)です。よってs2,s3を省略す ると、英字大文字を小文字へ変換する関数になります。 それでは、今回のサンプルプログラム、いきます。尚、dispは前回と同じものです。 -----^ SAMP_15.ICN ( date:96-12-01 time:00:03 ) ------------ nn の値 :",20 > nn) write("nn >:= 5 での nnの値 :",nn >:= 5) write("★char/ordの使用サンプル") write("ord(\"A\") :",ord("A")) write("char(ord(\"A\")) :",char(ord("A"))) write("★文字列整形関数の使用サンプル") write("right(\"ABCD\"\,10\,\"xyz\") :",right("ABCD",10,"xyz")) write("left(\"ABCD\"\,10\,\"xyz\") :",left("ABCD",10,"xyz")) write("center(\"ABCD\"\,10\,\"xyz\") :",center("ABCD",10,"xyz")) write("trim(\"aaabbbxxxdddxxx\"\,\'x\') :",trim("aaabbbxxxdddxxx",'x')) write("★entab/detabの使用サンプル") write("detab(\"abc\\tdef\\tfgh\") :",detab("abc\tdef\tfgh")) write("entab(\"abc def fgh\") :",entab("abc def fgh")) write("★mapの使用サンプル") write("map(\"ABCDEF\"\,\"ABC\"\,\"123\") :",map("ABCDEF","ABC","123")) write("★mapの使用サンプル/データ入れ替え") write("map(\"54321\"\,\"12345\"\,\"ABCDE\") :",map("54321","12345","ABCDE")) end -----$ SAMP_15.ICN ( lines:56 words:141 ) ------------------ Icon入門講座(15)エスケープ文字、他 風つかい 前回、少し説明残りがでましたので、補足をします。 では、15回、いきます。 1)エスケープ文字 エスケープ文字は次の通りです。 \b backspace \v vertical tab \d delete(rubout) \' single quote \e escape (altmode) \" double quote \f formfeed \\ backslash \l linefeed (newline) \ddd octal code \n newline (linefeed) \xdd hexadecimal code \r carriage return \^c control code \t horizontal tab 2)キーワード 私には、どう使うのか分からないのもありますが、次の通りです。 &allocated : i1,i2,i3,i4 # accumulated bytes allocated # (total,static,string,block) &ascii : c # cset of ascii characters &clock : s # current time of day &collections : i1,i2,i3,i4 # collection count # (total,static,string,block) &cset : c # cset of all characters ¤t : C # current co-expression &date : s # current date &dateline : s # current date and time &digits : c # cset of digits 0-9 &dump : i # if non-zero, causes dump on termination &e : r # base of natural logarithms, 2.71828... &error : i # run-time error conversion control &errornumber : i # run-time error number &errortext : s # run-time error message text &errorvalue : x # run-time error offending value &errout : f # standard error output file &fail # fails &features : s1,s2,...,sn # implementation features &file : s # current source code file name &host : s # string identifying host computer &input : f # standard input file &lcase : c # cset of lower case letters a-z &letters : c # cset of all letters A-Za-z &level : i # level of current procedure call &line : i # current source code line number &main : C # main co-expression &null : n # the null value &output : f # standard output file &phi : r # The golden ratio, 1.61803... &pi : r # The value of pi, 3.14159... &pos : i # string scanning position &progname : s # file name of the executing program &random : i # random number seed ®ions : i1,i2,i3 # current region size # (static,string,block) &source : C # activator of current co-expression &storage : i1,i2,i3 # current bytes allocated # (static,string,block) &subject : s # string scanning subject &time : i # current run time in milliseconds &trace : i # procedure tracing control &ucase : c # cset of upper case letters A-Z &version : s # version of Icon 3)算術・論理関数 私はあんまり使う機会がありませんが、次のとおりです。 abs(N) : N # compute absolute value acos(r1) : r2 # compute arc cosine asin (r1) : r2 # compute arc sine atan (r1,r2) : r3 # compute arc tangent cos(r1) : r2 # compute cosine dtor(r1) : r2 # convert degrees to radians iand(i1,i2) : i3 # compute bit-wise and icom(i1) : i2 # compute bit-wise complement integer(x) : i # convert to integer(切捨て関数に使える) ior(i1,i2) : i3 # compute bit-wise inclusive or ishift(i1,i2) : i3 # shift bits ixor(i1,i2) : i3 # compute bit-wise exclusive or log(r1,r2) : r3 # compute logarithm rtod(r1) : r2 # convert radians to degrees sin(r1) : r2 # compute sine sqrt(r1) : r2 # compute square root tan(r1) : r2 # compute tangent 今回で、私の分かる範囲は、説明を終わりました。 次回は、私が使っているプログラム例を説明したいと思います。 それでは、第15回はこの辺で。 【転載・編集自由】 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) BGM: 咲き誇れ愛しさよ/WINK BGD: 茉莉花茶 BGS: Mild Seven Menthol (icon_15.txt 1996/12/01 PCVAN PIG) ■ Icon > Icon入門講座(16)wild.icn 風つかい 前回、タイトルが間違っていましたね〜。(追記 このテキストは直っています。) それと前々回に、文字列操作関数を2つ忘れていました。では、16回、いきます。 まず、忘れた文字列操作関数を ・reverse(s1) 文字列の向きを入れ替えます。 "ABCD" を、"DCBA"へ変換する関数です。 ・repl(s1,i) 文字列 s1を i個分つなぐものです。 では、本題の wild.icnの話しへ戻ります。 予定では、YAX形式のバインダーの iyab.icnを説明する予定だったのですが、そこから呼んでいる wild.icnを先にやんな くちゃ。 ということで、wild.icnの説明を先に。 Iconは、ファイル読み込みをプログラムに記述して行います。 そこで、ワイルド カード指定でファイルを複数まとめて処理する時には、そのための procedureを作ら ないといけません。 wild.icnは、 ・引数のファイル指定に従って、MS-DOSへ"DIR"コマンドを発行し、その結果を テンポラリーファイルへ出力します。 例えば、"dir *.icn >> $$$tmp.$$$" です。 ・Iconは、このテンポラリーファイルを読み込んで解析して、ファイル毎の ・フルパス付きファイル名 ・ファイルサイズ ・日付 ・時刻 を要素として持つリストのリストを値として持ちます。 ・該当ファイルが無い場合は失敗します。 ・先頭に @をつけたファイル名リストによるファイル指定にも対応しています。 尚、"dir"コマンドの結果は メーカー・バージョンによって異なりますので、お使い の機種によっては修正が必要かも知れません。 -----^ WILD2.ICN ( date:96-12-01 time:19:52 ) -------------->" || tmp) # い時には"." } # を追加 close(dir) } default : { if not upto('.',arg) then arg ||= "." system("dir " || arg || " >>" || tmp) # ファイル指定 } } # end of case } # end of every } # end of else dir := open(tmp) | stop("cannot open " || tmp) # ファイルオープン # "dir" の結果格納ファイルから、ファイル指定部分を抜き出してリストへぶち込む。 while line := read(dir) do # tmpファイルから1行づつ読込。 put(fn_list,dir2lst(line)) # ファイル情報を抜き出して、 # リストへ格納 close(dir) remove(tmp) # 証拠隠滅 #################### # コマンド解析終了 #################### if *fn_list = 0 then fail # 該当ファイル無し else return fn_list end -----$ WILD2.ICN ( lines:56 words:236 ) --------------------") then fail # not file if find("あります") then {c_dir := "" ; fail} # c_dir リセット } # end of line ? list := split(line) # カラム分割 # case *list of { 3 : put(list,"00:00") # PC-98 no_EXT and 00:00 # ↑00:00は出ないので補う。 4 : { if charcnt(list[4],&digits ++ '-') = 8 # date test # ↑数字とハイフンだけかとういうチェック then { put(list,"00:00") # PC-98 00:00 push(list,pop(list) || "." || pop(list)) # ↑ファイル名と拡張子を取り出して、"."でつなぐ。 } else { if charcnt(s := list[4],&digits ++ ':') ~= *s # time test then list[4] := "00:00" # PC-98 00:00 } } default : { if charcnt(list[4],&digits ++ '-') = 8 # date test then { if charcnt(s := list[5],&digits ++ ':') ~= *s # time test then list[5] := "00:00" # PC-98 00:00 push(list,pop(list) || "." || pop(list)) } else { if charcnt(s := list[4],&digits ++ ':') ~= *s # time test then list[4] := "00:00" # PC-98 00:00 } } } list[1] := c_dir || list[1] # ディレクトリーを補う。 list[2] := deletec(list[2],',') # "\,"を取り去る。 list[4] := right(list[4],5,"0") # 時刻の10時の桁を補う。 return list[1:5] end -----$ DIR2LST2.ICN ( lines:54 words:248 ) ----------------- Icon入門講座(17)Test Driver for wild 風つかい 前回、wild.icn とその中で使っている procedureだけを示しましたが、実際はテス ト用のドライバーやテストデータを作ってテストしています。 それがないと、動きがわかりにくいと思いますので、その部分を参考にアップロード します。 では、17回、いきます。 dir2lst のテストドライバーです。 "DIR"コマンドの結果ファイルを読み込んで dir2lstで処理した結果を書き出すものです。 -----^ DIR2LST~.ICN ( date:96-12-01 time:19:19 ) -----------dir2lst.rst procedure main() write("test for dir2lst.icn\n") dat := open(s := "dir2lst.dat") | stop("cannot open ",s) while line := read(dat) do { write(line) writes("->") show_sl(dir2lst(line)) } end -----$ DIR2LST~.ICN ( lines:12 words:41 ) ------------------ 96-10-26 20:06 . .. 96-10-26 20:06 .. AAA AAA 10 96-10-26 20:06 AAA.AAA BBB BBB 10 96-10-26 20:07 BBB.BBB CCC 6 96-10-26 20:07 CCC CCC 6 96-10-26 CCC ↑テスト用に付加したデータ(実際にはこんなデータは無い) SRC 96-10-26 20:07 SRC 3 個 26 バイトのファイルがあります 3 ディレクトリ 44,810,240 バイトの空きがあります PC-9801VM21 MS-DOS 3.3D のDOSプロンプト ドライブ B: のディスクのボリュームラベルは user ディレクトリは B:\ICN CCC 729 95-06-16 AAA AAA 729 95-06-16 BBB AAA 1077 95-06-08 14:47 3 個のファイルがあります. 3682304 バイトが使用可能です. ドライブ I: のディスクのボリュームラベルは RAMDISK1920 ディレクトリは I:\ RCS 95-06-23 0:50 AAA AAA 729 95-06-16 BBB AAA 1077 95-06-08 14:47 CCC 1077 95-06-08 14:47 4 個のファイルがあります. 1949696 バイトが使用可能です. IBM Aptiva530 Win3.1 DOS窓 PC-DOS J6.3 ドライブ C にはボリューム・ラベルがありません ボリューム・シリアル番号は 255B-1DDB です ディレクトリーは C:\ICON\MY_PROGS . 96-05-04 18:03 .. 96-05-04 18:03 MAX_LEN ICN 326 96-02-06 1:01 PAGE ICN 2,975 96-02-06 1:15 DISP_COL ICN 553 96-05-05 18:26 TRIM ICN 68 95-06-26 14:29 ADD_NO ICN 267 96-05-07 22:50 ICON2U ICN 704 96-05-12 2:09 IYABP ICN 2,563 96-05-04 16:19 IYABPL ICN 2,520 96-05-04 16:17 ICON2E ICN 701 96-05-12 2:08 TEST ICN 41 96-05-07 23:00 12 個 10,718 バイトのファイルがあります 81,821,696 バイトが使用可能です -----$ DIR2LST.DAT ( lines:57 words:188 ) ------------------ wild.rst link wild2, disp procedure main() write("test for wilds.icn\n") write((L := ["abc"])[1]) show_wl(wild(L)) | write(L[1],"は見つからない。\n") write((L := ["*.*"])[1]) show_wl(wild(L)) write((L := ["*.icn"])[1]) show_wl(wild(L)) write((L := ["wi*.*"])[1]) show_wl(wild(L)) write((L := ["@WILD_FL.DAT"])[1]) show_wl(wild(L)) every writes(" ",!(L := ["*.icn","*.dat"])) ; write() show_wl(wild(L)) end -----$ WILD2~.ICN ( lines:25 words:52 ) -------------------- Icon入門講座(18)iyab.icn 風つかい 今回でやっと YAX形式のファイルバインダー iyab.icnの説明にたどり着きました。 では、18回、いきます。 YAX形式というのは、次のようなプログラムの前と後ろに識別行を付加した アップロード用プログラム形式のことです。 -----^ SAMP_16.ICN ( date:96-12-01 time:21:59 ) ------------ Icon入門講座(19)vanlog.icn 風つかい プログラム例の説明も今回で終わりです。 では、19回、いきます。 このプログラムは、pcvanのログファイルからメッセージを抜き出すものです。 メッセージを抜き出すだけなら、YOTさんの ygrepでpv.patを使えば高速に抜き 出せます。 私もずっと ygrepのお世話になっていましたが、pcvanのログで不便な点を解消 しようと、このプログラムを作りました。 pcvanのタイトル形式では、メッセージタイトルの先頭に識別記号がついていな いので、メッセージタイトルで検索してタグファイルを作るのが面倒なのです。 で、メッセージを抜き出すついでに、メッセージタイトルの先頭に記号つけるように しました。(記号は"■ "としています。) これで、ygrep -tg "■ " van1201.lop | irep elis でメッセージタイトルをもとに 簡単にタグジャンプできるようになりました。 ま、そんなためのプログラムです。 -----^ VANLOG2.ICN ( date:96-12-01 time:23:18 ) ------------月別書き込み数集計 風つかい #★内容 # # サンプルログ(インターネットニュースの開始) #Article 10 (561/561) in comp.lang.icon: # # サンプルログ(書込み・ニュースの終わり) #番号またはコマンド ################## link van_ln22, strings2, top2, wild2 procedure main(args) Usage := "Usage: vanlog2 van????.log" if *args = 0 then stop(Usage) # ファイル指定無し。 else fn_list := wild(args) | stop(Usage) # コマンド行解析 every list := !fn_list do { # ファイルリストから順に f_name := list[1] # ファイル名を取り出す。 if map(top_cut('\.',f_name)) == "log" # 拡張子"log"チェック then f_out := (top_get('\.',f_name) || "\.lop") # 出力先ファイル名生成 else stop("file_extension is not <>") # エラーメッセージ # ログファイルオープン dir := open(f_name) | stop("cannot open ",f_name) # 出力ファイルオープン out_dir := open(f_out,"a") | stop("cannot open ",f_out) write(&errout,top_cut('\\',f_name)," -> ",top_cut('\\',f_out)) # モニタ # ファイルから1行づつ読み込んで、処理モードに従い処理。 while line := read(dir) do { write(out_dir,van_line(deletec(line,'\^M'))) # 単独CRを削除した行データ } # の処理結果を出力 write(&errout) close(dir) # ログファイルクローズ close(out_dir) # 出力ファイルクローズ } end -----$ VANLOG2.ICN ( lines:48 words:146 ) ------------------ Icon入門講座(20)むすび 風つかい AWKer のための Icon入門講座 と副題をつけるべきだったな〜と思いつつ、私の知識 の範囲でのIconの説明を終わります。 最初に、テキスト(文章)解析言語といっておきながら、文章解析の話が全然でて こないぞ。 と、お思いでしょう。 Icon自体は、その機能を備えているのですが、私が使いこなしていないのもので.. Icon教典には、文章解析の例がでてくるのですが、よく理解できておりません。 私が使えない機能が未だ沢山あります。 ・バックトラッキング関係の機能は、ジェネレータとsuspend 以外にもあるのです が、手に負えません。 ・現時点では、グラフィック関係は Unix版で X-Windowを動かさないと無理みたい ですので試していません。 Linux あたりが、使える環境になりましたら試してみたいのですが。 でも、グラフィックの説明なんて、テキスト文章の範囲で、できるかしら。 この講座を読まれて、 ・Iconを使ってみよう。 とか、 ・Iconを極めてみよう。 とか、 ・講座の文章や例が分かりにくいからもっとわかりやすく書き換えてあげよう。 とか ・抜けている分の講座を作ってやろう。 とか お考えの方がいらっしゃると、とてもうれしいです。 ・アリゾナ大学へ留学してみよう。 とか ・今度の海外旅行は、アリゾナへいこう。 というんでも、ま、いっか。 ちなみに、アリゾナ大学は、西部劇では割とでてくるツーソンというところにあり ます。 http://www.cs.arizona.eduから、アリゾナ大学紹介 →Tucson の紹介へと たどれます。 それではIcon入門講座を終わります。長文におつきあいいただきまして、ありがとう ございました。 では、またお会いする日まで。 【転載・編集自由】 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) BGM: 瞳水晶/遊佐未森 BGD: 茉莉花茶 BGS: Mild Seven Menthol (icon_20.txt 1996/12/02 PCVAN PIG)