を使って排他的な開始条件として指定した場合には、同 し長さになる規則の順番に注意を払う必要はありません ( 逆にいえは、非排他的な開始条件を使う場合には、規 則の出現偵に注意する必要があります ) 。 宣言した状態にいないときは、どんな状態となってい るのでしよう。さきほどは、、普通の状態 " とごまかして いましたが、本当はこの状態にも名前が付いています。 INITIAL という名前です 2 。ですから、非排他的な開 始条件を使う場合にも、 INITIAL という開始条件名を 使うことで排他的な開始条件と同様な指定をおこなうこ とができます。たとえは、 %x string く string>. %s string く INITIAL> . く string> . と、 ECHO ; {ECHO ; ECHO ; {ECHO ; ECHO ; } ECHO LJN Ⅸ流プログラミング 74 バックスラッシュを正しく処理しながら、なおかっ改行 文字とバックスラッシュがヌ寸応していることを調べるの は、なかなか大変です。これにマッチする正規表現は、 次のようになります。 こでは、バックスラッシュに続くのはかならす 1 文 字と仮定したのでまだ簡単です。しかし、バックスラッ シュの後ろには 8 進数を指定することもでき、その場合 には 1 ~ 3 個の数字が並べられるとしたら・・・・どんどん 複雑になってしまいます。しかも、文字列表現を認識す るだけでなく、その中身カ俵す文字列を取り出したいと したら、文字列を認識したあとで、さらにその中身を確 認しなければなりません。 この例題を、開始条件を使って書いたプログラムを以 下に示します。 %s string Char char buf [ 1024 ] ; とは、まったく同し意味になります。 状態に関して、もう 1 つ触れておかなければならない ことがあります。それは、ある状態に移行するための方 法です。これには、特殊なアクションを使います。アク ションとして、 BEGIN(string) を指定すると、この次の入力を角斤する段階から string 状態となります。 最終的に作成される C 言語のソースファイルのなか #define では、状態は、 文字列のなかに改行文字を含むことができるが、 開始条件を使った例 ることはできません。注意してください。 や変数名など、ほかで用いている名前を状態名に指定す を使ったマクロとして扱われます。したがって、関数名 その UNIX MAGAZINE 1996.12 2 状態名の大文字と小文字は区別されます。 みます ( ちょうど C 言語の文字列と同様のものです ) 。 場合には直前にバックスラッシュが必要な言語を考えて く INITIAL>\" { p = buf ; BEGIN(string) ; く string>\" puts (buf) ; BEGIN(INITIAL) ; こで出力 * / く string>\\( [ 0 ー 7 ] ) { 1 , 3 } { 1 ong strtol(&yytext [ 1 ] , 0 (char * * ) 0 , 8 ) ; * p 十十 く string>"\\r" く string>"\\n" く string>"\\t" く string>"\\f" く string>" \\b" * p 十十 * p 十十 * p 十十 * p 十十 * p 十十 く string>\\( . ハⅡ ) く string>\n { int C ; while ( (c input ( ) ) ! = EOF & & c ! = * p + + = yytext [ 1 ] ; BEGIN(INITIAL) ; く string>. * p 十十 く INITIAL> い” ] + *yyt ext ; ます、定義部分で開始条件を宣言しています。 では、 lex でも使えるように非排他的な開始条件として 宣言しています。規則部分の最初では、認識した文字列 の実際の表現をオ内するための配列と、その配列を指す ためのポインタを宣言しています。前回も紹介しました 115
が、この部分は字旬角斤プログラムの先頭に組み込まれ るので、字句角斤プログラムのアクションで利用可能な 変数を宣言することができます。 規則の説明に入りましよう。最初の規則には、開始 条件として INITIAL を指定しています。これは、普 通の状態で、、” " を認識したときに実行するアクションの 指定です。このアクションでは、さきはど宣言した開始 条件、、 string" に入ることを BEGIN アクションを使っ て指定しています。つまり、この字句角斤器では、最初 ' を認識した段階で string 開始条件に入ります。 次の規則は、 string 開始条件になっている場合に” を認識したときのためのものです。 string 開始条件は文 字列を処理する部分ですから、 こで”を認識したと いうことは文字列の終りを認識したことになります。 こでは、文字列の最後に ' \ 0 ' を入れて、その文字列を出 力しています。本来は、 こで文字列を認識したときの 処理をするのですが、今回はたんに文字列の内容を出力 するだけです。最後に、文字列の認識が終了したため、 状態を INITIAL に戻しています。これを忘れると、 れ以降も文字列の内部として処理されてしまうので、注 意してください。 次の規則は、バックスラッシュの後ろに数字を並べた ときの処理をおこなっています。数字は 8 進数とみなさ れ、その 8 進数カ俵す文字コードをもつ文字に変換され ます。この規則では、アクションの最初に変数 ( 。 ) の宣 言があることに注意してください。アクションは中括弧 で括られているため、 C 言語にとっては新たなプロック として処理されます。もちろん、アクションのなかだけ で有効な変数を最初の部分で宣言しておいてもよいので すが、各プロックの先頭で宣言することもできます。 次に並ぶ 5 行は、バックスラッシュの後ろに特定の文 字を付けて特殊な文字を表すェスケープ・シーケンスの 処理です。ここに一致しなかった文字は、バックスラッ シュの後ろに書かれていても通常の文字として解釈され ます。この処理は、その次の規則に書かれています。 次の規則では、文字列の途中に、前にバックスラッシ ュカ咐いていない改行文字か現れたときの処理をしてい ます。ここでは、文字列の終りを示す、、” " までをたんに 読み飛ばすことでエラー処理をしています。一般のプロ グラミング言語を考えた場合、この方法は危険すぎるか もしれません。ワーニング・メッセージを出力したうえで バックスラッシュの付いた改行文字として扱ったり、改 116 行文字の前に ”か挿入されているとみなして扱うとよ いかもしれません。よけいな文字を読み飛ばすのには、 前回紹介した特殊なアクション input を利用していま す。 次の行は、文字列中の普通の文字を認識したときの処 理です。この場合には、たんにその文字をバッフアに加 えています。最後の行は、文字列中ではない文字を読み 飛ばすのに使っています。 lex では、一般的にパターンに 一致する文字列カ張くなるはど処理速度が上がります。 そこで、「文字列中でない文字とは、文字列の始まりで ある”を除く文字が 1 文字以わ里続している場合」と 考えてパターンを指定しています 3 。 このプログラムでは、同じ開始条件をもつ規則が数多 く記述されています。 flex であれば、これらをまとめて 記述することも可能です。 たとえは、 く string>"\\r" く string>"\\n" く string>"\\t" く string>"\\f'i く string>"\\b" という 5 行を、 く string>{ * p 十十 * p 十十 * p 十十 = * 十十 * p 十十 * p 十十 = * p 十十 = * p 十十 * p 十十 * p 十十 とまとめることもできます。 コメントを取り出す もう 1 つ例題を見てみましよう。今度は C のプロ グラムに含まれるコメント部分を出力するプログラムで す。 C 言語のコメントは、、 / * " で始まります。この部分 はそのまま書けはよいので簡単ですが、間題はその後ろ の部分です。 こは、 「任意の文字列がきてよいが、最初に、、 * / " という文字 列をみつけたところでコメントか終る」 と決められています。間題は、これをどう表現するかで す。今回は、同じプログラムをいくつか違う形式で書い てみます。 3 アクションには何も書かなくてもよいはすですが、なぜか lex ではう まく動かないので、空のアクションを指定しています。 UNIX MAGÅZINE 1996.12
DZ—X 流プログラミング 字列の始まりの文字を読み込んだら、文字列の終りの文 字を読み込むまて特別な処理をしたい場合などに便利で す。 実例を示す前に、ます使い方を紹介しましよう。最初 に、定義部分で使用する状態を定義しておきます。 %s string この例では、 str ⅲ g という状態を定義しています。最 初の、、 % s " が、状態を宣言する行であることを示してい ます。このあとに書いた string という文字列が、状態 名になります。複数の状態を用いる場合には、状態名を 空白で区切って並べます。 規則部分で、パターンの前に不等号で括って状態名 を付けると、それが開始条件となります。開始条件が 指定されると、その状態のときにだけ規則か有効になり ます。 く string> 74 今泉貴史 {ECHO ; ECHO ; } ECHO ; この場合は、最初の規則は string 状態のときにだけ 有効になります。それ以外の場合には、 2 番目の規則が 有効となるわけです。したがって、普通の状態では入力 文字がそのまま出力されますが、 string 状態では文字が 2 回出力されます。状態名は、カンマで区切って複旨 定できます。この場合、現在の状態が指定されたなかに 入っていれは、その規則か有効になります。 しつは、上の説明にはごまかしがあります。 string 状 態で最初の規則が有効になるというのは正しいのです が、同時に 2 番目の規則も有効になっています。同じ 前回は、正規表現を使ってケえた仕様から字句角斤器 長さの文字列に一致するため、規則としてさきに書いて を生成する lex (flex) の紹介をしました。 lex を使えば、 ある最初の規則に一致しているだけです。 lex にはない プログラミング言語処理系で使用する字句解析器など、 のですが、 flex に用意されている排他的開始条件 1 を用 手作業で作成するのは面倒なプログラムを、上交的簡単 いると、この問題を簡単に解決することができます。 に実現することができます。 flex では、状態の宣言で % s ではなく %x で宣言する 今回は、もうすこし複雑な lex の使い方について、例 ことにより、排他的な開始条件を宣言できます ()s を 題をましえて紹介します。 使った開始条件は非排他的な開始条件と呼はれます ) 。 %s で宣言した非排他的な開始条件では、開始条件がと くに指定されていない規則も有効になります。しかし、 %x で宣言した排他的な開始条件では、開始条件か指定 lex や flex では、開始条件と呼はれるものか準備さ されていない規則は有効にはなりません。このため、 %x れています。開始条件は、ソースファイルに書かれた規 則のうち、使える規則を制限します。このため、ある特 1 排 f 頓勺という言葉は、ソフトウェア里でときどき用いられ、「同時に 1 つしか存在しない」という未を表します。この場合は、ちょっと意 定の条件が成立したときだけ有効にしたい規則がある場 味カ嗄わっていて、「指定されていないものとは同時には有効にならな 合に、この機能を用いることができます。たとえは、文 い」という意味になります。 開始条件 114 UNIX MAGAZINE 1996.12
3 フログラマー入門 荒井美千子 JavaScript(2) JavaScript で書く HTML Java とちょっと似ている " こと 前回の記事では、 を知ってもらうために、日時を表す Date クラスを使 って、 WWW ページにアクセスした時刻を表示する JavaScript の例を紹介しました。 もう一度 Java のコード ( リスト 1 ) と JavaScript の コード ( リスト 2 ) を見くらべてください。細かな違いは ありますが、 Date クラスのオプジェクトの作り方から、 日時を表す文字列を取得するためのメソッドまでそっくり です。 則回は、、 JavaScript と Java はまるで違う " という意 graphic. drawString( 文字列 ) ; Java で Web ページに文字列を表小するには、 去絲材 j ・に注目してください。 と疑問に思われる方もいるでしよう。それぞれのコードの 「いったい、どこいらへんがそんなに違うんやろ」 味のことを書きました。 一方、 JavaScript で Web ページに文字列を表小する の名前を付けるかはプログラムの書き方しだいです。 トで、 graphic" と書くか、、 g " と書くか、それ以外の別 ソッドに引数として渡す Graphics クラスのオプジェク と書きます。、、 graphic" は、プラウザがアプレットのメ には、 104 名前で、プログラムか勝手に変史することはできません。 と書きます。この、、 document" は JavaScript カヾ夬めた document . vrite ( 文字列 ) ; リスト 1 時刻を新する Java のコード Date d = new Date() ; String datestr = d. t0String() ; String timestr = datestr. substring()l , 19 ) ; graphic . drawString(timestr,50, 100 ) ; リスト 2 時刻を表示する JavaScript のコード d = new Date(); datestr = d. t0String() ; timestr = datestr. substring()l , 19 ) ; document . write(timestr) ; なんだかこのあたりが、 Java と JavaScript の違いの ようです。 Java と JavaScript の世界観 Java の世界は、、、初めにアプレットありき " です。 Java のプログラムから見れば、プラウサなどの Java システムがアプレットを生成したときが世界の始まりで、 アプレットか消滅したときが川 : 界の終焉です。 また、 ・アプレットを含む HTML の文書 ・アプレットを表示しているウインドウ など、アプレットの外側の世界へは、アプレットのメソッ ドを介してアクセスします。 これに対し、 JavaScript の世界は、、初めにプラウザあ りき " です。 JavaScript の世界では、プラウサの部品やドキュメ ントなどが、すべて創世期から存在するオプジェクトと して用意されています。 JavaScript プログラムからは、 JavaScript システムによってあらかしめ決められた名前 UNIX MAGAZINE 1996 ユ 2
UN Ⅸへの招待 表 1 削除に関するコマンド キー / コマンド 1 文字単位の削除 カーソノ立置の左側 1 文字を削除 DEL カーソノ立置の左側れ文字を削除 C-u れ DEL カーソル位置の 1 文字を削除 C-d カーソノ立置から右へれ文字を削除 C-u れ C-d 行単位の削除 カーソノ立置の文字から行末 ( 改行の直前 ) までを削除 C-k カーソル位置以、降か改行文字あるいは予と空白の場合はそれらを削除 カーソノ立置から行頭までを削除 C-u 0 C-k カーソノ立置かられ個目の改行文字までを削除 C-u れ C-k カーソノ耳立置からテキストの知頁に向かってれ十 1 個目の改行文字までを削除 C-u - れ C-k リージョン ( マークからカーソル位置までのあいた ) を削除 C-w 単語単位の削除 カーソノ立置の 1 つ前から単語の知頁までを削除 ESC DEL カーソノ立置から単言韶 ) 末尾までを削除 ESC d 表 2 に関するコマンド コマンド カーソノ立置からバッフアの末尾までの範用で文字列を置換 ESC x replace-string カーソノ立置からバッフアの末尾までの硼で、正規表現を用いて文字列を置換 ESC x replace-regexp カーソノ耳立置からバッフアの末尾までの範用で、石忍しながら文字列を置換 ESC x query-replace ( または ESC % ) 図 1 リージョンの削除 (c) C-w でリージョンを削除 (b) カーソルを移動 (a) マーク寸ける 時計 日寺計 時計の・ = 、 打ち始めました。 1 加寺を 打ち始めました。 打ち始めました。 キルリング・・杲管 x 〇 x 〇〇〇〇〇〇〇〇〇 け rs Fi1e Edit H±Ip 旧釭 3 Fi_1± Ed it ・リ f に Fi-le Edit H*IP リーション マーク Mark set 1. 燧冬行の行頭にカーソルを移動ける。 います。以降では、実列を見ながら説明していきます。 2. C-k で行末までを削除するにのとき、削除内容がキ テキストの移動 ルリングに保管される ) 。 まず、テキストの削除とキルリングからコピーする機 3. カーソルを 4 行目の知頁に移動庁る。 能を使って、テキストを別の場所に移動してみましよう。 4. C-y でキルリングの内容をコピーする。 図 2 では、 (a) のテキストの最終行の、 本題からすこし外れますが、図 2-d の 4 行目の行末を うしろから、王子様が追いかけてきます。 見てください。行末に \ が 2 つ表示されています。以前も 触れましたが、これは、画面では 2 行に分割されている を 4 行目の先頭に移動しています。操作の手順は、次の が、実際には次の行に表示されているテキストもこの行の とおりです。 146 UNIX MAGAZINE 1996.12
・ ComNet Washington Convention Center, Washington, D. C. ◇ IDG ワールド・エキスボ・ジャノヾン (Tel 03-5276 ー 3751 ) ・ PAGE ' 97 San Francisco Mariott Hotel, San Francisco Conference ・ 1997 IEEE lnternational Solid-State Circuits ◇日本印届財支引劦会 (TeI 03 ー 3384 ー 3112 ) ・東京豊島区東池袋サンシャインシティ ◇半導イ杓発センター (Tel 0423-23 ー 1111 ) 12 ~ 14 ■ Network & Computing ' 97 ・千葉美浜区中瀬幕張メッセ ◇日経 BP 社エキスポ事務局 (Tel 03 ー 5210 ー 8287 ) 18 ~ 20 ー lnternet/lntranet Exposition Boston Hynes Convention Center, Boston ◇ BIenheim Group ( TeI 十 1 ー 800-232-3976 ) 19 ~ 22 ・ MACM70rld Expo Tokyo ' 97 ・千葉美浜区中瀬幕張メッセ 1997 ◇ MACWorld Expo Tokyo 統轄事務局 (Tel 03 ー 5276 ー 3751 ) 25 ~ 3 / 1 ・ Comdex China ' 97 China lnternational Exhibition Center, Beijing ◇ソフトノヾンク・エキスボ・ジャノヾン (Tel 03-5642 ー 8433 ) 3 March 5 ~ 7 ー Network Users' 1997 ・千葉美浜区中瀬幕張メッセ ◇日本経済辛用坦社 (Tel 03-5255-2847 ) 10 ~ 14 ・ UniForum ' 97 MOSCOne Convention Center, San Francisco ◇ UniForum Association ( Tel 十 1-800-255-5620 ) 11 ~ 14 ・ Spring lnternet 、 vorld ' 97 ・ Los A ngeles ◇ MeckIermedia ( TeI 十 1-171 ー 976-0405 ) UNIX MAGAZINE 1996 ユ 2 12 ~ 14 ■情報タ里学会第 54 回全国大会 ・千葉習志野市津田沼千葉工業大 ◇情報処理学会石支 (Tel 03-5484 蒭 535 ) 12 ~ 14 ■ Comdex lnternet San Francisco ◇ Softbank Comdex (Tel 十 1 ー 617-433-1818 ) 13 ~ 19 ・ CeBIT ・ Germany Messegelande, Hannover ◇ドイツ産業見本市日本代表部 (Tel 03-3363-6631 ) 19 ~ 21 ■ lnternet 、 vorld Asia ' 97 ・ Kuala Lumpur, MaIaysia ◇ MeckIermedia ( TeI 十 1-203 ー 226-6967 ) 24 ~ 27 ■ 1997 年電子情面言学会総合大会 ・邸反吹田市山手町関西大学千里山キャンパス ◇電イ情報通信学会 (TeI 03-3433-6691 ) 4 ApriI 7 ~ 10 ■ NAB ' 97 and NAB Multimedia World ・ Las Vegas Convention Center, Las Vegas ◇ NAB 日本代表事務局信井文夫 (TeI 03 ー 3942-2381 ) ◇ソフトノヾンク・エキスボ・ジャノ、ン (Tel 03 ー 5642-8433 ) ・千葉美浜区中瀬幕張メッセ ・ Comdex Japan ' 97 8 ~ 11 ◇ソフトノヾンク・エキスボ・ジャノヾン (Tel 03-5642-8433 ) Singapore ■ Net 、 vorld 十 lnterop Singapore 7 ~ 11 19 ◇ SEMI ジャノヾン (Tel 03-3222-5755 ) ・横浜西区みなとみらいパシフィコ横浜 ■ EDF ' 97 ( 電子ディスプレイ・フォーラム ' 97 ) 16 ~ 18 ◇ドイツ産業見本市日本代表部 (Tel 03-3363 ー 6631 ) Germany Messegel ande, H annover ・ Messe 14 ~ 19