アルゴリズムとデータ構造1

コンパイラ
2011年10月24日
酒居敬一@A468([email protected])
http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/COMP/2011/index.html
1
構文解析
前回の内容


下向き構文解析法


左再帰性の問題と、その除去
バックトラックの問題
今回の内容


LL(k)構文解析法。




LL(1)構文解析法

2
動機付けとして、下向き構文解析におけるバックトラックをなくしたい。
LLは Left to right scan, Left most derivation より。
k個の字句を先読みすることでバックトラックなし構文解析を実現する。
字句をひとつだけ先読みすることで、決定的に構文解析可能。
LL構文解析
下向き構文解析では、解析木を根から生成する。


根にある非終端記号(=字句の列の先頭)がどの生成規則
に適合するか、それが初めにわかればバックトラック不要。
 A α|β
の例では、αとβのどちらかを一意に決めたい、ということ。
字句をひとつ読んだとき、それが生成規則を決める
手がかりであるかどうかがわかればよい???


入力記号aがαの先頭記号になりうるか?


入力記号aがAの直後の終端記号になりうるか?



入力記号aがαの先頭記号でなければ、 A  α  ε の場合。
そこで、First集合、Follow集合というものを考えることにする。

3
そしてバックトラック不要にするために、 βの先頭記号ではないこと。
このようなaを含む集合をDirector集合という。
First集合
A α|β
αの先頭記号になりうる入力記号をFirst(α)とする。


同様にFirst(β)も考える。
First(α)∩First(β)=φならば、入力記号により
αかβを一意に決定できる。




Firstα   a | a  T ,α  a 



ただし、 α  ε ならば ε  Firstα  とする。
ただし、εに展開してもいいかどうか一意に決定できないので、
そういうときは後述のFollow集合とともに決定する。


A  αε
4
First集合を求めるアルゴリズム
α,βを記号列、A,Yを非終端記号、aを終端記号とする。
1. αが空列記号(ε)のとき:First(α)にεを加える。
2. αが終端記号aのとき: First(α)にaを加える。
3. αが非終端記号Aのとき:Aを左辺に持つすべての
生成規則A→βについてFirst(β)を求め、その要素を
First(α)に加える。
4. αが長さ2以上の記号列(α=Yβ)のとき
if   FirstY 
First  に FirstY  を加える。

else
5
First  に FirstY     と
First  を加える。
Follow集合

A  αε



という生成規則からはAをεに展開してもよい。
このときは、   First  でもある。しかし、εは字句ではない。
入力からは、前ページのようには、一意に決定できない。
そこでFollow(A)という集合を考える。


これはAの直後の終端記号に成りうる記号の集合。



FollowA   a | a  T ,S Aa


 a  First 
ならばαに展開できた。ところが、aがFirst集合に
含まれず   First  である場合でも a  FollowA であれば、
ここはαに展開できる。

つまり A  α  ε という生成規則に一意に決定できるということ。
6
Follow集合を求めるアルゴリズム
Sを開始記号、α,βを記号列、A,Bを非終端記号、
aを終端記号、$を入力の最後を表す特殊な記号とする。
1. Sが開始記号のとき:Follow(S)に$を加える。
2. A→αBβなる生成規則のとき:
Follow(B)にFirst(β)ー{ε}を加える。
3. A→αBβなる生成規則において、
First(β)にεが含まれているとき:
Follow(B)にFollow(A)を加える。

7
Director集合
First集合とFollow集合を合わせて、Aをαに展開すべき
かどうかを決定するための集合をDirector集合として
定義する。

記号列 α  N  T 
*
と非終端記号A  N に対して、生成規則 A  α があるとき、
DirectorA, α  を次のように定義する
。

 

DirectorA, α   a | a  T ,a  Firstα  または  α  ε かつ a  FollowA 



