16
コココココ 2012 コ 10 コ 18 コ コココ一@A468 ([email protected] ) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/COMP/ 2012/ index.html 1

コンパイラ 2012 年 10 月 18 日

Embed Size (px)

DESCRIPTION

コンパイラ 2012 年 10 月 18 日. 酒居敬一@A468 ( [email protected] ) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/COMP/2012/index.html. 構文解析. 字句の列を入力とする。 字句の列は字句解析器から出力される。 字句の列として表されたプログラムが、文法のどの部分 に対応するかを解析する。 今回の内容 構文解析の概論 下向き構文解析法の説明 下向き構文解析法の問題点と解決法. 構文解析の役割. - PowerPoint PPT Presentation

Citation preview

Page 2: コンパイラ 2012 年 10 月 18 日

構文解析 字句の列を入力とする。

字句の列は字句解析器から出力される。 字句の列として表されたプログラムが、文法のどの

部分に対応するかを解析する。

今回の内容 構文解析の概論 下向き構文解析法の説明 下向き構文解析法の問題点と解決法

2

Page 3: コンパイラ 2012 年 10 月 18 日

構文解析の役割 プログラミング言語の文法はBNFなどで記述される

。 それに基づいてソースプログラムの字句が解析される

。 字句の列から文法で許される並びであるかどうか調べ

る。 許されなれない並びであればエラーとする。 許される並びであれば、解析木を生成し構文木を出力する

。 さらに変数や関数の名前は名前表に出力する。

3

ソースプログラム 構文解析字句解析

字句出力

字句要求構文木

名前表

Page 4: コンパイラ 2012 年 10 月 18 日

構文規則(生成規則) この例では、乗算は加算よりも

先に行うことを示している。 演算順序を文法で規定している。

非終端記号 式・項・因子・名前

終端記号 a・b・c

→ 左辺の非終端記号を右辺に

書き換え可能であることを示す。

4

【式の構文規則】1.式 → 項|式+項2.項 → 因子|項*因子3.因子 → 名前|(式)

【文法G1】1.式 → 式+項2.式 → 項3.項 → 項*因子4.項 → 因子5.因子 → (式)6.因子 → 名前7.名前 → a|b|c

Page 5: コンパイラ 2012 年 10 月 18 日

構文図式 BNFと記述力は変わらない。 直感的でわかりやすい。

5

要素型 識別子

[ プログラム ]

[ 関数定義 ]

[ 変数宣言 ]

[ ブロック ]

関数定義

変数宣言;

返戻型 ブロック識別子 ( ),

変数宣言

文{ }

Page 6: コンパイラ 2012 年 10 月 18 日

6

[ 文 ]

[ 式 ]

[ 項 ]

return

条件式

ブロック

識別子

変数宣言

;(

=

ifwhile

)関数呼出し

;

条件式 文( )

式 ;

[ 関数呼出し ]

因数

因数 乗除演算子

識別子 式( ),

項 加減演算子

Page 7: コンパイラ 2012 年 10 月 18 日

7

[ 条件式 ]

[ 乗除演算子 ][ 加減演算子 ]

[ 返戻型 ]

[ 識別子 ]

int[ 要素型 ][ 整数 ]数字

数字

英字

英字

式== != > <>= <=

+-

/

要素型

void

[ 数字 ] と [ 英字 ] は非終端記号なので、本来はそれらも終端記号に至るまでの定義が必要。しかし、省略されている。前回のBNFの例でも省略されている。

Page 8: コンパイラ 2012 年 10 月 18 日

式a* ( b+c ) の解析木と構文木

8

因子

名前

a b c( )

因子

因子

因子 名前

名前

* +

解析木構文木

文法解析ではこれらの木を生成する。

解析木では葉に終端記号で末端以外が非終端記号

Page 9: コンパイラ 2012 年 10 月 18 日

構文解析法 一般にはふた通りに分類可能。

