thomas zeugmann - 北海道大学minato/toc2016/toc_lec05j.pdf · perl およびtcl...

60
”UNIX POSIX Thomas Zeugmann http://www-alg.ist.hokudai.ac.jp/thomas/ToC/ 5 UNIX ( ) c Thomas Zeugmann

Upload: others

Post on 10-Jun-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

計算理論

Thomas Zeugmann

北海道大学大学院情報科学研究科アルゴ リズム研究室

http://www-alg.ist.hokudai.ac.jp/∼thomas/ToC/

第 5回:UNIX における正規表現(日本語訳:大久保好章, 湊真一)

計算理論 c©Thomas Zeugmann

Page 2: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

はじめ に I

関連理論をある拡張形へ発展させ た後,その 応用について述べてみたい.特にこ こ では,UNIXで用いられる正規表現について見ていこ う.

計算理論 c©Thomas Zeugmann

Page 3: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

はじめ に I

関連理論をある拡張形へ発展させ た後,その 応用について述べてみたい.特にこ こ では,UNIXで用いられる正規表現について見ていこ う.

まず最初に,拡張正規表現の UNIX表記を導入する.

計算理論 c©Thomas Zeugmann

Page 4: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

はじめ に I

関連理論をある拡張形へ発展させ た後,その 応用について述べてみたい.特にこ こ では,UNIXで用いられる正規表現について見ていこ う.

まず最初に,拡張正規表現の UNIX表記を導入する.

次に,正規表現を用いるいくつかの UNIXユーティリティを見ていく.

計算理論 c©Thomas Zeugmann

Page 5: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

最初のややこしい事柄 I

正規表現の “基本”UNIX構文法は,POSIX によると,もはや時代遅れとされているが,過去の システムとの 互換性の ために今なお広く用いられている.

計算理論 c©Thomas Zeugmann

Page 6: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

最初のややこしい事柄 I

正規表現の “基本”UNIX構文法は,POSIX によると,もはや時代遅れとされているが,過去の システムとの 互換性の ために今なお広く用いられている.

POSIXは “Portable Operating System Interface” の 略であり,各種 UNIXオペレーティングシステムにおける互換性の 高いソフトウェア開発の ための アプリケーションプログラミングインターフェース (API)を定めるにあたって IEEEが策定した関連規格の総称である.

計算理論 c©Thomas Zeugmann

Page 7: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

最初のややこしい事柄 I

正規表現の “基本”UNIX構文法は,POSIX によると,もはや時代遅れとされているが,過去の システムとの 互換性の ために今なお広く用いられている.

POSIXは “Portable Operating System Interface” の 略であり,各種 UNIXオペレーティングシステムにおける互換性の 高いソフトウェア開発の ための アプリケーションプログラミングインターフェース (API)を定めるにあたって IEEEが策定した関連規格の総称である.

UNIXは,1960 - 70年代に AT & T Bell研究所の 研究グループが独自に開発したオペレーティングシステムである.しかし今日では,UNIXシステムはいくつかに枝わかれし,多くの“Unix-like”なシステムも存在している.例えば,Solaris,HP-UX, AIXやGNU/Linux, Mac OS, BSDなどがある.

計算理論 c©Thomas Zeugmann

Page 8: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

最初のややこしい事柄 II

正規表現の 完全 UNIX拡張は,特定の 非正規言語を表現でき る.こ れについては,触れるだけに留める.

計算理論 c©Thomas Zeugmann

Page 9: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

最初のややこしい事柄 II

正規表現の 完全 UNIX拡張は,特定の 非正規言語を表現でき る.こ れについては,触れるだけに留める.

Perlおよび Tclはそれら独自の 正規表現を定め,それらの 構文法に直接組み込まれた強力な正規表現エンジンを持つ.

計算理論 c©Thomas Zeugmann

Page 10: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

最初のややこしい事柄 II

正規表現の 完全 UNIX拡張は,特定の 非正規言語を表現でき る.こ れについては,触れるだけに留める.

Perlおよび Tclはそれら独自の 正規表現を定め,それらの 構文法に直接組み込まれた強力な正規表現エンジンを持つ.

