http://www.sw.it.aoyama.ac.jp/2014/Compiler/lecture4.html
© 2005-14 Martin J. Dürst 青山学院大学
次の右線形文法に相当する NFA の遷移図を作りなさい
[都合により削除]
宿題 1 の NFA と同等の DFA を作り、遷移表で表しなさい (状態の書き換えは不要)
[都合により削除]
[都合により削除]
宿題 2 の DFA を右線形文法に変換しなさい
[都合により削除]
flex
, bison
, gcc
, make
の動作確認 (提出なし;
ただし、不可能な場合、必ず次回にノートパソコンを持参すること)
これらは全て同じ力を持って、正規言語を定義・受理する
これらを表現する「正規表現」(regular expression) という協力な表現方法が存在
ある DFA から同等の最小の DFA は次のように作成可能:
最小化の目的:
State next_state[state_count][symbol_count]; /* 遷移表 */ Boolean final_state[state_count]; /* 受理状態かどうか */ State current_state = start_state; /* 初期状態で初期化 */ Symbol next_char; /* 次の入力記号 */ while ((next_char=getchar()) != EOF && /* 入力終了 */ current_state != no_state) /* 行き止まり */ current_state = next_state[current_state][next_char]; if (final_state[current_state]) printf("Input accepted!"); else printf("Input not accepted!");
計算機実習 I の演習問題 (04C1):
ある文章中、&
, "
,
'
, <
, >
を見つけ、それぞれを &
, "
,
'
, <
, >
に変換せよ。
Ruby で書くと次のようになる:
gsub /"/, '"'
gsub /'/, "'"
gsub /</, '<'
gsub />/, '>'
gsub /&/, '&'
gsub
は「文字列内全て置換」のメソッド
//
の間は正規表現
abc
: {abc} の言語を表現a*
: {ε, a, aa, aaa,...} (の言語)a|b
: {a, b}ab|c*|d
: {ab, ε, c, cc, ccc,..., d}a(b|c)*d
: {ad, abd, acd, abbd, abcd, acbd, accd,...}|
, *
,
(
, )
)優先度 | 正規表現 | 条件 | 言語 | 備考 |
---|---|---|---|---|
ε, a | a ∈ Σ | {ε} 又は {a} | ||
低い | r|s | r, s が正規表現 | L(r|s) = L(r) ∪ L(s) | 集合和 |
低め | rs | r, s が正規表現 | L(rs) = L(r)L(s) | 連結 |
高め | r* | r が正規表現 | L(r*) = (L(r))* | 閉含 |
高い | (r) | r が正規表現 | L((r)) = L(r) |
L(r) は r によって定義される言語
word
(aa)*a
)、偶数
((aa)*
)、3で割れば余りが 2
(aa(aaa)*
)、等abc(a|b|c)*
(a|b|c)*abc
(a|b|c)*abc(a|b|c)*
正規表現に対応する NFA は正規表現の部分表現から再帰的に作成可能
ε と a に対応する NFA は初期状態一つと受理状態一つとそれを結ぶ ε 又は a と書かれた矢印
r|s の NFA は r の NFA と s の NFA から次のように作成:
rs の NFA は r の受理状態と s の初期状態を ε で結んで、r の初期状態は rs の初期状態、s の受理状態は rsの受理状態。
r* の NFA は次のように作成:
正規表現: a|b*c
変換は可能が、複雑
変換の原理:
正規表現の便利な追加機能 (括弧内は相当する理論的な正規表現)
.
: 任意の文字一個 (a|b|c|
...)+
: 一個以上の r
(rr*
)?
: r の有無 (r|ε,
その代わり ε は使えない){
m,
n}
:
m 個以上 n 個以下の r
(r...rr?
...r?
)[acdfh]
: 複数の文字から選択
((a|c|d|f|h)
)[b-f]
: b から f の字 ((b|c|d|e|f)
)\*
等: \
はメタ文字のエスケープに使われる^
と $
などで語 (行)
の先頭と最後をマッチ(提出不要)
(a|c*)a|b
予定:
準備: