コンパイラ/正規言語のソースを表示
←
コンパイラ/正規言語
ナビゲーションに移動
検索に移動
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループに属する利用者のみが実行できます:
登録利用者
。
このページのソースの閲覧やコピーができます。
{{Wikipedia|正規言語}} == 正規表現の規定 == {{Wikipedia|正規表現}} 正規表現はよくプログラムの文字列の解析に使われる。今から正規表現の規定を行う。 === 演算記号 === * <math>|</math> : <math>r | s</math> は、<math>r</math> または <math>s</math> のどちらかの要素を意味する。すなわち、<math>r | s</math> は <math>r</math> または <math>s</math> である。 * 連結 (<math>\cdot</math>だが普通省略される) : <math>rs</math> は見た目の通り、<math>r</math> の要素の後に <math>s</math> の要素をつなげたものである。 * <math>*</math> : <math>r*</math> は、<math>r</math> の0回以上の繰り返しを意味する。すなわち、<math>\epsilon, r, rr, rrr, \ldots</math> である。 * <math>( )</math> : <math>(r)</math> は <math>r</math> と同じである。通常の計算式のように、優先順位を明確にするために使われる。 以上が正規表現の本質の表現である。次のものは、正規表現中によく出てくるといった理由で、拡張した省略記法の演算子もあるので代表例を紹介する。 * <math>+</math> : <math>r+</math> は、<math>r</math> の1回以上の出現である。<math>r+ = rr*</math> である。 * <math>?</math> : <math>r?</math> は、<math>r</math> の0回または1回の出現を表す。<math>r? = r | \epsilon</math> である。 === 演算子の優先順位と結合 === 演算子を決めただけでは、例えば<math>r | s*</math> は、 <math>(r | s)*</math> なのか、 <math>r | (s*)</math> なのか分からない。また、<math>r | s | t</math>は、<math>(r | s) | t</math> (左結合)なのか、<math>r | (s | t)</math> (右結合) なのか分からない。このように、無駄なカッコを多用しなくて済むように演算子の優先順位と結合を取り決める。なお、これは一般的な優先順位である。 * <math>* + ?</math> の3つは最も優先順位が高く、左結合である。 * 連結はその次に優先順位がたかく、左結合である。 * <math>|</math> は最も優先順位が低く、左結合である。 === 正規表現の定義方法 === 先ほどから誤魔化して使っていたが、<math>=</math> という記号がある。これは、<math>r = s</math> のとき、r と s が'''等価'''であり、同じ言語を表すということを示す記号である。 正規表現の定義 (正規定義) は、 <math> \begin{align} d_1 \to r_1 \\ d_2 \to r_2 \\ d_3 \to r_3 \\ d_4 \to r_4 \\ \ldots \\ d_n \to r_n \\ \end{align} </math> という形で、文脈自由文法とかなり似ている。しかし、'''決定的な違い'''があって、それは、<math>i \leq j</math> のとき、<math>d_i \to r_i</math> の <math>r_i</math>の中に <math>d_j</math> があってはならない'''、ということである。 これにより、正規表現は'''再帰が制限される'''ので、文脈自由文法よりも小さい文法クラスになり、表現範囲が狭くなるのである。 文脈自由文法は完全に正規表現を包含し、文脈自由文法の方が大きいクラスである。このことの証明はここでは省くが、正規表現の定義方法が文脈自由文法とほとんど同じで、正規表現の演算子を文脈自由文法で置き換えてやることができれば、文脈自由文法は少なくとも正規表現以上であることが分かる。あとは文脈自由文法では表現可能だが正規表現では表せない言語、例えば釣り合ったカッコの列、があることを示せばこれは証明される。 === 演算子の法則 === <math>|</math> は、交換法則、結合法則、が成り立つ。式で表すと、 * <math>r | s = s | r</math> * <math>r | (s | t)</math> 連結は、結合法則、<math>|</math>に対して分配法則、が成り立つ。式で表すと、 * <math>(rs)t = r(st)</math> * <math>r(s | t) = rs | rt</math> <math>\epsilon</math>は連結に対して単位元である。式で表すと、 * <math>\epsilon r = r \epsilon = r</math> また、<math>\epsilon</math>に関して言えば、 * <math>r* = (r | \epsilon)*</math> * <math>r+ = rr* = r(r | \epsilon)*</math> * <math>r? = (r | \epsilon)?</math> である。 * <math>*, +, ?</math> は全て冪等性を持つ。式で表すと、 * <math>r** = r*</math> * <math>r++ = r+</math> * <math>r?? = r?</math> 以上は、別に非常に重要というわけではないが、暗黙の了解を明確化し、参考程度に思ってもらえばよい。 == 有限オートマトン == {{Wikipedia|決定性有限オートマトン}} {{Wikipedia|非決定性有限オートマトン}} 決定性オートマトン (DFA)、非決定性オートマトン (NFA) はどちらも正規言語を処理するだけの能力を持っている。正規表現と非決定性オートマトンのあいだのつながりは比較的理解しやすいので、まずはNFAの定義から始める。 <small>注釈 : NFA とさらに ε遷移を含むNFA という分け方もあるが、ここでは NFA といったら ε遷移をも含むものとする。</small> NFA は以下の定義からなる。 *状態と呼ばれるものの集合 *入力文字の集合 *状態 s, 入力文字 a に対して 状態を返す'''遷移関数''' move(s, a) *'''開始記号'''と呼ばれ、他の状態とは区別される状態 s<sub>0</sub> *'''受理状態'''と呼ばれ、他の状態とは区別される状態の集合 このNFAの表現の仕方には主に二つあり、それは遷移図と遷移表である。 === 遷移図 === 繊維図は、各状態を円として書き、move(s, a) = r ならばs から r に向かって、a をラベルに持つ矢印を書く。 === 遷移表 === 各状態と各入力記号列を縦横で並べたものである。空欄は誤りを意味する。 [[カテゴリ:コンパイラ]]
このページで使用されているテンプレート:
テンプレート:Wikipedia
(
ソースを閲覧
)
コンパイラ/正規言語
に戻る。
ナビゲーション メニュー
個人用ツール
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
ソースを閲覧
履歴表示
その他
検索
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
特別ページ
ツール
リンク元
関連ページの更新状況
ページ情報