いずれにしても,その 基本原理は共通であり,こ こ ではそれらを重点的に見ていく.

計算理論 c©Thomas Zeugmann

Page 11: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

“基本”UNIX正規表現 I

正規表現の 基本 UNIX構文法は POSIX によると時代遅れとされているが,ほとんど の UNIXユーティリティ(grep, sed ...)はデフォルトでそれを用いている.

計算理論 c©Thomas Zeugmann

Page 12: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

“基本”UNIX正規表現 I

正規表現の 基本 UNIX構文法は POSIX によると時代遅れとされているが,ほとんど の UNIXユーティリティ(grep, sed ...)はデフォルトでそれを用いている.

grepは “global search for a regular expression and print outmatched lines,” の 略,sedは “stream editor.” の 略である.

計算理論 c©Thomas Zeugmann

Page 13: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

“基本”UNIX正規表現 I

正規表現の 基本 UNIX構文法は POSIX によると時代遅れとされているが,ほとんど の UNIXユーティリティ(grep, sed ...)はデフォルトでそれを用いている.

grepは “global search for a regular expression and print outmatched lines,” の 略,sedは “stream editor.” の 略である.

実際の アプリケーションの ほとんどは,128文字を含む ASCII文字セットを扱う.こ れは,Σ = {a, b}といったこ れまでの 例とはまったく異なる.

計算理論 c©Thomas Zeugmann

Page 14: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

“基本”UNIX正規表現 II

アルファベット {a, b} に関して,“任意の 文字”を表現したいとする.こ の とき ,a ∨ bと書く事ができ る.しかし,もし 128文字から成るアルファベットを考えた場合,“任意の 文字”を同様に表現すると,非常に長い記述になってしまう.

計算理論 c©Thomas Zeugmann

Page 15: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

“基本”UNIX正規表現 II

アルファベット {a, b} に関して,“任意の 文字”を表現したいとする.こ の とき ,a ∨ bと書く事ができ る.しかし,もし 128文字から成るアルファベットを考えた場合,“任意の 文字”を同様に表現すると,非常に長い記述になってしまう.

そこ で,UNIX正規表現では,大き な文字セットを簡潔に表現するために文字クラスの 記述を許している.

計算理論 c©Thomas Zeugmann

Page 16: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

“基本”UNIX正規表現 II

アルファベット {a, b} に関して,“任意の 文字”を表現したいとする.こ の とき ,a ∨ bと書く事ができ る.しかし,もし 128文字から成るアルファベットを考えた場合,“任意の 文字”を同様に表現すると,非常に長い記述になってしまう.

そこ で,UNIX正規表現では,大き な文字セットを簡潔に表現するために文字クラスの 記述を許している.

おそらく既に次の ような記述を見たこ とがあるだろう.[a − z], [abfg]

実際的なニーズを考慮した構文法を次の スライドで定義する.

計算理論 c©Thomas Zeugmann

Page 17: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

“基本”UNIX正規表現 III

まず,文字クラスを表現する方法を定義する.文字クラスに関する規則は次の 通りである.

記号 . (ドット)は任意の 一文字を表す.列 [a1a2 · · ·ak]は次の 正規表現を表す.

a1 ∨ a2 ∨ · · · ∨ ak .

∨記号を省略するため,こ の 表記は記述すべき 文字を半分省いている.

計算理論 c©Thomas Zeugmann

Page 18: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

その他の文字クラス

角カッコの 中に a − dなる形式の 範囲を書くこ とで,ASCII列における aから dまでの すべての 文字を表す.よって,[a − z]は任意の 小文字に一致する.もしすべての 英文字と数字の 集合を表現したい場合は,[A − Za − z0 − 9]と書くこ とができ る.

UNIX正規表現において特別な意味を持つ角カッコ等の 記号(文字)は,それらの 前にバックスラッシュ \をつけて表現する.

[^]は,カッコ内に含まれない一文字に一致する.例えば[^a − z]は,小文字でない任意の 一文字に一致する.

計算理論 c©Thomas Zeugmann

Page 19: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

その他の文字クラスと規則

^は行の 先頭,$は行の 終端に一致する.\( \)は,カッコ内の 表現を単一の ブロックとして扱うために用いられる.∗ は,その 直前ブロックの 0回以上の 繰り返しに一致する.すなわち,我々の 表記における 〈 〉 に相当する.例えば,空文字列 λ,および,abc,abcabc,abcabcabc,. . . に一致させ るためには,\(abc \)∗ と記述すればよい.

\{x, y\}は,その 直前ブロックの 少なくとも x回,多くともy回の 繰り返しに一致する.よって,a\{3, 5\}は,aaa,aaaaおよび aaaaa に一致する.

こ の 構文法においては,和集合演算に相当する表現はない.

計算理論 c©Thomas Zeugmann

Page 20: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

POSIX拡張 I

現代的な UNIX正規表現は,コマンドラインフラグ “-E”を指定するこ とで,現代的な UNIXユーティリティにおいてしばしば使われる.POSIX の 拡張正規表現の 構文法は,いくつかの 例外を除いて,伝統的な UNIX正規表現の それと同様である.そこ では次の メタ文字が追加されている:

|は和演算を意味する ∨ の 代わりに用いられる.演算子 ? は,その 直前ブロックの “高々 1回” の 繰り返しを意味する.よって,ba?は bあるいは ba に一致する.演算子 +は “1以上”を意味する.よって,R+は我々の 表記における R〈R〉 の 略記である.興味深いこ とに,バックスラッシュはより現代的な UNIX正規表現では取り除かれる.すなわち,\( \)は ( )となり,また,\{ \}は { }となる.もし {x, y} において x = yならば,第 2引数も省略するこ とができ る.すなわち,a{5}は aaaaaを意味する.

計算理論 c©Thomas Zeugmann

Page 21: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

注意点 I

また,おそらく既に気付いている通り,正規表現を記述する際,先に用いた下線付き の 文字ではなく,通常の 文字を用いる.つまり,a の 代わりに単に aと記述する.また,·も省略される.

計算理論 c©Thomas Zeugmann

Page 22: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

注意点 I

また,おそらく既に気付いている通り,正規表現を記述する際,先に用いた下線付き の 文字ではなく,通常の 文字を用いる.つまり,a の 代わりに単に aと記述する.また,·も省略される.

先に述べた通り,Perlは,POSIX拡張正規表現さえよりもさらに豊富な構文法を有する.こ の 構文法は,他の ユーティリティやアプリケーションにおいても用いられる.名称は未だ"正規表現"ではあるが,Perl における拡張は,正規表現を遥かに超えた記述力をもたらす.

計算理論 c©Thomas Zeugmann

Page 23: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

注意点 II

付加的な記述力を与える共通した正規表現の 拡張は,後方参照である.\1や \2といった後方参照は,前の カッコ内の 表現に一致する文字列とだけ一致する:

計算理論 c©Thomas Zeugmann

Page 24: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

注意点 II

付加的な記述力を与える共通した正規表現の 拡張は,後方参照である.\1や \2といった後方参照は,前の カッコ内の 表現に一致する文字列とだけ一致する:

例 1: (cat|dog)\1は catcatと dogdog に一致するが,catdogやdogcat には一致しない.

計算理論 c©Thomas Zeugmann

Page 25: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

注意点 II

付加的な記述力を与える共通した正規表現の 拡張は,後方参照である.\1や \2といった後方参照は,前の カッコ内の 表現に一致する文字列とだけ一致する:

例 1: (cat|dog)\1は catcatと dogdog に一致するが,catdogやdogcat には一致しない.

例 2: (.∗)\1は papa, mamaといった繰り返す語の 文字列と一致する.より一般には,非空の 任意の 文字列を wとしたとき ,ww

に一致する.なお,L = {ww | w ∈ Σ+}は正規でないこ とに注意しよう.

計算理論 c©Thomas Zeugmann

Page 26: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

注意点 II

付加的な記述力を与える共通した正規表現の 拡張は,後方参照である.\1や \2といった後方参照は,前の カッコ内の 表現に一致する文字列とだけ一致する:

例 1: (cat|dog)\1は catcatと dogdog に一致するが,catdogやdogcat には一致しない.

例 2: (.∗)\1は papa, mamaといった繰り返す語の 文字列と一致する.より一般には,非空の 任意の 文字列を wとしたとき ,ww

に一致する.なお,L = {ww | w ∈ Σ+}は正規でないこ とに注意しよう.

後方参照により付加される記述力には,コストを払わなければならない.Perlが採用している最もよく知られた実装は,最悪時において指数的な探索アルゴリズムを必要とする.

計算理論 c©Thomas Zeugmann

Page 27: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 I

正規表現の 最も古い応用の ひとつは,“字句解析器”と呼ばれるコンパイラの 構成要素の 記述に見られる.こ れは,ソースプログラムを走査 (scan)し,トークン,すなわち,論理的なまとまりを成す連続した文字からなる部分文字列を認識する.キーワードや識別子がトークンの 一般的な例であるが,他にも多数存在する.走査器 (scanner)は,有限オートマトンとして実装される.

計算理論 c©Thomas Zeugmann

Page 28: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 I

正規表現の 最も古い応用の ひとつは,“字句解析器”と呼ばれるコンパイラの 構成要素の 記述に見られる.こ れは,ソースプログラムを走査 (scan)し,トークン,すなわち,論理的なまとまりを成す連続した文字からなる部分文字列を認識する.キーワードや識別子がトークンの 一般的な例であるが,他にも多数存在する.走査器 (scanner)は,有限オートマトンとして実装される.

UNIXコマンド lexと,その GNU版である flexは,入力として UNIXスタイルの 正規表現の リストを受取る.こ こ で,各正規表現には,字句解析器がトークンの 具体例を見つけた際にすべきこ とを記述したコードがカッコ書き で付随している.

計算理論 c©Thomas Zeugmann

Page 29: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 II

こ うしたツールは 字句解析器の生成器と呼ばれる.なぜなら,それは入力として,字句解析器に関する高度なレベルの 記述をもらい,字句解析器として機能する関数をそこ から作り出すからである.

計算理論 c©Thomas Zeugmann

Page 30: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 II

こ うしたツールは 字句解析器の生成器と呼ばれる.なぜなら,それは入力として,字句解析器に関する高度なレベルの 記述をもらい,字句解析器として機能する関数をそこ から作り出すからである.

正規表現の 表記法は,トークンを記述するにあたり十分強力なので,lexや flex の ようなコマンドは大変役に立つ.

計算理論 c©Thomas Zeugmann

Page 31: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 II

こ うしたツールは 字句解析器の生成器と呼ばれる.なぜなら,それは入力として,字句解析器に関する高度なレベルの 記述をもらい,字句解析器として機能する関数をそこ から作り出すからである.

正規表現の 表記法は,トークンを記述するにあたり十分強力なので,lexや flex の ようなコマンドは大変役に立つ.

こ れらの コマンドは,ソースプログラムをトークンに分解する効率的な関数を生成するために, 「正規表現からDFAへの 変換アルゴリズム」 を用いるこ とができ る.その 主な利点はコード記述にある.なぜなら,正規表現は決定性有限オートマトンを書くよりずっと容易だからである.

計算理論 c©Thomas Zeugmann

Page 32: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 II

こ うしたツールは 字句解析器の生成器と呼ばれる.なぜなら,それは入力として,字句解析器に関する高度なレベルの 記述をもらい,字句解析器として機能する関数をそこ から作り出すからである.

正規表現の 表記法は,トークンを記述するにあたり十分強力なので,lexや flex の ようなコマンドは大変役に立つ.

こ れらの コマンドは,ソースプログラムをトークンに分解する効率的な関数を生成するために, 「正規表現からDFAへの 変換アルゴリズム」 を用いるこ とができ る.その 主な利点はコード記述にある.なぜなら,正規表現は決定性有限オートマトンを書くよりずっと容易だからである.もし何かを変更する必要があるとき ,正規表現の 変更は非常に単純であるこ とが多いが,決定性有限オートマトンを実装したコードを変更するこ とは悪夢である.

計算理論 c©Thomas Zeugmann