上向き構文解析。 解析木を下から生成していく。 右辺と一致する入力列を左辺に置き換える。

下向き構文解析。 解析木を上から生成していく。 生成可能な解析木を仮定し、一致するかどうかで解析をすすめ

る。

9

【文法G1】1.式 → 式+項2.式 → 項3.項 → 項*因子4.項 → 因子5.因子 → (式)6.因子 → 名前7.名前 → a|b|c

Page 10: コンパイラ 2012 年 10 月 18 日

上向き構文解析法

10

因子

名前

a b c

因子因子

名前名前

因子項

+ *

記号列: a+b*c

7を適用: 名前+名前*名前

6を適用: 因子+因子*因子

3,4を適用:

因子+項*因子 ⇒ 項+項*因子 ⇒ 項+項

1,2を適用:

式+項 ⇒ 式

解析木の下のほう、終端記号の非終端記号の置き換えから始まる解析法。

右辺が一致し左辺に置き換えることを還元という。

Page 11: コンパイラ 2012 年 10 月 18 日

下向き構文解析法 解析木を根のほうから生成する。

木の形を仮定して葉に至るかどうかを調べる。 葉に至るまで木が完成しなければ、読み込んだ字句は戻

して別の形を探っていく。別の形が尽きたらエラーになる。 仮定⇔後戻り、を繰り返す。

11

void A(){a を読む ;B(); /* B を読む */c を読む ;

}   直接導出の例

void S(){a を読む ;A(); /* A を読む */b を読む ;d を読む ;

}void A(){

c を読む ;b を読む ;

または/* 解析が失敗して後戻りが発生したら */c を読む ;

}

c|cbAaAbdS

Page 12: コンパイラ 2012 年 10 月 18 日

acbdの解析手順例

最も左にある非終端記号から解析を始めている。 最左導出という。

文法の展開に失敗したら後戻りがある。

12

解析手順 入力記号 文法の適用 解析結果

a c b d S → a A b d1 a c b d a A b d ○

2 c b d A → c b | c3 c b d c b ○

4 d a A b d ×5 c b d A → c b | c6 c b d c ○

7 b d a A b d ○

Page 13: コンパイラ 2012 年 10 月 18 日

下向き構文解析の問題点 再帰的なプログラムで実現できない文法がある。

左再帰性の問題という。 再帰呼び出しが無限ループする。

左辺の非終端記号に対し、右辺に複数の生成規則があるときに、どれを仮定すべきか一意に決まらない。 バックトラック問題という。

前のページの3~6のところ。

13

void 式 (){式 ();+ を読む ;項 ();

}

Page 14: コンパイラ 2012 年 10 月 18 日

問題のある文法。

これを次のように書き換える。

一般には次の形をとるときが問題で、

このように書き換える。

左再帰性の除去

14

|AA

|AAAA

nm ||||A||A|AA 2121

|A||A|AAA||A|AA

21

21

m

n

Page 15: コンパイラ 2012 年 10 月 18 日

バックトラック法で解は求まるが、やはり速いほうがいい。

そこで、共通部分がある場合にくくりだす。

次のように書き換える。

バックトラック

15

c|cbA

|bAAcA

void A(){c を読む ;

b を読む ;   または

/* 解析が失敗してバックトラックが発生したら */何も読まない ;

}

Page 16: コンパイラ 2012 年 10 月 18 日

    を    に置き換えて解析。

16

解析手順 入力記号 文法の適用 解析結果

a c b d S → a A b d1 a c b d a A b d ○

2 c b d A → c A'3 c b d c A' ○

4 b d A' → b |ε5 b d b ○

6 d a A b d ×7 b d A' → b |ε8 b d a A b d ○

nm |||||||A 2121

m

n

|||A||||AA

21

21

c|cbAaAbdS

|bAAcAaAbdS

の形の場合、

という形に文法を変形する。バックトラックがなくなるわけではない。