ウォンツテック

そでやまのーと

以下のフェーズを考える

1.正規表現の文法を考える
2. 1の文法が構文解析した時にあいまい(解析木が複数通りある)で無い事を確かめるため、LL(1)文法を満たしているかを考察する

まず1だけど、文法(構文規則)を考える。
正規表現の定義は前回与えた通りでさらに優先順位があり
R*が最も高く(=R+)次にRS、最後にR|Sとなる。
今回は"()"の表現も許すため(R)が最も優先順位が高くなる。

これからひとまず正規表現Rの再帰的下向き構文解析を以下のように置く

[文法R]
R = T or R | T
T = ET | \epsilon
E = F | F* | F+
F = CHARACTER | ( R )

※orは正規表現上"|"の事であるが、同じ記号を使うため便宜的に置き換えた。また、CHARACTERはアルファベットの事で\epsilonは空文字とする。


ここで、上記の文法がLL(1)である事を確かめるため、参考文献「コンパイラ 中田育男著」より以下の定義を引用する
【定義】記号列 \alpha \in (V_{N} \cup V_{T})*と非終端記号A \in V_{N}について、First(\alpha)とFollow(A)を次のように定義する。
※V_{N}V_{T}はそれぞれ非終端記号の集合と終端記号の集合を意味する

First(\alpha) = \{a|a \in V_{T}, \alpha \overset{\text{*}}{\Rightarrow} a...\}
ただし、\alpha \overset{\text{*}}{\Rightarrow} \epsilonなら\epsilon \in First(\alpha)とする
Follow(A) = \{ a|a \in V_{T}, S \overset{\text{*}}{\Rightarrow} ...Aa... \}
※...とは任意の記号列を意味する

これはすなわち、First(\alpha)\alphaの先頭の終端記号になりうる集合であり、Follow(A)は文形式の中でAの直後の終端記号になりうるものの集合である。

また、Director(A,\alpha)を以下のように定義する

【定義】記号列 \alpha \in (V_{N} \cup V_{T})*と非終端記号A \in V_{N}に対して、生成規則A \rightarrow \alphaがあるとき、Director(A, \alpha)を次のように定義する
Director(A, \alpha) =  \{ a|a \in V_{T}, a \in First(\alpha) \\ or \\ (\alpha \overset{\text{*}}{\Rightarrow} \epsilon \text{ and } a \in Follow(A)) \}

※First, Follow, Directorを求めるアルゴリズムはめんどいんで掲載しない。

文法RのFirst, Follow, Directorを求めるとそれぞれ以下のようになる

■First
 First(F) = {CHARACTER, (}
 First(E) = {CHARACTER, (}
 First(T) = {CHARACTER, (, \epsilon}
 First(R) = {CHARACTER, (, \epsilon}
■Follow
 Follow(R) = {$, )}
 Follow(T) = {or, $, )}
 Follow(E) = {CHARACTER, (}
 Follow(F) = {CHARACTER, (, *, +}
■Director
 Director(R,TorR) = First(TorR) = {CHARACTER, (}
 Director(R,T) = First(T) or Follow(R) {CHARACTER, (, $, )}

ここでいきなり Director(A, \alpha) \cap Director(A, \beta) \not{=} \phi
となってしまったので上記の正規表現文法RはLL(1)では無い。

というより、R = TorR|Tの時点で最初の文字がどちらの分岐に行くか定まるわけが無い。。
※First(TorR) \cap First(T) \not{=} \phi

この文法Rって参考文献「Cプログラマのための アルゴリズムとデータ構造」に出てた正規表現の構文規則とほぼ同じなんだけど(実際そこでも R = T|TorRという事をやっている)
、これはLL(1)である必要が無い?!
ってか良く考えたらこの構文規則をNFA,DFAと変換していくわけだけど、DFAってLL(1)を満たしてないか?!
という事はわざわざ最初の構文規則はLL(1)を満たして無くてもいい?
もしくはLL(1)が満たされていれば、実はその構文規則をNFAに変換する段階ですでにそれはDFAになっているかもしれない?

ここでDFAの定義を復習
DFAとは次の条件を満たす有限オートマトンである
(1) \epsilonによる遷移がない
(2) 1つの状態から同じ記号による異なった状態への遷移はない

これって確かにLL(1)っぽい。
なぜなら、\epsilonの遷移が無いのでまずFollowを考える必要がない、次に、ある記号が与えられた場合遷移はかならず一意に定まる。

うーん。。
とりあえずLL(1)じゃないけど文法Rでコーディングしてみるかな。。