Page 33: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

例として,次の (1行の )正規表現を考える.

(0|1)∗1(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)

(0|1)(0|1)(0|1)(0|1)

こ の 正規表現が定める言語を受理する決定性有限オートマトンを作ってみよう.

計算理論 c©Thomas Zeugmann

Page 34: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

例として,次の (1行の )正規表現を考える.

(0|1)∗1(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)

(0|1)(0|1)(0|1)(0|1)

こ の 正規表現が定める言語を受理する決定性有限オートマトンを作ってみよう.

ただし,諸君が予想するよりずっと多くの 状態が必要なの で,完全に週末をつぶすつもりでいて欲しい.

計算理論 c©Thomas Zeugmann

Page 35: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

例 (続き )

その こ とを確かめるには,まずはこ れをずっと短くした次の 正規表現から始めるべき である.

(0|1)∗1(0|1)

こ れに対応するオートマトンは次の 通りである.

1

1

00

1

0

0

1

計算理論 c©Thomas Zeugmann

Page 36: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

例 (続き )

では,次の 正規表現について各自で考えてみよ.

(0|1)∗1(0|1)(0|1)

計算理論 c©Thomas Zeugmann

Page 37: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

例 (続き )

では,次の 正規表現について各自で考えてみよ.

(0|1)∗1(0|1)(0|1)

次の 正規表現については?

(0|1)∗1(0|1)(0|1)(0|1)

同様に,より長い正規表現について順次考えていく.

計算理論 c©Thomas Zeugmann

Page 38: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

例 (続き )

では,次の 正規表現について各自で考えてみよ.

(0|1)∗1(0|1)(0|1)

次の 正規表現については?

(0|1)∗1(0|1)(0|1)(0|1)

同様に,より長い正規表現について順次考えていく.

最後に,およそ 32,000,000 の 状態を持つ決定性有限オートマトンとなる正規表現を与えてみよ.

計算理論 c©Thomas Zeugmann

Page 39: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 III

では,字句解析器に戻ろう.以下は,lexコマンドへの 入力例の一部である.