ところで、同じ入力記
号 a が DirectorA, α  にも DirectorA,β  にも入っていたら、
α と β のどちらへ展開すべき かが決まらない。
そのようなものをなく
8
したものが 、 LL1 文法である。
LL(1)文法
LL(1)文法の定義

与えられた文法Gに対 する任意の生成規則
A  1 |  2 |  |  n
に対して
DirectorA, i   DirectorA, j    , where i  j
ならば、文法Gは
LL1 文法であるという。
先頭の字句をひとつ読めば展開すべき生成規則が
一意に決まるということを意味している。
そのような文法をLL(1)文法といっている。

9
再帰的下向き構文解析1

LL(1)文法であれば、バックトラックしない
再帰的下向き構文解析器が作成できる。
【文法G1】

(1)式
→
式+項
(2)式
→
項
(3)項
→
項*因子
(4)項
→
因子
(5)因子
→
(式)
(6)因子
→
i
しかしながら、この文法G1では、左再帰性をもつため、
このままでは再帰的下向き構文解析ができない。
10
再帰的下向き構文解析2

左再帰性を除去した文法G2
【文法G2】

(1)式
→
項 式端
(2)式端
→
+項 式端|ε
(3)項
→
因子 項端
(4)項端
→
*因子 項端|ε
(5)因子
→
(式)|i
正規右辺文法もしくは拡張BNFによる文法G3
【文法G3】
11
(1)式
→
項 {+項}
(2)項
→
因子 {*因子}
(3)因子
→
(式)|i
形式言語による言語と文法の定義1

アルファベット

空でない有限集合。


文字・記号


アルファベットの要素を有限個並べたもの。
空語・空文字列・空記号列


アルファベットの要素。
語・文字列・記号列


ABC…Zのような英語のアルファベットと混同しないように。
アルファベットの要素をひとつも含まないもの。εで表す。
語彙

12
生成規則に現れる記号(全部)の集合。
形式言語による言語と文法の定義2

四つ組G=(N,T,P,S)を文法という。

N,T,Pは空ではない有限集合。



NとTに共通部分はない。
Pの要素(生成規則)は「左辺→右辺」の形をとる。



N,T,P の要素はそれぞれ非終端記号,終端記号,生成規則。
左辺と右辺は(N∪T)*の要素とする。
開始記号SはS∈Nとする。
文法G上の言語L(G)とは、


開始記号Sから出発し、生成規則(Pの要素)を有限回適用して
得られた、終端記号列(文)の集合。


x  N  T  で S  x ならば x を文形式という。
x T
13


で S  x ならば
x を文という。




LG   x  T | S  x  である。


形式言語による言語と文法の定義3

句構造文法



タイプ0(制限なし)
タイプ1(文脈依存文法)


アセンブリ言語はこのタイプ。
タイプ2(文脈自由文法)



1950年代後半に言語学者チョムスキーによって考案された。
生成規則の左辺がひとつの非終端記号だけからなる。
C言語やJavaなど高級言語はたいていこのタイプ。
タイプ3(正規文法)
14
予習・復習

C言語では次のような宣言もしくは定義ができる。

複雑な宣言や定義をそのまま書くと複雑で読みにくいので、
通常はtypedefを使って段階的に宣言や定義する。
int *f();
int (*f)();
/* fはintへのポインタを返す関数 */
/* fはintを返す関数へのポインタ */
char **argv;
/* charへのポインタのポインタ */
int (*daytab)[13]; /* daytabはintを要素とする要素数13の配列へのポインタ */
int *daytab[13];
/* daytabはintへのポインタを要素とする要素数13の配列 */
char (*(*x())[])(); /* xはcharを返す関数へのポインタの配列へのポインタを返す関数 */
char (*(*x[3])())[5];/* xはcharを要素とする要素数5の配列へのポインタを返す関数
へのポインタを要素とする要素数3の配列 */
出典: "プログラミング言語C 第2版", 共立出版, 149ページ, 2001年.

これらの文に対応する生成規則を考えてみよう!
15