すに記述することもできます ) 。規則のなかで 1 つでも REJECT アクションを使うと、スキャナの処理速度が 落ちてしまいます。また、 REJECT アクションを実行 すると即座に再度規則の検査を始めるため、 REJECT アクションの後ろに文を書いても、それらは実行されま せん。 アクション部分に何も書かなかった場合も、特別な アクションとして扱われます。この場合、マッチした文 字列はたんに捨てられます。プログラミング言語の解釈 をする際に、空白文字などを無見したい場合には有効で しよう。次の例では、入力のなかから空白とタブをすべ て取り除いたものを出力します。 [ \t] . l\n ECHO ; アクション部分に、、にだけを書くと、これも特別なア クションとして解釈されます。このアクションは、すぐ 次に続く規則のアクションと同しアクションとなること と、 ECHO ; を意味します。つまり、 この例の場合には、 は同し意味となります。 ECHO ; ECHO ; a に ECHO ; アクションのなかに { ECHO ; REJECT ; } REJECT が入っている場合には意味か変わります。 でもまったく同様です。しかし、 UNIX MAGAZINE 1996.11 行後、最初に一致した規則のアクションで ECHO を実 えるように指示するものです。つまり、 yymore() の実 入れ替えるのではなく、現在の yytext の内容に付け加 にパターンに一致したときに、現在の yytext の内容を yymore() というアクションもあります。これは、次 には一致しなくなります。 字、 a " に一致したときに REJECT を実行しても、、 " では 1 つの規則として扱われます。したがって、文 { ECHO ; REJECT ; } では、それぞれが別の規則として扱われますが、 LJN Ⅸ流プログラミング 73 行すると、直前に一致した文字列も出力されることにな ります。 yyless() は引数をとるアクションです。引数として は数字を 1 つ指定します。このアクションを実行する と、パターンに一致した文字列のうち、先頭から指定し た数字ぶんの文字だけを採用して、それ以降の文字は入 力に返す ( まだ読み込んでいないとみなす ) 処理をしま す。このアクションを実行すると、 yytext や yyleng の 値も変更されるので注意してください。また、 yyless(0) を実行すると、パターンに一致した文字列すべてを入力 に返す処理をおこないます。したがって、次に再度パタ ーンの検査をおこなったときに同じ規則に一致してしま います。ここで無限ループができてしまうため、処理が 止まらなくなってしまうので注意してください。 yyless() では、入力された文字を戻すことができまし たが、 unput() を使えば、任意の文字を入力に戻すこと ができます。 unput には引数が 1 つあり、これには戻 したい文字を指定します。複数の文字 ( 文字列 ) を戻す 場合、文字列の先頭から順に戻したのではうまくいきま せん。最後に戻したものが次に読み込まれるためで、文 字列を戻したい場合には文字列の後ろから先頭のほうへ 逆に戻す必要があります。 次は input() です。このアクションを実行すると、字 句角斤器が次に読み込もうと思っている文字を得ること ができます。 input() を使って読み込んでしまうと、字 句解析器はその文字を読み込むことができません。 in- put() で読み込まれた文字の次の文字から読込みを続け て解析をおこないます。この input() と unput() と を組み合わせることにより、次に字句角斤器か読み込む 文字を盜み見して、処理をおこなう場合などに利用でき ます。 input ( ) ; unput (c) ; c に依存した処理 ... 最後に、 lex だけに存在するアクションを紹介してお きましよう。 output(c) とすると、引数として指定し た文字を出力することができます。 ECHO アクション では、パターンに一致した文字列だけを出力できまし たが、このアクションを使えば、任意の文字を出力す ることが可能です。ただし、とくに処理をしていない 場合には、出力は標準出力に対しておこなわれるため、 putchar() を使っても同様なことができます。 flex ユー 87
6 特集モーレッ UN Ⅸ C-k : カーソル位置より前の文節を確定し、以後を、、か な " に戻す。 C-g : 漢字変換モードから抜けて、ローマ字かなモードに 戻る。 これらのコマンドは、変換キーを押して漢字変換モード に入ってしまってから、かなの入力間違いに気がついたと ー大きなのっ歩の夫売る時計一 たとえは、次刎列を見てください。 きに活躍してくれます。 UNIX MAGAZINE 1996.11 ワープロなどでも、「ん」の入力去は機種やソフトウェ 「ん」の入力 はうがいい事柄を挙げておきます。 そのほか、たまごでの日本語入力について知っておいた そ也 C-k と C-g は、必要に応して使い分けてください。 あら、なくなっちゃった ーおおきなのっぽのふうるどけい田← C ー g をもう 1 回入力 ← C - g を入力 ー大きなのっぽの国売る時計一 くなり、そこへ入力していた、、かな " も消えます。 れます。さらにもう 1 回 C - g を入力するとフェンスがな 本を漢字変換モードからローマ字かなモードに戻してく 一方、 C-g はカーソルの位置に関係なく、フェンス内 いいわけです。 ので、よぶんな「う」を消去してもう一度変換しなおせば す。こうすれは、フェンス内の文字を自由に編集できる い」は漢字変換モードからローマ字かなモードに戻りま のように「大きなのつほ。の」までか不寉定し、「ふうるどけ 大きなのつほのい、うるどけい田 ー大きなのつほの売る時計一← C-k を入力 せます。そこで C ー k を入力すると、 ほの」までを正しく変換してから「夫」にカーソルを合わ このような場合、ますはさきほどと同様に「大きなのっ きても、文字の修正はできません。 由に修正できますが、漢字変換モードでは文節の変更はで 変換前のフェンスモードでのフェンス内であれば文字を自 「ふる」と入力するところを「ふうる」と間違った例です。 アごとに違い、いつもちょっと迷うところです。たまご では、「ん」は n を 1 文字だけ入力します。、、 nn" と 続けると、「んん」となってしまいます 2 。「いんよう ( 引 用 ) 」や「かんい ( 簡易 ) 」などのように「ん」に続い て、、やゆよ " や母音か読く場合は、、、 n " に続いて、、 ' " を 入力すれは、、、Ⅱ " 1 文字で「ん」カ蔀寉定します。 「でいすく」のように、拗促音を単独で入力する場合に は、該当する衂足音の前に、、 x " を入力します。つまり、 「でいすく」の場合は、、 dexisuku" とします。 z に続いて・・ ローマ字かなモードで、小文字 z に続いて文字を適当に 打ってみてください。あるいは、大文字 Z でも試して みてください。たまごでは、各種のおもしろい文字を入 力することができます。 辞書登録て書を鍛える さきほど、 UNIX のかな漢字変換プログラムはあまり 賢くないと書きました。これにはさまざまな理由がありま すが、辞書の語彙数が少ないことも原因の 1 つです。逆に いえは、辞書にどんどん登録していけは、より賢いフログ ラムへ成長していく可能性があるということです。 ただし設ファイルを利用すれは、、で「ん」に変換することも [ あ ] 辞書登録「喜章読み : ■ コマンドを実行すると、エコー領域に 4. 読みがなを指定する です。 単語求のためのコマンドは、、 x toroku-region 3. 単語泉コマンドを打つ 録する単言韶 ) 範用を指定します。 てカーソルを単言韶 ) 直後の位置まて彩動して、辞書に登 : 頁の文字で C-SPC を入力してマークを設定し、続い 言韶 ) 指定も同し要領でおこないます。登録したい単語の 前回説明した、、マーク " を思い出してください。登録単 2. 登録したい単語を指定する 変換させるなどして、その単語を表示させてください。 まず、登録する単語を表示します。漢字を 1 文字すっ 1. 登録したい漢字を表示する 辞書イ求の手順を説明します。 2 できます。 31
ザーの方も安心してください。出力先を変更する方法に ついては、次回に紹介します。 簡単な例題 88 加えられているのか分からないかもしれませんが、この まり、これは無視されます。なせわざわざこんな規則が は、アクションとしてコメントしか付いていません。つ . l\n 最後の規則、 しています。つまり、数字が入力されたときの処理です。 進数として解釈した値を引数として push 関数を呼び出 は、数字の 1 個以 - ヒの並びに一致し、その文字列を 10 [ 0 ー 9 ] + push(strtol(yytext, NULL, 0 ) ) ; う。最初の規則、 です。ちょっと複雑な規則について説明しておきましょ 対してあらかじめ決められた関数を呼び出しているだけ は 2 つだけです。はとんどのものは、 1 文字の入力に しか使っていません。それも、正規表現を使っているの lex の核心である規則部分では、たった 9 個の規則 言もおこないます。 タックなどの宣言をしています。関数のプロトタイプ宣 ルをインクルードしたり、数値をイ尉寺しておくためのス しよう ( リスト 1 ) 。最初の定義部分では、ヘッダファイ っそく、この言 t 算機を実現するプログラムを書いてみま とがないので、プログラムにするのが簡単なのです。さ この言去だと、括弧を使って優立が変えられるこ れから 4 を引く」という感しですね。 と書くのです。「 1 に 2 と 3 を掛けたものを足して、そ 1 2 3 x 十 4 ー は、 1 十 2 x 3 ー 4 の書き方とはかなり異なる書き方をします。たとえば、 逆ポーランド記法は、皆さんか慣れ親しんでいる数式 ンド記法 (RPN) を採用する電卓にしてみましよう。 複雑なことはできません。電卓の機能を絞り、逆ポーラ 成してみましよう。ただし、 lex を用いて作成するため、 こで、すこし実際的な伊題として、電卓プログラムを作 うすればよいのかがよく分からないかもしれません。そ ところで、 lex と flex を実際に利用するとなると、ど 規則を除いてコンパイル、実行してみるとすぐに理解で きるはすです。 しつは、 lex では、いすれの規則にも一致しなかった 文字は、指定しないとそのまま出力してしまいます。っ まり、関係ない文字を入力したときには、その文字が出 力されてしまいますし、数字や記号を区切るために入力 した空白文字も出力されてしまいます。そこで、このよ うなアクションがない規則を加えて、プログラムからの よけいな出力がないように任意の 1 文字を捨てているの です。この後ろのコード部分には、演算子を実現するた めのコードが並んでいます。 このプログラムをコンパイルして実行すると、次のよ うになるはすです。 % . /calc 1 2 3 * + 4 3 計算結果を見るには、最後に してください。 ☆ " が必要です。注意 今回は、正規表現を使って与えた仕様から字句角斤器 を生成する lex を紹介しました。 lex を使えは、プログ ラミング言語の字句解析器など、手作業で作成するのは 面倒だと思うようなプログラムも、上罅交的簡単に実現で きます。とはいえ、今回紹介できたのは lex の基本部分 だけです。より、おいしく " 使うには、、わざ " を使う必 要があります。次回は、もうすこし複雑な lex の使い方 について、伊地を交えながら紹介します。 UNIX MAGAZINE 1996.11 ( いまいずみ・たかし東京工業大学 )
連載 / IJN Ⅸ知恵袋ー② ( ファイル 1 ) 図 2 空行を無視する例 NAME diff files SYNOPSIS find differences between tWO ( ファイル 2 ) SYNOPSIS files diff NAME find differences between t 0 diff [options] from—file to—file ・ -r または --recursive 2 つのディレクトリを上交します。ディレクトリに含ま れるすべてのファイルをサプディレクトリも含めて検索 し、両ディレクトリに含まれる同し名前のファイルどう しを上交して 1 つのパッチファイルを生成します。 ・ -N または --new-file 2 つのディレクトリを上交するとき、新ディレクトリに は存在するが旧ディレクトリには存在しないファイル がある場合があります。このような状況は、ソフトウェ アのバージョンアップなどて澤斤しいソースファイルを 追加したときなどに起こります。通常、 di 仕コマンドは 新旧ディレクトリの両方に存在するファイルのみを比 較します。したがって、新しく追加されたファイルは 無視されます。このスイッチを指定すると、 patch コ マンドを実行するときに、新しく追加されたファイルを 生成するようになります。なお、副作用として、 patch コマンドの実行後、新しいファイル名の末尾に . 。ⅱ g カ咐いた 1 大きさ 0 バイトのバックアップ・ファイル が生成されます。このバックアップ・ファイルかイ腰 なら、 patch コマンドを実行するときに一 E もしくは -remove-empty-files スイッチを指定します。 ・ -B または -—ignore-blank-lines 空行の挿入や削除を無見します。このスイッチを指定す ると、たとえは図 2 に示した 2 つのファイルは同じも のとみなさパッチを生成しません。 ・ -b または --ignore-space-change 1 もちろん、 patch コマンドの一 B や --suffix スイッチでバックアッ プ・ファイル名を変史していれは、変更した名前のバックアップ・ファ 114 イルかできます。 diff [options] from—file to—file 図 3 空白文字列さが違う文」 Frequent1y Asked Questions for FreeBSD 2 . X Frequent1y Asked Questions for FreeBSD 2. X 図 4 空白文字列を消去した文列 FrequentIy Asked Questions for FreeBSD 2 . X 図 5 2 つのファイル合 FrequentIyAskedQuestionsforFreeBSD2. X ・ di 仕コマンドの出力 void func (int , ・新ファイル int func (int , ・旧ファイル #ifndef FUNC_RETURN VOID int func(int, #else / * FUNC—RETURN_VOID * / void func (int , #endif / * FUNC_RETURN_VOID * / 空白文字列の長さを無視します。たとえば、 した 2 つの文は同じものとみなされます。 ・ -w または -—ignore—all-space 図 3 に小 空白文字列そのものを無視します。たとえは、図 4 に 示した 2 つの文は同しものとみなされます。 ・ -i または --ignore-case アルファベットの大文字と小文字を同じものとみなし ます。 ・—D name または——ifdef=name このスイッチを指定すると、 d 沮コマンドはパッチファ イルを出力しません。このスイッチは、新旧 2 つのファ イルを統合する場合に使用します。たとえは、あるプロ UNIX MAGAZINE 1996.11
す。 lex 独自の拡張もあるので、すべてのパターンを紹 介しておきます。 正規表現、、て " と、、 s " の連結を表す 正規表現と、、 s " の選択を表す ・ rs LJN Ⅸ流プログラミング 73 正規表現、、 r " に対するグルーピングを表す 文字 x を表す ( 特殊な意味をもつ文字を除く ) 改行を除く任意の 1 文字を表す ・ abc] abc のうちの任意の 1 文字を表す a から z の任意の 1 文字を表す a から z 以外の任意の 1 文字を表す ( 改行文字も含ま れるので注意 ) 正規表現、、 r " の 2 回の縄区しを表す 正規表現、、 r " の 2 回以 E の縄区しを表す 正規表現、、て " の 2 回以上 5 回以下の縄区しを表す 正規表現、、て " の 0 回か 1 回の出現を表す 正規表現、、て " の 1 回以ーヒの縄区しを表す 正規表現、て " の 0 回以 E の縄区しを表す ・ r { 2 , 5 } ・ r 十 { 名前 } ・ r { 2 } UNIX MAGAZINE 1996.11 直タブ文字を意する。 ド、 n は改行文字、 r はリターン文字、 t は ( 水平 ) タブ文字、 v は垂 1 a は警告信号 ( 通常はベル ) 、 b はバックスペース、 f はフォームフィー 文字コードが 16 進数で 56 である文字を表す \ X56 文字コードが 8 進数で 123 である文字を表す \ 123 ものを表す 合には次項、次々項。それ以外の場合には文字 x その それぞれの未 1 に、 x が 7 までの数字か文字 x の場 x が a 、 b 、 f 、 n 、 r 、 t 、 v の場合には ANSI C での 特別な意味が消された文字列、、 * + " " を表す 定義部分で定義された名前を展開することを表す 後ろに正規表現、、 s " をともなった正規表現 r を表 す ( 、、 s " はパターンにはマッチしない ) 行末に置かれた正規表現、、 r " を表す 行頭に置かれた正規表現てを表す の文字に対しては 1 度だけ出力する場合などに、 ら、特定の文字に対して 2 度出力をおこない、それ以外 たパターンと一致することに決められています。ですか えられます。この場合、規則の並びのなかで前に書かれ 同じ長さの文字列が複数のパターンと一致することも考 のパターンと一致して abc として認識されます。また、 ンと一致して a と b と c に分けられるのではなく、最後 の 3 っか書かれていた場合、文字列 abc は最初のパター カ甘采用されます。したがって、パターンとして、 ンに一致する文字列としては、できるかぎり長い文字列 列が複数のパターンに一致することがあります。パター 規則部分では複数の規則を指定できますが、同じ文字 す括弧を積極的に用いるとよいでしよう。 します。優先順位カ坏安な場合には、グルーピングを示 では ab ' に続いて、、 c " が 3 回繰り返されたものを意味 lex では abc" が 3 回繰り返されたものを意味し、 flex なっています。たとえば、 abc{3}" と指定した場合、 これらの規則の優頂位は、 lex と flex とでは若干異 { ECHO ; ECHO ; } ECHO ; にも注意してください。 lex では、名前に対応づけられ lex と flex とでは、 { 名前 } " の扱いか若干異なる点 てしまいます。規則の順番には十分注意してください。 の、、 . " と一致するため、 2 番目の規則は使われなくなっ などと書いてしまうと、 a を含む任意の 1 文字が先頭 85
UN Ⅸへの招待 表 1 Mule の奐に使えるおもな正規表現 意味 改行・文字以タ P ) 1 文字 0 回以 E の区し 1 回↓リはマ区し 0 回か 1 回 一致する文字集合を作る 使用例 一致する文字列 abcd 、 abbd 、 axyd など bc 、 AAbc 、 AAAbc など A*bc XXZ 、 XXXZ 、 XXXXZ な、ど X 十 Z efg 、 eefg e?fg 小文字のアルファベットすべて [a-z] [bp] ig big 、 pig 行頭 行頭にある rabbit -rabbit 行末 行末にある turtle turtle$ キ未文字のエスケープ どちらかの正規表現お尺する aaa または bbb aaa\ ー bbb グルーフイヒ ac 、 ad 、 bc 、 bd れ番目のグループ ( れ = 1 ~ 9 ) acc 、 add 、 bcc 、 bdd 置換前文字列全体 置換前文字列 : pork 置換後文字列 : \&y porky ノヾッフアのう巨頁 ノヾッフアのう頁にある What \ ( What / ヾッフアの末尾 ノヾッフアの : 末尾にある that's all \ 'that 's a11 単言韶 ) 地頁 pen や penalty など、 pen"%{i まる単語 \ く pen 単言韶 ) 毛 accord や word など、、 ord" で終る単語 0 rd\ > 確認しながらの置換 3. ミニバッフアが次のようになるので、 with: の後ろに 置換後の文字列を入力し、 Return キーを押す。 こまでに紹介した 2 つの置換コマンドは、実行した か最後、有無を言わせす該当するすべての文字列を変更し Query replacing maru with : hishigata てしまいます。しかし、一致する文字列の一 - だけを置換 4. 置換対象の文字列の後ろに順次カーソルが置かれてい したい場合もあります。 くので、 y 、 n 、 Space 、 DEL などをタイプし、置換 そのようなときは、 query-replace カイ更利です。 るかどうかを返答する。 のコマンドはⅵの、 y や Space では置換、Ⅱや DEL では変更せすに次の 置換対象文字列へ進む。途中でこの作業を中止すると , $s/old/new/gc きは、 q または Return をタイフする。 に似た働きをします。 ' ( ピリオ 4 の応答では、 こで説明した以外に、 操作の手順を説明しましよう ' ( カンマ ) 、 C-r 、 C-w 、 C ー 1 、 ! 、勣ゞ使えます。 1. ESC % " とタイフする 4 。 これらのキーの意味を、簡単に説明しておきます ( ? を タイプすると表示されます ) 。 2. ミニノヾッフアに : 最初に -- - 数した文字列だけを置換して終了する。 Query replace : , : 置換後、 Space を押すまで置換した文字列の直後に留 と表示されるので、置換したい文字列を入力する。 た まる ( 置換結果を 1 っ 1 っ石忍したいときにイリ ) 。 とえば、、 maru" という文字列を置換する場合は、 C-r : 置換イ↑業をいったん中止する (ESC C-c を押すと maru R. eturn Query replace : 再開する ) 。 C-w : その点での置換対象文字列を削除し、置換竹喋 とする。 をいったん中止する (ESC C-c を押すと再開する ) 。 4 ESC x に続いて query-replace をタイプし、前節の replace- C-I : カーソルか画面の中央部に位置するように画面を再 string と同し手順で操作することもできます。メニューの Edit から、 描画し、置換イ 1 璞を続行する。 Query Replace" を j 尺して実行することも可能てす。 く > 150 UNIX MAGAZINE 1996.11
LJN Ⅸ流プログラミング 73 字を、次の記号はその文字を読み込んだときに移る状態 応づけたい正規表現を記述します。この部分は、行末ま を表しているのです。 でが正規表現だとみなされます。 定義部分中の行頭から始まっていない記述は、 lex. もう 1 つ重要なのが、 yylex 関数のなかに埋め込まれ yy. c にそのまま埋め込まれます。これは、 yylex 関数 たアクションを実行する部分です。これは、記述ファイ の外部に埋め込まれるので、外部変数の定義などがおこ ル (lex のソースファイルです ) に書いたアクション部 なえます。 flex の場合には、行頭部分の空白文字を取り 分がそのまま埋め込まれていることが分かるはすです。 除いた形式で lex. yy. c に出力されます。しかし、 lex の 憶えておいてほしいのは、 flex が C のソースファイ 場合には行頭の空白文字も残したまま lex. yy. c に出力さ ルを作成する点です。そのため、必要であれは外部変数 れるため、注意が必要です。というのは、次のようなこ を宣言しておいてそれをアクションで利用したり、自分 とがあるからです。 自身で作成する関数を記述ファイルのなかに書いておい インクルード・ファイルを指定したり、マクロを定義 て、作成される lex. yy. c ファイルに含めてしまい、簡単 するなど、 C プリプロセッサに対する命令を記述する にコンパイルできるようにすることも可能です。ちょっ 場合、先頭の # 記号は行頭になければなりませんでした としたプログラムを作成する場合には、この機能は便利 ( 最近のシステムではこの制約はないようです ) 。 lex で です。 は行頭の空白文字も残したまま lex. yy. c に出力されてし 己述ファイル まうので、プリプロセッサに対する命令を lex のソース プログラムに埋め込むことができません。このために 己述ファイルの形式から紹介していきましよう。記述 特殊な記法か準備されています。定義部分のなかでも、 ファイルは大きく 3 つの部分から構成されます。 定義部分 規則部分 コード部分が存在しない場合には、 2 つ目の % % 以降 は省略可能です。 定義部分 = 一 1 ロ と、 で囲まれた部分に関しては、そのまま lex. yy. c ファイル に出力します。つまり、 #include く stdio . h> などと書くことができるようになっています。 この記法 は、 lex と flex の両方で使えます。 こでは、規則部分で利用できる名前を定義します。 たとえば、 [a-zA-Z] [a-zA-Z0-9] * ID 規則部分 とすると、規則部分で {ID} と指定した場合には、 規則部分では、 で指定した正規表現、、 [a-zA-Z][a-zA-Z0-9]*" が指定さ アクション れたものとみなされます。規則部分で複雑な正規表現が 何度も出現する場合には、それを名前で定義しておくと という対で規則を記述します。 もちろん、複数の規則を 規則か読みやすくなります。 記述することができます。 注意してはしいのは、パターンは行頭から始めなけれ 名前として用いることができるのは、正規表現で表せ ば、、 [-a-zA-Z][--a-zA-Z0-9]*" となります。つまり、下 ばならないことと、アクションはパターンと同し行に 線かアルファベットて始まり、その後ろにマイナス記号、 書かなけれはならないことです。行頭から始まってい ない場合、定義部分と同様に、 lex. yy. c のなかにそのま 下線、アルファベット、数字のいすれかが 0 個以上続い た文字列です。これをます行頭に指定します。名前の後 ま書き出されてしまいます。これは、先頭の規則の前で ろに空白文字 ( スペースかタブ ) を置き、その後ろに対 のみ意味があります。規則を記述する前に空白文字で始 83 UNIX MAGAZINE 1996.11
図 1 カーソノイ立置とポイントの系 ・・・カーソル位置 赤い赤いんこ ポイント・・・・ : 1 文字削除 ます、 1 文字を削除するコマンドです。前回、、、ポイ ント " の説明のところで簡単に紹介しましたが、 Mule で は DEL と C-d の 2 つのキー 1 が使えます。 DEL で はカーソルの左側 ( またはポイントの直前 ) の、 c-d では カーソノ立置 ( またはポイントの直御の 1 文字を削除し ます。 こで、ポイントについて簡単に復習しておきましょ う。ホイントとは、カーソルとその直前の文字のあいだ にある ( 目に見えない ) 点です ( 図 1 ) 。同し削除キーで も、カーソルを基售にするのと、ポイントを基準にするの とでは説明ガ去がすこし変わります。 MuIe 本来の考え方 からいえばポイントをもとにしたほうがいいのかもしれ ませんが、 こでは分かりやすさを優先してカーソルを 基準に説明します。 それでは、 1 文字削除キーの例をみていきましよう。い つものように、ⅵと上交してみます ( ェデイタは Mule カめてという人は、次の段落へ進んでください ) 。 vi で は、入力した 1 文字を削除するのに、挿入モードとコマ ンドモードとでは異なるキーを使います。前者は UNIX の stty コマンドで設定した erase 文字 ( 通常は DEL ま たは Backspace(C-h)) 、後者は x や X などです。挿 入モードでは、直前に入力した 1 文字を削除する場合は erase 文字を使い、それよりも前に入力した文字を消すた めにはいったんコマンドモードに移行してからカーソル を移動し、 x や X などを使います。これに対し、 MuIe はモードレスなので、このような違いはありません。直前 に入力した 1 文字を消すのも、それより前に入力した 1 文字を消すのも、同しように DEL キーを使います。 まず、 DEL キーの働きをみてみます。たとえば、 1 Mule では、各種のコマンドをキーに割り当てることカそきます。たと えば、デフォルトの言殳定では、 DEL に delete-backward-char 、 C- d に delete-char というコマンドカり当てられています。本来なら、 これらのコマンド名もイ己したはうカ、いのかもしれません。しかし初 ノ ) うちはかえって混乱しそうなので、当分のあいだキーの割当てだけを 紹介することにします。 UNIX MAGAZINE 1996.11 UN Ⅸへの招待 UNIX MAGAX' と、、、 Z " と入力するつもりで、、 X " をタイプしてしまった としましよう。このとき、カーソルは X の右側にあるの で、 DEL キーを押せば X か削除されます。その後は、引 続きテキストを入力していくだけです。 入力したテキストのうち、どこかの 1 文字を削除する 場合も同様です。前号で説明したカーソル移動キーを使 って削除対象の文字の 1 つ右側の文字上に移動し、 DEL キーを使います。たとえば、 1 行上の同しカラムの文字を 消したいときは、 C-p DEL とタイプします。 C-p は、 ( カーソノ耳立置よりも上に行が あれは ) 1 行上の同一カラム上にカーソルを移動するキー です。 C-d は、カーソル位置の文字を削除するキーです。正 確にいえは・、、ポイントの変の 1 文字 " を削除するキーで すが、ポイントの後ろにカーソルがあるので、カーソル位 置の文字か削除されるのです。 こで、 1 文字削除のキーを使って 2 行を 1 行にまとめ てみましよう 2 。図 2 をご覧ください。図 2-a では、カー ソルは 1 行目の行末にあります。前回も説明しましたが、 ( ⅵと違って ) Mule では改行も 1 文字として扱います。 つまり、 ( 目には見えませんか ) カーソルは改彳・丁文字の上 に置かれているわけです。ここで、カーソル上の 1 文字 を削除する C-d を使うと図 2 ー b のようになります。改行 文字か削除さ 1 行目と 2 行目が連結されています。 DEL を使っても同様の操作ができます。ただし、カー ソルを次行の : 頁に置いて実行します (DEL はカーソル の直前の 1 文字を消すからです ) 。すると、直前のテ文 字か削除さカーソルのあった行か前行の行末につな がって連結されます。 UNIX MAGAZ I NE ↓ DEL UNIXMAGAZINE 2 ⅵでは、 1 行目にカーソルを置き、 J コマンドを使います。 145
6 モーレッ IJN Ⅸ おさるロ ←リターンを入力 り、 C-\ を押すたびにローマ字かなモードと通常のモード かなとアルファベットの混合文書が作成できます。つま のようになります。これを繰り返しおこなうことにより、 おさる osaruu そこでもう一度 % saru " と入力すると、 入力します。すると、モードラインか図 2 ( 1 ) に戻ります。 ターンキーを押すなどしてフェンスモードを抜け、 C-\ を ローマ字かなモード状態から通常の状態に戻るには、リ モードを抜けて通常の状態に戻ります。 入力を終えたところでリターンキーを押すと、フェンス 移行します。 字を入力した瞬にフェンスか現れて、フェンスモードに をフェンスといいます。つまり、ローマ字かなモードで文 字が表示されます。この状態をフェンスモードといい、 ーで囲まれた部分に入力文 モードで文字を入力すると、 ちゃんとひらがなになったでしようか。ローマ字かな られたら照れるがな。 monkey : たいしたことあれへんけどな。そんなに褒め 入力できました。なんだか感敷だな。 あつぶる : UNIX で初めてアルファベット以外の文字を フェンス内での文字編集 とか交互に入れ替わるわけです。 あつぶる : こういうことは、はっきりしておかないとあ monkey : そんなにきつばりと言わんでもええやない ないです ( きつばり ) 。 あつぶる : いえ、べつに monkey さんを褒めたわけじゃ マンドが使えます。 フェンス内での文字の編集では、基本的に通常ク扁集コ monkey : ほな、いまから説明しよか。 してしまったらどうするんですか ? とあとまで尾を引きますから。ところで、間違って入力 C-e C- k C- d DEL カーソルをフェンス内の最後の文字へ カーソルのある文字から最後までを削除 カーソルのある文字を消去 カーソルの直前の文字を消去 これらを駆使すると、フェンス内の文字を自由に編集で きます。 ただし、フェンス内の最後の文字を DEL で消去する場 合は、入力アルファベットの文字単位で消去されます。つ まり、さきほど刎列の場合、最後に入力した「る」を DEL で消去していくと次のようになります。 ーおさる国 ←ここで DEL を入力 さ r 田←もう一度 DEL を入力 ーおさ田 細かなことかもしれませんが、憶えておいてください。 もし「おさら」と間違って打ってしまった場合、最後の a だけ消去して u を入力すると、「おさる」になりますれ ほんのすこしだけですが、入力文字数を稼ぐことができま す。 monkey : 関西人は、こんなところでも損せえへんよう に気をつけるもんや ! あっぷる : はいはい。 0 やろうかな漢字変換 ! ! C- f C- b C-a 28 カーソルを 1 文字ぶん進める カーソルを 1 文字ぶん戻す カーソルをフェンス内の地頁の文字へ monkey : いよいよ、かな漢字変換の始まりゃな。 あつぶる : ワープロと同じですよね。ます、ひらがなを ローマ字で入力しておいて、それを変換キーで漢字に変 換してもらうんですね。 monkey : そや。 あつぶる : でも、変換キーとかないですよね。 monkey : ワープロ専 . 用機やらパソコンに付いてる日本 語キーポードやったらあるねんけどな。いま使うてるの は、、英語キーポード " ゆうて、見てのとおり、キートッ プに、、かな " か書いてあれへんやつや。このタイプには 変換キーはあらへん。かといって、変換キーで変換でき るともかぎらへんねん。 あっぷる : なんだかややこしいですね。つまり、 あるキーのうち、どれかか変換キーになるということで UNIX MAGAZINE 1996.11 すか ?
DZ—X 流プログラミング らあらかしめ決められた文字列をみつけるためのもので す。たとえは、 C 言語で書かれたプログラムを認識する 場合には、そのなかの if や while などの予約語を拾い 出したり、 C 言語での文字列表現を認識することも必要 になるでしよう。字句解析器は、これらの処理をおこな います。 lex を利用すると、ある決められた文字列の認』寺に、 どのような処理をするのかを記述できます。具体的に は、正規表現として指定したある文字列を認識したとき に実行する C 言語のコードを指定できます。たとえは、 文字列を認識したときに決まった値 ( トークン値 ) を返 します。この場合、関数を繰り返し呼び出すことにより、 対象となっている予約語を示すトークン値が順番に返さ れます。 こで、トークン値を返すのではなく、認識した文字 列に対して処理を実行するようなプログラムを記述すれ ば、単独で動作するコマンドを生成できます。たとえは、 行末までの 1 行を認識し、それを標準出力に出力するプ ログラムを書けば、標準入力を標準出力にコピーするプ ログラムになります。ますは、この簡単なプログラムが 実行できるようになるまでを紹介します。 実際に、皆さんにも試してもらいましよう。そのため には、プログラムが必要になります。次のような内容の ファイルを、 a. 1 という名前で作成してください (lex の ソースファイルは拡張子に I を付けることになってい ます ) 。 73 今泉貴史 前回は、いくつかの文字列を一度に指定する方法とし て、 UNIX でよく用いられる正規表現について解説しま した。さらに、正規表現と関係の深い正規式、正規式の 最初の 2 つの、、 % " はおましないだと思ってください。 紹介のために BNF による文法の記述方法などもとりあ 2 行目では、正規表現と対応するアクションを指定して げました。 います。この正規表現は、「任意の ( 改行を除く ) 1 文字 今回は、 lex というシステムを紹介します。 lex は、文 が 0 回以上繰り返され、その後ろに改行文字か読くも 字列の並びから言語の予約語などを取り出す字句解析器 の」を表しています。入力が正規表現にマッチしたとき を作成するシステムです。とはいえ、前回紹介した正規 に実行されるのが、 ECHO と呼はれるアクションです。 表現を処理するための汎用のシステムですから、使い途 これは、対応する文字列を画面に表示します。 はさまざまです。ますは、 lex だけで作成するプログラ ファイルの準備ができたら、これを引数にして lex を ムからみていくことにしましよう。 起動します。 lex の働き % lex a. 1 その結果、 1 行すっ標準出力に送り出す処理を実現す る lex. yy. c というファイルが作成されます。 *"\n" ECHO; lex は、与えられた記述にもとづき、字句解析器を生 成するコマンドです。字句解析器は、テキストのなかか UNIX MAGAZINE 1996.11 81