else {return(ELSE); }[A − Za − z][A − Za − z0 − 9]∗ {code to enter the found iden-

{tifier in the symbol table;{return(ID);

}

>= {return(GE);}

= {return(EQ);}

· · ·

図 1: lexへの 入力例

計算理論 c©Thomas Zeugmann

Page 40: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

字句解析 IV

1行目で キーワード elseが処理され,その 動作として記号定数ELSEが返される.

2行目の 正規表現は識別子を記述したもの であり,ある英文字の後に 0個以上の 英文字や数字が続く.その 動作として,見つかった識別子が (未登録であれば)記号表に登録され,識別子を表す記号定数 IDが返される.3行目は 2文字の 演算子記号 >=を処理する.また,最後の 行は,1文字の 演算子記号 =を処理する.

実際には,各キーワード,各演算子記号,カンマやカッコ等の 各句読点記号,数字や文字列等を含む各定数について,それぞれを記述した正規表現が現れるだろう.

計算理論 c©Thomas Zeugmann

Page 41: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

flexの使用例

flex の 動作を見るために,次の コードをファイル (例えば,ex.lex )に保存せ よ.

/*****************************/

/* making x for u */

/*****************************/

%option noyywrap

%%

"u" printf("x");

main () {

yylex();

}

計算理論 c©Thomas Zeugmann

Page 42: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

flexの使用例

次の 内容を記述したサンプルテキスト (例えば,xu.txt)を新規作成せ よ.

Romans used for both letters U and V the same symbol V.They also used V to denote the number 5. Some moneylenders used the fact that one can obtain an X by extendingthe lines in V - thus a debt of 5 Sesterces became 10Sesterces. Thus, in German we have the common saying“ein X für ein U vormachen.” (English “throw dust in aperson’s eye”)See: Kurt Krüger -Lorenzen, Das geht auf keine Kuhhaut

計算理論 c©Thomas Zeugmann

Page 43: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

flexの使用例

こ こ で以下を実行する.flex ex.lex

こ れにより,C言語の プログラム lex.yy.cが生成される.次に,それをコンパイルする.gcc lex.yy.c -o xu最後に,xu < xu.txtを実行する.

lex.yy.c の 内容を確認してみよう.

計算理論 c©Thomas Zeugmann

Page 44: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

flexの使用例

もしすべてがうまくいったら,内容は次の 通りとなるだろう.

Romans xsed for both letters U and V the same symbol V.They also xsed V to denote the nxmber 5. Some moneylenders xsed the fact that one can obtain an X by extendingthe lines in V - thxs a debt of 5 Sesterces became 10Sesterces. Thxs, in German we have the common saying“ein X fxer ein U vormachen.” (English “throw dxst in aperson’s eye”)See: Kxrt Krüger -Lorenzen, Das geht axf keine Kxhhaxt

計算理論 c©Thomas Zeugmann

Page 45: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す I

あるファイル中の テキストを探すためにテキストエディタ (あるいは,UNIXプログラム grep)をしばしば使うであろう (例えば,深さ優先探索プログラムを定義した箇所を探したい場合等).こ れと密接に関連して,適切なWebページを絞り込む,または見つける問題が考えられる.

計算理論 c©Thomas Zeugmann

Page 46: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す I

あるファイル中の テキストを探すためにテキストエディタ (あるいは,UNIXプログラム grep)をしばしば使うであろう (例えば,深さ優先探索プログラムを定義した箇所を探したい場合等).こ れと密接に関連して,適切なWebページを絞り込む,または見つける問題が考えられる.

こ れらツールはど の ように動作するの か?

計算理論 c©Thomas Zeugmann

Page 47: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す II

一般に使われるアルゴリズムとして,Knuth-Morris-Pratt (KMP)および Boyer-Moore (BM)がある.両者は類似した考え方に基づいており,O(m + n) の 線形時間で動作する.こ こ で,mは探したい文字列 (パターンと呼ぶ) の 長さ,nは探す対象となるファイルの 長さである.どちらも特定の 文字が等しいかそうでないかだけを調べ,文字に関する複雑な計算は一切行なわない.

計算理論 c©Thomas Zeugmann

Page 48: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す II

一般に使われるアルゴリズムとして,Knuth-Morris-Pratt (KMP)および Boyer-Moore (BM)がある.両者は類似した考え方に基づいており,O(m + n) の 線形時間で動作する.こ こ で,mは探したい文字列 (パターンと呼ぶ) の 長さ,nは探す対象となるファイルの 長さである.どちらも特定の 文字が等しいかそうでないかだけを調べ,文字に関する複雑な計算は一切行なわない.

実際は Boyer-Moore の 方がわずかに高速だが,より複雑である.Knuth-Morris-Prattは単純なの で,こ こ ではこ ちらについて簡単に述べる.

計算理論 c©Thomas Zeugmann

Page 49: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す III

文字列 sasoを grep したいとしよう.こ こ では,現在の 状態にそれまでに走査した文字列に関する情報を保持させ た決定性有限オートマトンを作る.いま,こ れまでに走査した文字列が“nauvwxy”であったと仮定すると,次の ふたつの 事柄について知る必要がある

計算理論 c©Thomas Zeugmann

Page 50: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す III

文字列 sasoを grep したいとしよう.こ こ では,現在の 状態にそれまでに走査した文字列に関する情報を保持させ た決定性有限オートマトンを作る.いま,こ れまでに走査した文字列が“nauvwxy”であったと仮定すると,次の ふたつの 事柄について知る必要がある

1 既に探しているパターン (saso)に一致したか?2 もしまだであるなら,一致に至る途中段階にあるか?

計算理論 c©Thomas Zeugmann

Page 51: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す IV

もし,一致の 途中段階にあるならば,パターンの ど こ までを既に走査したの かも知る必要がある.よって,各状態は,パターンへの 部分一致であってほしい.

計算理論 c©Thomas Zeugmann

Page 52: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す IV

もし,一致の 途中段階にあるならば,パターンの ど こ までを既に走査したの かも知る必要がある.よって,各状態は,パターンへの 部分一致であってほしい.

saso に関する可能な部分一致は,λ, s, sa, sasであり,完全一致は saso それ自身である.別の 言い方をすると,saso の 空文字列を含むすべての 接頭辞を考慮する必要がある.

計算理論 c©Thomas Zeugmann

Page 53: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探す IV

もし,一致の 途中段階にあるならば,パターンの ど こ までを既に走査したの かも知る必要がある.よって,各状態は,パターンへの 部分一致であってほしい.

saso に関する可能な部分一致は,λ, s, sa, sasであり,完全一致は saso それ自身である.別の 言い方をすると,saso の 空文字列を含むすべての 接頭辞を考慮する必要がある.

もしパターンの 長さがmならば,m + 1 の 接頭辞が存在する.よって,可能な部分一致を記録するために,オートマトン中にはm + 1 の 状態が必要となる.空一致が開始状態,完全一致が受理状態となるこ とは明らかであろう.

計算理論 c©Thomas Zeugmann

Page 54: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探すV

一般に,ある状態において文字を読みこ むと,その 部分一致にいま読み込んだ文字を加えた文字列の 接尾辞で,かつ,パターンの接頭辞でもある最長の 部分一致に対応する状態へ遷移する.例えば,既に sasを読み込み,次の 文字が aである場合は,部分一致sa に対応する状態へ遷移するこ とになる.

計算理論 c©Thomas Zeugmann

Page 55: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探すV

一般に,ある状態において文字を読みこ むと,その 部分一致にいま読み込んだ文字を加えた文字列の 接尾辞で,かつ,パターンの接頭辞でもある最長の 部分一致に対応する状態へ遷移する.例えば,既に sasを読み込み,次の 文字が aである場合は,部分一致sa に対応する状態へ遷移するこ とになる.

我々が欲しい決定性有限オートマトンは以上の 考え方に基づいて作り出すこ とができ る.

計算理論 c©Thomas Zeugmann

Page 56: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探すVI

sasoを含むすべての 文字列を受理する決定性有限オートマトン

other

start s a s

sa

other

s any

oempty s sa sas saso

計算理論 c©Thomas Zeugmann

Page 57: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探すVII

O(m3 + n)時間の 文字列照合アルゴリズムを得るためには以上の議論で十分である.そこ では,状態表を作成するために O(m3)

時間を,入力ファイルに対してそれを動作させ る際に O(n)時間を要する.

計算理論 c©Thomas Zeugmann

Page 58: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探すVII

O(m3 + n)時間の 文字列照合アルゴリズムを得るためには以上の議論で十分である.そこ では,状態表を作成するために O(m3)

時間を,入力ファイルに対してそれを動作させ る際に O(n)時間を要する.

KMPアルゴリズムには,ふたつの 巧妙な点がある.ひとつは,O(m)領域の みを必要とする状態表の 表現にある (上の 場合はO(m2)領域を要する).

計算理論 c©Thomas Zeugmann

Page 59: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

テキスト中のパ タ ー ンを探すVII

O(m3 + n)時間の 文字列照合アルゴリズムを得るためには以上の議論で十分である.そこ では,状態表を作成するために O(m3)

時間を,入力ファイルに対してそれを動作させ る際に O(n)時間を要する.

KMPアルゴリズムには,ふたつの 巧妙な点がある.ひとつは,O(m)領域の みを必要とする状態表の 表現にある (上の 場合はO(m2)領域を要する).

もうひとつは,O(m)時間ですべてを作り上げる複雑なループを用いている点である.こ れにより,全体で O(m + n)時間となる.しかし,こ れら巧妙な点はこ れまでの 講義でも既に見てき たはずである.必要に応じてテキストにある参考文献を参照するこ と.

計算理論 c©Thomas Zeugmann

Page 60: Thomas Zeugmann - 北海道大学minato/ToC2016/toc_lec05j.pdf · Perl およびTcl はそれら独自の正規表現を定め,それらの構文法 に直接組み込まれた強力な正規表現エンジンを持つ.

はじめに “基本”UNIX POSIX 応用 テキスト中の パターンを探す おわり

Thank you!

計算理論 c©Thomas Zeugmann