湯淺太一 - yuasa.kuis.kyoto-u.ac.jpyuasa/shokodo/ocw.pdf · 文字列の計算...
TRANSCRIPT
コンパイラ
湯淺太一
�
講義資料のダウンロード
����
�������������� ������������������������ ��
「コンパイラ」講義資料(パスワードが必要)
ユーザー名:
��������
パスワード:
�������
「コンパイラ」講義資料
�� ����� 版
��� ��!��
�"#
版
��� ��!��
�
第1章
コンパイラの概要
�
Cコンパイラ
実行形式
プログラム
Cコンパイラ
プリプロセッサ
アセンブラ
リンカー
ヘッダファイル
ライブラリ
ソースファイル
ソースプログラム
前処理済み
ソースプログラム
前処理済みファイル
アセンブリ
プログラム
アセンブリファイル
オブジェクトファイル
オブジェクト
プログラム
他のオブジェクト
ファイル
�
コード生成例
�������������
�������
��� ����
��
���������
���
�
���
�������
�
���
�����
�
���
���� !���"
#
���$
���� !���"
%
���
&�!���"����
'
���
����&�!���"
�((
�����
)
���
�������
�*
���
���
��
��
ボトム
上位番地
下位番地
実引数
戻り番地
esp
ebp
xy
�
機械語コード
*�*�*�*��***�**����**�*��*****��
���*��*******�**�***�*��*�**��*�
****�*******�����*�*����*�**��*�
****�***�***�**�*�**��*�������**
�***�*��*�*�*�*�������**�*****��
��****�*******�*�***�**���*�****
��**�**���****��
�
*�*�*�*�
�
�***�**����**�*�
�
�*****�����*��*******�**
�
�***�*��*�**��*�****�***
#
****�����*�*����*�**��*�****�***
%
�***�**�*�**��*�������**
'
�***�*��*�*�*�*�������**
�*****����****�*******�*
)
�***�**���*�****
�*
��**�**�
��
��****��
�
���
命令
�***�**�������
��� �� �� �
レジスタ
������
からレジスタ
� �� �� �
へ移動する.
�***�*��*�����
��� �� �� �� �� �� �� �� �� �� �� �
レジスタ
� �� �� �
の指す位置から相対的に
� �� �� �� �� �� �� �� �
番地の位置にあるデータを,レジスタ
������
へ移動す
る.
�***�**�*�����
��� �� �� �� �� �� �� �� �� �� �� �
レジスタ
� �� �� �
の指す位置から相対的に
� �� �� �� �� �� �� �� �
番地の位置へ,
レジスタ
������
のデータを移動する.
�
$%&%
形式
�
���������$+���
�
���$
+����+���
�
���$
,��+���
�
���$
�+�����+���
#
���$$ �+�����+���
%
���$
+����&��+����
'
���$
&��+�����+���
�(($
,��+���
)
���$
+����+���
�*
���$
+���
��
��
�
コンパイラとは
ソース言語から目的言語への変換
クロスコンパイル
クロスコンパイ
ラのソースコード
入力ファイル
出力ファイル
クロスコンパイラ
Cコンパイラ
計算機
X
計算機
M
X 用ソフトウェ
アのソースコード
X 用ソフトウェア
ブートストラップ
ソースファイル
オブジェクトファイル
クロスコンパイラ
Cコンパイラ
X用Cコンパイラ
クロスコンパイ
ラのソースコード
計算機
X
計算機
M
X 用コンパイラ
�
コンパイラの構造
��
字句解析
�
構文解析
'�
意味解析
!�
コード生成
字句解析
字句要素を切り出して,トークン列を生成.
(
言語の字句要素
��
識別子
�
キーワード
'�
定数(整数定数,浮動小数点定数,文字定数)
!�
文字列リテラル
)�
演算子
*�
区切り記号
���
���
�
���
�
�
�
���
�
�
�
�
��� �
�
�
�
�
�
構文解析
文法をチェックし,構文木を生成.
*+
x
x
y
xy
2
関数定義
指定子リスト
パラメータリスト
複合文
宣言リスト
文リスト
指定子リスト
パラメータ
retu
rn
int
int
int
foo
変数宣言
必要な情報のみ保持
���
条件
�
文
��$��
文
if s 1s 2
e
��
意味解析
*+
x
x
y
xy
2
関数定義
指定子リスト
パラメータリスト
複合文
宣言リスト
文リスト
指定子リスト
パラメータ
retu
rn
int
int
int
foo
変数宣言
コード生成
局所変数等の割り付け
最適化
�
��������
�����!���"
�
���$�������
�
�((
�����
�
��
��
第2章
字 句 解 析
��
文字列の計算
アルファベット:言語を構成する文字の(有限)集合
文字列
�
文字の並び
空の文字列
�
文字を一つも含まない文字列
�
文字列の連結
���
例:
����-+���-
結合則
��,���-+,���-��
が成り立つ
�
�����
と書いてよい
�
���
と略記することもある
文字列のべき乗
��+�
��+���
��
�
,�+�� �'�-
公式 ��
+����+���+�
���+�����
��
文字列集合の連結
��+������������
例:
����-�����-�+�����-��-���--�
結合則
�,���-+,��-��
が成り立つ
�
����
と書いてよい
�
��
と略記することがある
文字列集合のべき乗
�+���
�+�
��
�+������
�
��
�
�
,�+�� �'�-
例:
+����-�
のとき
�+��+��������-���-����-�-��-����-��-��-�-���-�-�-�
公式
�+�
�+����+
��+
��
�+
�
�
��
�
�������
�
�
��
�
������
�
��
�
��
���
と空集合
����+����+
�+� +
��
文字列集合の正の閉包
,��� �.�������-
+
��
��
�����+
� � ��
�
例: �
��
+����������������
�����+����������������������
文字列集合の閉包
,������-
�+����
+
��
��
��
�����+
� � ��
�
例: �
���+������������������
公式
��+��+
��
+
��+
���+�
例:C言語における
�/
進定数
���������#�%�'� �)���*���������#�%�'� �)��
��
正規表現
アルファベット
0+�����������
上の正規表現
���
���
,���0-
'�� ����
(
� ����
は正規表現)
!�� ����(
� ����
は正規表現)
)���
(
�
は正規表現)
�,�-:
正規表現
�
が表す文字列集合
�,�-+���
�,��-+����
�,�����-+�,��-��,��-
�,�����-+�,��-��,��-
�,��-+�,�-�
例:
��,,���-�-は
,
�����
上の正規表現.
�,���-�
と略記
�,�,���-�-
+�,�-��,,���-�-+�,�-�,�,���--�+�,�-�,�,�-��,�--�+����,�������-�
+����������+����������������������������
+�������������������������������
��
正規表現
�
の解釈
���
:
�
が省略可能
��:
��
自体
� ����:
� �
または
� �
� ��� �
:
� �
のあとに
� �
��
:
�
が
/
個以上
略記法
� ���+���
�+����
C言語の字句要素
識別子
��,���-�
キーワード
������� ��.�-����-�� ����
演算子
���/�������
区切り記号
������������
�/
進定数
�,������)-���オ
プション
浮動小数点定数
�,,�0���0�-�
指数部
�����
�
指数部
-,1���2�$- ���
文字定数
�2���3,�
文字
��と
3
と改行以外
-3
ここで,
�+
���������4�5�6�����7
�+*���������)
�オプション
+,,8��-,2�$- ����,2�$-,8��- ���-���
�
指数部
+,9��-&����
��
有限オートマトン
��������������
有限個の状態を持ち,文字を1文字ずつ読み込むことによって,自分自身
の状態を変化させる,一種の仮想計算機
#$
は五つ組
�0���1����で
定義
0�
アルファベット
��
状態全体の集合
1�
状態遷移
��������の
集合
状態
� �
で
�
を読んだら状態
� �
に遷移
��
初期状態
,���-
��
受理状態の集合
,���-
状態遷移図
2�+�0���� �'�!�������� �� ���'��'���!�����!�
in
t2
13
4
2 +�0���� �������� �� ��� ����� �
2
ba
1
��
�
+�0���1�����#$
�+����������
入力文字列
次の条件を満たす状態列
� ��������
が存在するとき,
�
は
�
を受理
,����� -
する.
�+� �
��
��
� ���
��
���
��
��
� ���
�,�-��
が受理する文字列全体
�
�
が受理する言語
,���3��3�-
例:
�,2�-+�����
in
t2
13
4
�,2 -+����������������+�,���-
2
ba
1
�,�-+�,��-の
とき,
�と
��
は等価
,�4��.���� -
�
決定性
��������� ���
有限オートマトン
任意の
���
と
��0
に対して,
�������の
形の状態遷移が高々一つ
"#$�0���1����の
状態遷移関数
�,���-+
� � � � � � � � ���,��������1
のとき
-
, その他の場合
-
�
が与えられれば,
1+�������,���-�������0��,���-�+ �
"#$
を
�0��������と
表記することがある.
適用例
,�-:
受理するかどうかの判定
入力文字列
����������
����
� ,
��
�
����
かつ
�,����-�+
ならば,
��
�,����-
,
��
�5�
とし,このステップ
を繰り返す.
'����
かつ
���
であれば
��と
表示し,そうでなければ
��
と表示する.
��
適用例
, -:
文字列の切り出し
入力文字列
����������
����
/ ,
��
/,
��
�(初期状態)
����
であれば,
��
�
'���
�5�
!��,����-�+
なら,
��
�,����-
とし,ステップ
へ戻る.そうでなければ,
�
の値を返す.
例:
2
b a1
入力文字列が
�����
のとき
�
���
����
���
�
���
����
���
�
���
��
非決定性有限オートマトン
�
遷移
�������
εq
q’
状態
�
に達したときに,入力文字列と無関係に,
��
へ遷移してよい.
�
に留まってもよい.
非決定性
,����� ������ ��-
有限オートマトン
,6#$-
次のいずれかを満たす
#$�0���1����
��1
が
�
遷移を含む.
�
ある
���
と
��0
に対して,
�������の
形の状態遷移が,
1
の中に複数存在
する.
例
2!+�0���� �'�������� �� ���'�� ���'�����'�
2)+�0���� �'�!�������� �� ���'������!�����'�!�
2
ba
13
ε
ba
1
23
a4
��
次の条件をすべて満たす経路
� ���
��
� ���
��
���
��
��
� �
が存在するとき,
6#$�0���1����は
,文字列
�+���������
を受理する.
��� �+�
����������� ��1,�+�� ���-
'����������
から
�
を除去すると
�
と一致する.
!�� ���
例
� �,:�-+������
�
に対して
��
���
���
'
��
に対して
��
���
���
'
2
ba
13
ε
�,:#-+������
�
に対して
��
���
!
��
に対して
��
���
���
'
ba
1
23
a4
��
正規表現から
���
への変換
�:正規表現
�
:
#$
�,�-+�,�- の
とき,
�
と
�
は等価
正規表現
�
を,等価な
"#$
に変換
���
を,等価な
6#$
に変換
�6#$
を,等価な
"#$
に変換
'�"#$
を,状態数最小の等価な
"#$
に変換
��
正規表現から
���
への変換
�,�-�
正規表現
�
に対する標準形
6#$
sf
( )
Mr
��
初期状態への遷移は存在しない
�
受理状態は一つだけ
'�
受理状態からの遷移は存在しない
��
,�-�,�-
εs
f
, -�,��-
sf
ia
,'-�,�����-
εεε ε
fs
2f2s
1f1s
( )
M1r ( )
M2r
,!-�,�����-
ε2f
2s1f
1s( )
M1r
( )
M2r
,)-�,�� �-
ε
ε
εf
s1f
1s( )
M1r
��
例:
�,,���-���-
,�-�,�-と
�,�-
ab
, -�,���-
a b
εε
εε
,'-�,,���-�-
ε
εa b
εε
εε
ε
,!-�,,���-���-
a
ε
εa b
εε
εε
ε
bε
ε
s1
23
f
5
6
4
78
910
��
���
から
���
への変換
a
ε
εa b
εε
εε
ε
bε
ε8
910
7
s1
2 453
6
a
ε
εa b
εε
εε
ε
bε
ε8
910
7
s1
2 453
6
a
ε
εa b
εε
εε
ε
bε
ε8
910
7
s1
2 453
6
a
ε
εa b
εε
εε
ε
bε
ε8
910
7
s1
2 453
6
f
f f
f
a
aa
a
b
bb
b
ab
ab
b
aa b
��
状態数最小の
���
21
ab
ab
baa
3
b
4
21,3
ab
b
aa
b
4
アルゴリズム
��
受理状態とその他の2グループに分ける.
�
同一文字に対する遷移先が異なる状態を,別グループに分ける.
21
ab
ab
baa
3
b
42
1a
b
ab
baa
3
b
4�
字句解析プログラム
正規表現以外の規則
��
最も長い字句要素を切り出す.
例
���-+�5�-+��5-
�
字句要素の種類ごとに優先度を設ける.
例
���
は識別子ではなく,キーワード �
�
字句構造全体の
���
� ���������
字句要素の種類ごとの正規表現
� �����������
の
"#$
では種類がわからない
����������
種類ごとのマーカ
�
各受理状態に適切なマーカをつける
��
種類ごとに
6#$�,��-
を求め,受理状態にマーカをつける
im
isif
( ) ir
M
�
新しい初期状態
�
を用意し,全体の
6#$����
を作成.
ε ε
1s( )
M1r
1f
s
nf( ) nr
Mm
nns
1m
'�����
を
"#$
����
に変換.
個々の受理状態には,優先度最大のマーカを残す.
!�
状態数最小の
"#$
を作成.
ただし,マーカの異なる受理状態は別グループ.
��
例
��
キーワード
���
�
識別子
��
英字
�
英数字
�
'�
空白
��
スペース
fi
1
英字
εε
ε
スペース
スペース
3
2
英数字
i
スペース
英数字
f2
1
2英数字
スペース
3
f 以外の
英数字
i 以外の英字
��
状態遷移表
状態遷移関数
����0�
��� �
を表にしたもの
ma
1a1q nqiq
ja
δ(
,
)
iqj
a
ほとんどの要素が
(未定義)
��
状態遷移表の圧縮
Ent
ryV
alid
atio
n
a
1q nqq
δ(
)
q, a
q
Nex
t
;�$�(�����!9�� !�"��"+
� � � � � � � � ��
,�,���-�+ -
�
以外
,�,���-+ -
�����������<����
����9�� !<"���
���;�$�(�����!�"<�
��� �=���!�"�
�$��
��� �8=>91?=9>�
�
��
各ベクタの設定方法
ab
b
aa
b
31
2
0 4
Nex
tV
alid
atio
n
97 98 99 100
101
102
2 1 2 3 2 1
1 1 2 2 3 3
21
2
3
1
2 1
2 3
97 98
131
0
127
Ent
ry
1 2 3
0 2 42
$�(77
コードでは,
3�3+89
,3�3+8:
��
字句要素の切り出し
関数
�-���
最も長い字句要素を切り出して
����
に格納し,マーカの値を返す.入
力の終りに達していれば,
9=>@11?29
を返す.
0
buf
tom
ark
end
from
cyy
text
ソースファイル
����!*"
~
���!��&�"�
これまでに読み込んだ文字列
����!*"
~
���!�� .&�"�
最も長い字句要素
����!� ��"
~
���!��(&�"�
前回読み込みすぎた文字列
��
0
buf
tom
ark
end
from
cyy
text
ソースファイル
-
への文字設定
�(���-��-���
���!����"-�
���� ��A��(�
-���!� ����"�
�$��
-B��-�����
�
バッファの初期化
�����������
�� .��� ����(*�
-B��-�����
�
��
字句要素の切り出し
-������$��������
�� ��*��A�� .�����
����!�"���!�"�
����!�"3C*3�
����� .A����
���!����"-�
D��$��� ��A��(�
���!����"���!� ����"�
-���!�� .��"�
� ���� .�
��(���
� �� .��*�
�
その他のサブ関数
����������������
状態遷移関数
�,���-の値
����$����
状態
�
が受理状態かどうか
�� .� ����
受理状態
�のマーカ
�� .��������
の値を
�� .
に保存
��
�-�����
���-9@1� ��� �9=>@11?29�
<��
<�8=>91?=9>�
�� �����
�������$�<���
�� .�������
<�<�
� ����������������<�-��E8=>91?=9>��
<��
�(���-��-���
��$�����<�E8=>91?=9>��
-������$��������
��� ��� .� �<���
��$���
$���-�$�� � ���
���-9@1� ��� �9=>@11?29�
<��
��
�
�
エラーリカバリ(次の空白まで読み飛ばす)
$���-�$�� � ���
D��$��-E33//-E3C�3//-E9@1�
�(���-��-���
�� .�������
-������$��������
� �����F$���-�$� � �3+�3C�F�������
�
��
字句解析の自動化
���
と
;��
+-���-��0$
++
!C�"���
��G������� �����F+��@H0C�F��������
0�� �����F+��D ��B0C�F��������
++
+$���-��0$
+--$��00-&$$
+�0���
������
�������@H0
���
���@H0
��D ��B0
+
��
+-���-���0$
++
!C�"���
F�FGF&FGF�FGFIFGFF
� �����F+����� ��� �F�������
F�F
� �����F+������ ��� �F�������
!�&4"!�&4*&)"�
� �����F+���(������� �F�������
!*&)C0"��� �����F+������� �F��������
0
� �����F+��(��3�.��D�F�������
++
+$���-���0$
+--$��00-&$$
+�0���
��-���0�����-I�
��-��(������� ����� ��� ����(������� �
����� ��� ��0�������� ������ ��� �
��-��(������� �I���� ��� ����(������� �
��
���
から正規表現への変換
"#$�
+�0��� ����������������
�� ���� �
から
� �
へ,
� ��������
だけを通過して遷移させる文字列全体の集合
� ��
� �
~
� ��
� �
����/
のとき
�� ��+�
��
�
��
,���
�
��
-��
��
�
��
��
��
�
��
� ��
� �
~
� ��
��
� ��
����
� ��
� �
~
� ��
��
� �
� ��
� �
~
� ��
��
� �
��+/
のとき
�� ��+
� � � � � � � � �����,����-+� ��
,��+�
のとき
-
����,����-+� ������,�+�
のとき
-
���
の状態数
�,�-+
��
�� �
この集合式を正規表現に変換する
iq1q
kq
jqk-
1q
��
例
ab
b
aa
b
31
2
�� ��+�
� ��,�
� ��-��
� ����
� ��+�
� ��,�
� ��-��
� ��+�
� ��,�
� ��-�
�� ��+�
� ��,�
� ��-��
� ����
� ��
�� ��+�
� ��,�
� ��-��
� ����
� ��
�� ��+�
� ��,�
� ��-��
� ����
� ��+,�
� ��-�
� ����
� ��
+,�
� ��-��
� ��+���������+�������
�� ��+�
� ��,�
� ��-��
� ����
� ��+ ������+�����
�� ��+�
� ��,�
� ��-��
� ����
� ��+ ����+���
�� ��+�
� ��,�
� ��-��
� ����
� ��+
�� ��+�
� ��,�
� ��-��
� ����
� ��+��������������+�������
�� ��+�
� ��,�
� ��-��
� ����
� ��+������� ����+���
�� ��+�
� ��,�
� ��-�
+,����������������-,����������������-�
+,�������
���-,�������
���-�
+,�������
���-
"#$
と等価な正規表現は,
,���
�-
��
例:コメントの正規表現
/5
34
21
/
*以外の文字
*と
/ 以外の文字
**
*
I���
以外の文字
��
,��
と
I
以外の文字
��
以外の文字
����-�I
状態番号の
'
と
!
を入れ替えると
I�,��
以外の文字
�,�-��
と
I
以外の文字
-�,�-��I
��
正規表現の限界
正規表現では表せない文字列集合の例
�+��
� ������/�
正規表現
�
で表せたと仮定する
���,�-の状態数
����
�,��-を
受理する
�,�-の
経路
� �� �
���
� �
�
��
�
�
� �� �
� ��
�
���
�
�
��
�
�
� ���
� �+� �
なる
���,/������-が
存在する
� �� �
���
� �
�
��
�
�
� �� �
���
� �
�
��
�
��
�
� �� �
���
� �
�
��
�
��
�
� �
���
� ��
�
���
�
�
��
�
�
� ���
� �
から
� �
への経路をカットすると
� �� �
���
� �
�
��
�
�
� �,+� �-
� �
���
� �
�
��
�
��
�
� �
���
� ��
�
���
�
�
��
�
�
� ���
�,�- は
���
���
����
�, ��-も
受理する
�
矛盾
文脈自由文法なら
�
����
��
第3章
文 法
��
構文,制約,意味
構文
,�� ��-
:プログラムの構造を定義
制約
,��� ���� -
:構文以外の規則
意味
,���� ��-:
実行を定義
例:
�<
文構文:
������������ ��$������ �
制約:
����
は真偽値を表す型
意味:
����
を計算し,その値が真なら
���� �
を,
偽なら
���� �
を実行する
文法:構文+制約
構文解析は「文法解析」ではない.
構文解析の話をするときは,制約には言及しない.
�
構文=文法
��
構文の記法
$�=>�*/
の
?6#
����3�����
� �B ������� �@�������� �@����� ���A���0
�� �B ������� �@����A���0
����� �@��
は非終端記号
,��� ���������A��-あ
るいは構文変数
,�� ��.����A��-
� �B ��
は,終端記号
, ���������A��-
����� �@����� ������� �@�������� �@����� ������ �@��
識別子リストとは
�
��
識別子であるか,
�
識別子リストと識別子をカンマで区切ったもの
例:
B���4C
���
は識別子なので識別子リスト
��
が識別子リストなので
B��C
も識別子リスト
'�B��C
が識別子リストなので,
B���4C
は識別子リスト
生成規則
,������ ���-
��
と縦棒は,メタ記号
,�� ����A��-
�
拡張
?6#
の例:
����� �@����� �������� �@��������� �@��
C言語の構文記法:
�������� ����
�������
�������� �����������
�� ����� �������� �������� ��������
����� の
構文図式
,�� �����3���-の
例:
prog
ram
iden
tifie
r
,
()
;bl
ock
.id
entif
ier
prog
ram
��
文法
生成規則:
�
�
,
は記号,
�
は記号列
-
�
規則:
�
�
文法:組
�!�"
!
:生成規則の集合
"
:出発記号
, �� ��A��-
語彙
,.���A�����-#
:
!
に現れる記号全体の集合
非終端記号
#�
:生成規則の左辺に現れる記号
終端記号
#�
:非終端記号以外の記号
#+#�
�#�
#�
�#�
+
"�#�
例:文法
=�+
����$+
�#��#�����$
��+�$�
$�%
$�
%
%�
%��
%�
�
��
�$�
��
��
#�
+�$���%�
#�
+�����������
#+#�
�#�
+�$���%�����������
��+�$�
$�%�%
%�
%����
��
�$����
��
&+��
,
'+���
,
�
��!
のとき,
&�
'
&
は
'
を直接生成する.
'
は
&
に直接還元される.
Ax
yv
wx
yα
&�
���
������
���
'
のとき,
&� �
'
&� �
'
または
&+'
のとき,
&� �
'
&
は
'
を生成
,�������-す
る.
'
は
&
に還元
,������-される.
v w
"� �
�
のとき,
�
は
(
の文形式
,�� �� ���<���-
特に
�
が終端記号列なら
�
は
(
の文
,�� ����-
�,(-:
(
の文全体の集合,
(
の定義する言語
例:
��+�$�
$�%�%
%�
%����
��
�$����
$�
$�%�
%�%�
%�%���
��%��
�
��%���
������
������
�����
�����だ
けが文
��
導出
,����.� ���-:
&
から
&� �
'
である記号列
'
を求めること
最左
,��< ��� -
導出
$� ��
$�%� ��
%�%� ��
��%� ��
��%� ��
��%��
� ��
������ ��
������ ��
�����
最右
,��3� ��� -
導出
$� ��
$�%� ��
$�%��� ��
$�%��� ��
$����
� ��
$����� ��
%����� ��
������ ��
�����
E T F i
E +T *
T F i
F i
��
解析木とあいまい性
解析木
構文木
E T F i
E +T *
T F i
F i
i
+
i
i*
あいまいな文:二つの異なる解析木が考えられる文
あいまいな文法:あいまいな文を生成する文法
例:文法
= +�� �$,
� +�$�
$�$�$�$��$����
文
�����に
対する二つの解析木
+
*
ii
E
E
iE
E
E
E
E
+
*
i
E
EE i
i
��
あいまいな英文
%���;���
「主語+動詞」
�
「光陰矢の如し」
「動詞+目的語」
�
「蝿の速度計測をしろ」
あいまいな日本語文
ここではきものをぬぎなさい
「ここで履物を脱ぎなさい」
��
「ここでは着物を脱ぎなさい」?
��
�<
文の構文
����� �
�����������
�������������$������
�����
あいまいな
�<
文
���) �����) ��� ��$��� �
���) ������) ��� ��$��� ��
���) ������) ��� ���$��� �
e 2e 2
e 1
expr
)st
atst
at(
)ex
pr(
stat
expr
)st
atst
at(
)ex
pr(
stat
stat
stat
ifel
se
ifif
if
else
e 1s 2
s 1s 1
s 2
C言語の場合は左側
��
�<
文のあいまい性除去
開いた(
����
)文:直後に「
�$��
+文」をつけても
文になり得る文
閉じた(
�����
)文:
����
でない文
����� �
��������
��������
� ���������
��������� ���������$��� ��������
�����
���������
������������
��������� ���������$����������
��
演算子の優先順位と結合性
演算子の優先順位
����*+�����*�
演算子の結合性
�&�&*+��&��&*
なので左結合的
,��< ����� �.�-
��*+���*�
なので右結合的
優先順位と結合性
���&*+�����&*
��
��������:
���������������� の
とき
���
を先に計算
��
生成規則
�
����������が
存在
�
ある非終端記号
�
に対して
�
� �
�������
��������:
����������������の
とき
���
を先に計算
��
生成規則
�
����������が
存在
�
ある非終端記号
�
に対して
�
� �
�������
+
*
A B
C
A +
*
B
C �
例:文法
=�
��$�
$�%
が存在し,
�$�
$�%
�
����
��$�
$�%
が存在し
�%�
%��
�
����
��$�
$�%
が存在し,
�$�
%�
%��
�
����
����
かつ
����
なので,
�
は
�
より優先順位が高い.
+
*F
T
TE
E
+ TE
E
E
T
+
+E
E
T
*F
T
T
��
文脈自由文法とその限界
が文形式に現れていれば,
の前後(文脈)に
関係なく,
を左辺とする生成規則を適用可能
文脈自由文法で表現できない記号列集合
++��
����������+�����������������������
�,(-++
なる文脈自由文法
(
が存在したと仮定
次の
������
が存在する.
"� �
��� �
��&�� �
������
(
が生成する記号列
"� �
��� �
��&�� �
���&&�� �
������'&�&���
は,
+
の要素でない.
�
矛盾
A A
xy
u
x’
v
y’u
’v’
w A A
xy
u
x’
v
y’u
’v’
wAu
v
u’
v’
S S
��
+
を生成する文脈自由でない文法
"�
����
��
������
���
��
���
��
"�
�����
��������
����������
�
����������
����������
���������
�
����������
����������
���������
��
第4章
構 文 解 析
��
構文木とその表現
6
組
,6� ����-
���-��(&��
a=
+
de
bc
*-
=
+
e
*
c
a
bd
-
���$�
:
6
組へのポインタの型
��.��
:トークンへのポインタの型
���$�
型は,
��.��
型を含む.
6
組の生成
����.�����$��F�F������
����.�����$��F&F�,�)��
����.�����$��F�F��������
����.�����$��FF�������
トークンの種類判定
����������
��
再帰的下向き
������ ����� ����構
文解析法
解析関数
,�����3<��� ���-
�
����
p a 1a 2
c 1b 2
b 1$
���$��� ���5���
��.���� ������4����$��
��������������//��� ���5���
//�����4������
��� ���.�����$��F5F����4��
�� ���
������-�������� ��� ���
�� ���
��� �=822�
�
D
は特殊な終端記号と見なす.
生成規則は再帰的
�
再帰的な解析関数群
��
入力トークン列全体の解析
���$��� �����
���$���� ���5���
����//�����������
��� ���
�$��
������� � ���
�
再帰的下向き構文解析法の問題点
左再帰
,��< ��������-
バックトラック
,A�� �����3-
��
左再帰
文法が左再帰を含む
�
解析関数の再帰呼出しが止らない.
=�
の生成規則:
$�
$�%�%
直接の左再帰
,������� ���< ��������-
���$��� ���9���
��.���� �������$����
������� ���9���//����$��������
//��� ���J����
��� ���.�����$��F�F�����
�� ���
������ ���J��� ��� ���
�� ���
��� �=822�
�
間接的な左再帰
�
����
��
��,
��
C言語における左再帰
�������� ����
�������
�������� �����������
右再帰に置き換え可能.
�������� ����
�������
���������������� ���
単純に右再帰に置き換えられない例
�����������������
�� ��� �����������������
������������������� ��� �����������������
����������������&�� ��� �����������������
左結合的が右結合的になってしまう.
�&��-+��&���-�+�&���-�+�&�&-
(
言語の文法には,間接的な左再帰は存在しない.
��
「直接の左再帰」の除去
�
���
� ��
�� ��
��� ��
���� ��
���� ��
�
�� ��
���
�
��
��
����
� ��
��� ��
���� ��
����� ��
���� ��
����� ��
���
���$��� ���5���
��.���� �����
�������������� ��� ��� ���5����
�� ���
��� �=822�
� ���$��� ���5�����$����
��.���� �����
��������������
��� ��� ���5����.�����$��F5F������
�� ���
��� ���
�
aA a
aAA
a
bAA
ε
AA
’A
’
A’
ba
a
aA
’
�
一般の場合
�
����������-������-�
ここで
-��#�
,
-�
は
で始まらない.
���#
�
-�������-��
��
�������������
例:
=�
の生成規則
$�
$�%�%
%�
%����
��
�$���
から左再帰を除去した文法
='
$�
%$�
$��
�%$���
%�
�%�
%��
��%���
��
�$���
��
バックトラック
複数の選択肢があるとき,その一つを試してみて,
失敗だったらもとの状態に戻してやり直す.
例
�
���
��
���,
���$��� ���5���
��.���� ������4����$��
��������������//��� ���6���
//���-�4������
��� ���.�����$��F5F����4��
�� ���
��� �=822�
� ���$��� ���6���
��.���� �������
��������������� ��� ���
�� ���
��������������//���(�������
��� ���.�����$��F6F�����
�� ���
��� �=822�
�
正しく動作しない(例:
��,�)
�
一般的には複雑な機構が必要
��
くくり出し
,<�� ����3-
によるバックトラックの回避
数学では「
��5��
の
�
をくくり出して
�,�5�-」
��
���,
の
�
をくくり出す.
��
�,,��-
���$��� ���6���
��.���� ������
����������������
��.���� ������
������(�������
��� ���.�����$��F6F�����
�� ����
��� ���
� �� ���
��� �=822�
�
生成規則が終端記号で始まらない場合は適用が困難.
�
���
��
��.
��
���
.�
���
バックトラックのもう一つの大きな問題:
適切なエラーメッセージ出力が難しい �
�
����構
文解析法
�
個のトークンを先読みし,どの生成規則を適用するかを決定する
��
��.
の解析関数で,
次の入力トークン
�
を先読みし,
��
もし
�
�
����な
ら
�� ���K
を呼び出す.
�
もし
.
�
����な
ら
�� ���>
を呼び出す.
'�
どちらでもなければ構文エラー
��
����文
法
文法
(+�#��#��!�"
#�� ,�-:
記号列
�
の
@�
集合
#�� ,�-+�����#���� �
�����
#�����,- :
非終端記号
の
<�����
集合
#�����,-+�����#��"D� �
��������
D�#�����,-な
ら,
"
� �
���
常に,
D�#�����,"-
S A
a
α
a
��
"���� ��,��-:
生成規則
�
�
の
����� ��集
合
"���� ��,��-+
� � � � � � � � �#�� ,�-
,�� �
�
でない
-
#�� ,�-�#�����,-,�� �
�
のとき
-
�
�
で還元するときに,入力トークン列の先頭に現れる可能性のある終端記
号の全体
S
α
a
AA
$
α
a
��,�-文
法:右辺だけが異なる任意の生成規則
�
�
と
�
-
に対して
必ず "
���� ��,��-�"���� ��,�--+
が成り立つ文法
��
����文
法のための計算
記号列
�
が
�
を生成する(
�� �
�
)かどうかの判定
�+�
なら
�� �
�
�+����������+�
なら
�� �
�
は,
すべての
��
に対して
��
� �
�
と同値
6���,�-:
記号
�
に対して
�� �
�
かどうか
6���,�-+
� � � � � � � � � ���,�� �
�
のとき
-
<���,�� �
�
でないとき
-
��
すべての記号
�
に対して
6���,�-�
<���
��
規則
�
�
に対して,
6���,-�
���
'��
規則以外の生成規則
�
�������に対して,
すべての
��
について
6���,��-+ ���な
らば,
6���,-�
���
!�
変更がなくなるまで,ステップ
'
を繰り返す.
��
例:
=�
から左再帰を除去した文法
='
$�
%$�
$��
�%$���
%�
�%�
%��
��%���
��
�$���
6���,$�-+6���,%�-+ ���
6���,$-+6���,%-+6���,�-+<���
��
@�
集合の計算
�+�
なら
#�� ,�-+
�+����������+�
に対しては,
#�� ,�-+
� � � � � � � � �#�� ,��-
,��
� �
�
でない
-
#�� ,��-�#�� ,�������-,��
� �
�
のとき
-
�
記号についての
@�
集合から求められる.
��
終端記号
�
に対して
#�� ,�-�
���
非終端記号
に対して,
#�� ,-�
�
生成規則
�
�����,��,#�
�#�--
に対して,
��
� �
�
なら
#�� ,-�
#�� ,-�#�� ,�-
'�
変更がなくなるまで,ステップ
を繰り返す.
��
例:文法
='
の
@�
集合
$�
%$�
$��
�%$���
%�
�%�
%��
��%���
��
�$���
生成規則
��
�$�
と
��
�から
#�� ,�-+�����
生成規則
%��
��%�
から
#�� ,%�-+���
%�
�%�
から(
6���,�-+<���な
ので)
#�� ,%-+#�� ,�-+�����
#�� ,%�- ,
#�� ,%-と
同様に,
#�� ,$�-+���
#�� ,$-+#�� ,%-+�����
�
<�����
集合の計算
��
出発記号
"
に対して
#�����,"-�
�D�
"
以外の非終端記号
に対して
#�����,-�
�
生成規則
�
����,��#�-に
対して,
#�����,�-�
#�����,�-�#�����,-
'�
生成規則
�
�����,��#����+�-
に対して,
#�����,�-�
#�����,�-�#�� ,�-
もし
�� �
�
なら,さらに
#�����,�-�
#�����,�-�#�����,-
!�
変更がなくなるまでステップ
と
'
を繰り返す.
S A
B
S A Bα
��
例:文法
='
の
<�����
集合
$�
%$�
$��
�%$���
%�
�%�
%��
��%���
��
�$���
出発記号
$
が右辺に現れる規則は
��
�$�
だけ
#�����,$-+�D���
$�
が右辺に現れる生成規則は
$�
%$�
と
$��
�%$�
#�����,$�-+#�����,$-+�D���
%
が右辺に現れる生成規則も
$�
%$�
と$��
�%$�
%
の直後は
$�
,
6���,$�-+ ���な
ので,
#�����,%-+#�� ,$�-�#�����,$�-+���D���
#�����,$�-,
#�����,%-と
同様に,
#�����,%�-+#�����,%-+���D���
#�����,�-+#�� ,%�-�#�����,%�-+�����D���
��
文法
='
における
����� ��集
合
$�
%$�
$��
�%$���
%�
�%�
%��
��%���
��
�$���
6���,$�-+6���,%�-+ ���
6���,$-+6���,%-+6���,�-+<���
#�� ,$-+#�� ,%-+#�� ,�-+�����
#�� ,%�-+���
#�� ,$�-+���
#�����,$-+#�����,$�-+�D���
#�����,%-+#�����,%�-+���D���
#�����,�-+#�� ,%�-�#�����,%�-+�����D���
"���� ��,$���%$�-+���
"���� ��,$���-+#�� ,�-�#�����,$�-+�D���
"���� ��,%����%�-+���
"���� ��,%���-+#�� ,�-�#�����,%�-+���D���
"���� ��,���$�-+���
"���� ��,���-+���
"���� ��,$���%$�-�"���� ��,$���-+
"���� ��,%����%�-�"���� ��,%���-+
"���� ��,���$�-�"���� ��,���-+
='
は
��,�-文
法である.
��
����構
文解析法
,��< � ����3� ������3E��< ��� ����.� ���-
バックトラックのない再帰的下向き構文解析
='
のための解析関数
���$��� ���9���
������$�� ����
GG����������
���$���� ���J���
��� ��� ���9�����
��$��
������� � ���
�
���$��� ���9�����$����
�������$��������
���$��
����
�� ���J���
��� ��� ���9����.�����$��F�F������
��$���������������GG��� �� �����
��� ���
�$��
������� � ���
�
バックトラックがなくなったので
��
適切な時点で構文エラーを検出できる
��
の値を保存しておく必要がない.
��
��
構文解析
,��< � ����3� ������3E��3� ��� ����.� �������.���-
文法
��$�
$������$
における
�����
の最右導出
$� ��
$��� ��
$����� ��
�����
注目点挿入
$
・
� ��
$�� ・
/
$�・
�/
$
・
��
� ��
$��・
��/
$�・
���/
$
・
����
� ��
� ・
����/
・
�����
�����D
の
��
構文解析
・
�����D�
�・
����D�
$
・
����D�
$�・
���D�
$��・
��D�
$
・
��D
�
$� ・
�D�
$��・
D�
$
・
D各ステップでは,
還元(
������
):注目点直前の記号列を還元
シフト(
��< )
:注目点を一つ右に移動
��
・
�����D�
�・
����D�
$
・
����D�
$�・
���D�
$��・
��D�
$
・
��D
�
$�・
�D�
$��・
D�
$
・
D
�
�
で還元するときに
の節を用意し,
�
の各記号の節へ枝を張る.
上向き構文解析法
,A� ����������3-
初期状態:・
�D
�
:入力トークン列
i
+E
E
Ei
i+
解析中の状態:
�・
&D
��,#��#�-�
:構築した部分解析木の記号列
&�#� �
:未処理の入力トークン列
最終状態:
"・
D
"
:出発記号
最終状態に変換できれなければ,構文エラー.
��
����項
生成規則の右辺にドットをつけたもの
例:
$�
$��
の
��,/-項
:
$�
・
$��
(導入項)
$��
を読み込めば
$
に還元できる.
$�
$
・
��
$
を読み込んだ.
��
を読み込めば
$
に還元できる.
$�
$�・
�
$�
を読み込んだ.
�
を読み込めば
$
に還元できる.
$�
$��・
(完全項)
$��
を読み込んだ.
$
に還元できる.
$�
文法上の出発記号
"�
新しい出発記号
"�
・
$D
(出発項)
$
を読み込んで
D
に達すれば受理できる.
"�
$
・
D
(受理項)
$
を読み込んだ.
Dに達していれば受理できる.
��
文法
��$�
$������$
における
��
構文解析
+E
i
$受理
E →
i・
E →
E +
i・
E →
E +・
i
E →
E・
$E
→ E・
+ i
S →・
E $
E →・
E +
iE
→・
i
i
+E
E →
E +
i・
E →
E +・
i
E →
E・
$E
→ E・
+ i i
S →
E・
$E
→ E・
+ iE
・i +
i +
i $
i・+
i +
i $
E・
+ i
+ i
$
E +・
i + i
$
E +
i・+
i $
E・
+ i
$
E +・
i $
E +
i・$
E・
$
��
文法
��$�
��$����$
における
��
構文解析
+
E
i
受理
i
E →
i +
E・
・i +
i +
i $
i・+
i +
i $
i +・
i + i
$
i + i・
+ i
$
i + i
+・
i $
i + i
+ i・
$
i + i
+ E・
$
i + E・
$
E・
$
E →
i・
+ E
E →
i・
E →
i・
+ E
E →
i・
+ i
E →
i・
+ E
E →
i・
E →
i +
E・
E
E
不都合な
状態
S →
E・
$$
E →
i +・
EE
→・
i + E
E →・
i
E →
i +・
EE
→・
i + E
E →・
i
S→・
E $
E →・
i + E
E →・
i
��
0���,/-項
集合
(�����,0-:
0
の閉包
,������-
�(�����,0-�0
��
��・
���
が
(�����,0-の
要素なら,
任意の導入項
��
・
-
も,
(�����,0-の
要素
例:文法
��$�
��$����$
(�����,"�
・
$D-
+�"�
・
$D�$�
・
��$�$�
・
��
=� �,0��-
+(�����,��
���・
���,�
��・
���-�0�-
例:文法
��$�
��$����$
=� �,�$�
� ・
�$�$�
�・���-
+(�����,�$�
��・
$�-
+�$�
��・
$�$�
・��$�$�
・
���
正準オートマトン
������������������
初期状態
(�����,�"�
・
$D�-
から始め,可能な遷移をすべて求める
例:文法
��$�
��$����$
の正準オートマトン
+i
受理
i
E →
i +
E・
E →
i・
+ E
E →
i・
E
ES →
E・
$$
E →
i +・
EE
→・
i + E
E →・
i
S→・
E $
E →・
i + E
E →・
i
# #
不都合な状態
F�
還元状態(完全項を含む状態)
正準集合:正準オートマトンの状態集合 �
�
配置
�������������
��
構文解析のある時点
���������・
����������D
における配置は,
,����� ���� ������� ������������D-
� �
:初期状態,
� �+=� �,� ��
����-+=� �,� �����������-
��
構文解析開始時点の配置:
,������������D-
�
�������
による還元後:
,����� ��������� ��
�������������D-
�+=� �,� ��
��-
��
を読み込んでシフト後:
,����� ������� �������������D-
�+=� �,� ����-
最終的な配置:
,��"��D-
��
例:文法
=�+����$の
正準オートマトン
I 0
I 1 I 2 I 3 I 4 I 5
I 6
I 7
I 8
I 10
I 11
E
+
*
T F i
(
E
TF
(
TF
(
i
F
(i
)+
*I 9
i
受理
$
# # #
#
#
#
��+�$�
$�%�%
%�
%����
��
�$����
初期状態
0 �
+(�����,�"�
・
$D�-
F�
還元状態
不都合な状態(とりあえずシフトを優先):
0 �+�$�
%
・
�%�
%
・���
0 +�$�
$�%
・
�%�
%
・
���
��
=�
の正準集合
0 �+�"�
・
$D�
$�
・
$�%�
$�
・
%�
%�
・
%���
%�
・
��
��
・
�$��
��
・
��
0 �+�"�
$
・
D�
$�
$
・
�%�
0 �+�$�
%
・
�
%�
%
・
���
0 �+�%�
�
・
�
0 �+���
�・
$��
$�
・
$�%�
$�
・
%
%�
・
%���
%�
・
��
��
・
�$��
��
・
��
0 �+���
�・
�
0 �+�$�
$� ・%�
%�
・
%���
%�
・��
��・
�$��
��・
��
0 �+�%�
%�・��
��
・
�$��
��
・��
0 �+���
�$
・
��
$�
$
・
�%�
0 +�$�
$�%
・
�
%�
%
・
���
0 ��+�%�
%��
・
�
0 ��+���
�$�・
�
��
I 0
I 1 I 2 I 3 I 4 I 5
I 6
I 7
I 8
I 10
I 11
E
+
*
T F i
(
E
TF
(
TF
(
i
F
(i
)+
*I 9
i
受理
$
# # #
#
#
#
���
��������
の読込み
���� ��
��������
�で還元
���� ��
��������
�
で還元
���� ��
��������
�
で還元
���� ��
���������の
読込み
���� ��� ��
������
の読込み
���� ��� ��� ��
������
�で還元
���� ��� ��� ��
������
�
で還元
���� ��� ��� ��
�������の
読込み
���� ��� ��� ��� ��
����
の読込み
���� ��� ��� ��� ��� ��
����
�で還元
���� ��� ��� ��� ��� ��
����
���
で還元
���� ��� ��� ��
����
���
で還元
���� ��
��
受理
��
�����構
文解析
��������E
1文字先読み
,��������-し
,
<�����
集合で不都合な状態を解消
���,�-文法:
���,�-構
文解析が可能な文法
例:
=�
の不都合な状態
0 �
0 �+�$�
%
・
�%�
%
・
���
次の入力トークンが
��#�����,$-+�����,�
の要素なら,
$�
%で還元
�G�Hな
ら,
G�Hを
読み込んでシフト
'�
どちらでもなければ,構文エラー
0 +�$�
$�%
・
�%�
%
・
���
#�����,$-+�����,����
�
=�
は
���,�-文
法
��
�
�
�
�
�
D
0 �)
!
0 �
*
受理
0 �
� 9
�
�
0 �
�!�!
�!
�!
0 �)
!
0 �
�*�*
�*
�*
0 �)
!
0 �)
!
0 �
*
��
0
��9
��
��
0 ��
�'�'
�'
�'
0 ��
�)�)
�)
�)
動作表
$
%
�
0 �0 �0 �0 �
0 �0 �0 �0 �
0 �
0 0 �
0 �
0 ��
行先表
��$�
$�%
�$�
%
'�%�
%��
!�%�
�
)���
�$�
*���
�
動作表
,�� ��� �A��-
�
:状態
0 �
にシフト
��
:
�
番目の生成規則で還元
受理:構文解析終了
空欄:動作未定義
�構文エラー
行先表
,3� � �A��-
還元後の状態(
=� �,0��-)
��
���,�-構
文解析プログラム(文法に依存せず)
���$��� �����
��������*�
�� �����
�-�����-�$��.����-���������������
����-�0��(�LM?1J��
������������������
�������$���������
������-�0����
��$������-�0��(�N9>8K9��
����� �(�-���-�0�����
�����$��.���B��������������������
��$������-�0��(�5KK9OJ�
��� �������$�����
�$��
I�����-�0��(�8=>91?=9>��I
������� � ���
��
配置
,����� �������
���� ������������D-
の表現:
変数
�����
:
� �
� �
スタック:
� ������������
�
.����
スタック:
���������
��
還元用関数(文法に依存)
��� �(�-������ �(�-������
���$����
�D��-��� �(�-������
-�����I�9&P9�J�I
�������$�����������$�����
������$�����
������������������������
�������$�����.�����$��F�F������
-�����I�9&PJ�I
��� �9�
-�����I�J&PJ�1�I000
-�����I�J&P1�I
000
-���#�I�1&P�9��I000
-���%�I�1&P��I
000
��
$�
$�%
による還元:
,����� �������
�� ��
�$�� ��
��� ��
�%�� �����-�
,����� �������
�� ��
�$������-
$�
の構文木は
%�
と同じ
��,�-や
�$��,�-で
も,プログラムは同じ.動作表と行先表が異なる.
��
����構
文解析
<�����
集合より正確な先読み記号を使用
�
�
による還元
"・
D�� ��
�
・
&D� ��
�� ・
&D
次の入力
�
は,
��#�� ,&D-
のはず.
��,�-項
:次の入力が
�
なら
�
�
で還元可能
I�
�・
��J
��,�- 項
の一般形:
I�
��・
����J
完全項を核
,����-
とする
��,�-項
I�
����・
��J
になって次の入力が
�
なら,
�
����
で還元可能
��,�-構
文解析の初期状態:
0 �+(�����,�I"��
・
"�DJ�-
=� �,0��-+(�����,�I�
���・
����J�I�
��・
�����J�0�-
�
��,�-項
集合
0
の閉包
0�+(�����,0-
��0��
0
�0�
の要素
I�
��・
�����J,生成規則
��
-
,
���#�� ,���-で
あるすべての
��
について,
I��
・
-���Jを
0�
に追加.
'�0�
に追加がなくなるまで,ステップ
を繰り返す.
例:
=�
を
��,�-構
文解析するときの初期状態
0 �+(�����,�I"�
・
$�DJ�-
+�I"�
・
$�DJ�
I$�
・
$�%�DJ�I$�
・
%�DJ�I$�
・$�%��J�I$�
・
%��J�
I%�
・
%���DJ�I%�
・
��DJ�I%�
・
%����J�I%�
・
���J�
I%�
・
%����J�I%�
・
���J�I��
・
�$��DJ�I��
・
��DJ�
I��
・
�$���J�I��
・
���J�I��
・
�$���J�I��
・
���J�
+�I"�
・
$�DJ�
I$�
・
$�%�D �J�I$�
・
%�D �J�
I%�
・
%���D � �J�I%�
・
��D � �J�
I��
・
�$��D � �J�I��
・
��D � �J�
��
��,�-構
文解析のための正準オートマトンの作り方:
���,�-の
場合とまったく同じ.
例:
=�
を
��,�-構
文解析するためのオートマトン
0 �+=� �,0 ��%-+(�����,�I$�
%
・
�D �J�I%�
%
・
���D � �J�-
+�I$�
%
・
�D �J�I%�
%
・
���D � �J�
0 �+=� �,0 ���-+(�����,�I��
� ・
$��D � �J�-
+�I��
�・
$��D � �J�
I$�
・
$�%�� �J�I$�
・
%�� �J�
I%�
・
%���� � �J�I%�
・
��� � �J�
I��
・
�$��� � �J�I��
・
��� � �J�
0� �+=� �,0 ��%-+(�����,�I$�
%
・
�� �J�I%�
%
・
���� � �J�-
+�I$�
%
・
�� �J�I%�
%
・
���� � �J�
�+0 �
���,�-の
ときは
=� �,0 ��%-+0 �
だった.
�
��,�-は
,より詳細な構文解析が可能.
���,�-文
法はすべて
��,�-文
法.
��,�-文
法で,
���,�-文
法でないものが存在する.
��
������構
文解析
��,�-構
文解析法は,状態数が多過ぎて実用的でない.
核が同じである
��,�-項
を同一視して状態数を減らす.
例: 0 �
+�I$�
%
・
�D �J�I%�
%
・
���D � �J�
0� �+�I$�
%
・
�� �J�I%�
%
・
���� � �J�
を融合し,
0 �+�I$�
%
・
�D � �J�I%�
%
・
���D � � �J�
さらに =
� �,0 ��%-+0 �
�$��,�-は
,正確さは
��,�-よ
り劣るが,
���,�-よ
りは正確.
状態数は
���,�-と
同じ.
��
�$��,�-文
法で,
���,�-文
法でない例:
�!+�"�
$�$��
$�
��
� ����
�
�
・
��������
・
����������
・
��������
・
�����
� �����
�
�
�
・
����
� ������
�
・
������
� ������
�・
�������
�・
����
� ������
�
・
��������
・
�����
� ������
���
・
����
� ������
�・
����
S
+E i
E i
I 2 I 3I 6I 5
I 1
I 4I 0
この文法は
�$��,�-文
法(
��,�-文
法でもある)
���,�-用
の
0 �+�"�
�・
�$�
�・
�
について
#�����,"-+�D�
,
#�����,$-+�D���
なので,
���,�-文
法でない.
ポイント:
0 �
は,
0 �
から
�を読み込んだ直後の状態.
$�
�で還元すれば,
"�
$�$
の最初の
$
.だから,次の入力は
G�H
二つ目の
$
のために,
#�����,$-が
D
を含む.
��
構文解析の自動化
,����KL� $�� ���(�������(�������-
+-���� �� 0
+��.��O28LJ?:9L2O5NNO5N?>9=J?1?9N
++
9�
9O28LJ�,,��.�����$��F�F�,��,����
GJ
�,,,���
J�
JJ?:9L1�,,��.�����$��F�F�,��,����
G1
�,,,���
1�
2O5N9NO5N�,,,���
G?>9=J?1?9N
�,,,���
++ ���
ここに
��.�����$�
等の定義
���
+�--&(�� �� 0
+$�&$
000
#%#5�B
�����%�� �� 0
000
�� � 5�B
�����%0���0-
000
)�5�B
�����%0���0�
+-��0���0�
Q(�����O28L�#'
Q(�����J?:9L�#
000
+
��
����
用に
���
を使う例:
+-���-���� 0$
+�
Q��-$�(�F0���0�F
���� ����$��$�
+�
++
!C�"���
F�F
� ��� �O28L��
F�F
� ��� �J?:9L��
F�F
� ��� �2O5N��
F�F
� ��� �NO5N��
!�&4"!�&4*&)"��$��$-���$�������� ��� �?>9=J?1?9N��
C�
� ��� �*��
0
�� �����F$���-�$� � �3+-3C�F�����!*"�� ��� �*��
++
-�� L� ��BJ��$�!�***"�-�� �LJ�L� ��BJ��$��
���-���$��������
���������LJ���� -��LJ��������
LJ���� $����������� ��� ���
� +
��
pars
er.y
yacc
へのソース
構文解析
プログラム
y.ta
b.c
トークン定義
y.ta
b.h
scan
ner.
l
lex へのソース
実行形式
プログラム
a.ou
t
字句解析
プログラム
lex.
yy.c
lex ライブラリ
yacc
ライブラリ
yacc
lex
cc
��.�����$�
に構文木を表示させる:
���� ������$�*�
�����.�����$��-�� �������� B������ B���
� �����FJ+(��+��F���� ������$������
���� B�P*�� �����F+��F�� B����$��� �����FJ+(�F�&� B���
���� B�P*�� �����F+�F�� B����$��� �����FJ+(F�&� B���
� �����F�C�F�� ��� �&� ������$��
�
��
実行例:
+$���-���� 0$
+--0���0-$��00-&$&$$
+�0���
���4�D
J��������
J�����4�D�
J�����J��J��
+�0���
���
J��������
������ �
+
��
����
を使って,動作表と行先表の情報を調べる:
+�--&��� �� 0
+-��0������
�����*
,�--����09,��(
�*�
?>9=J?1?9N
�����#
2O5N
������
0
� �
9
B����
J
B����
1
B����
������
���
中略
���
�������
1�2O5N9NO5N0
�#�
0
�(�-�#
'�� ����$�������� ����$�
'B ���� �$�����������
+
��
あいまいな文法への対処
文法
=�<+���<�"を
使用する.
��<+�"�
���$�"����$�"�$��"��$�
$�
��
��
����構
文解析の場合
くくり出しの結果
=�<H+���<H�"
��<H+�"�
���$�"��$�
�
�$��"��
$�
��
#�� ,$-+���
#�� ,-+��$����#�����,-
+��$����#�����,"-+��$���D�
#�� ,"-+������
#�����,"-+�D��#�� ,-+�D��$���
#�����,-+#�����,"-+�D��$���
#�����,$-+�����
"���� ��,"����$�"-+����
"���� ��,"��$�-+���
"���� ��,��$��"-+��$���
"���� ��,��-+#�����,-+�D��$���
"���� ��,$��-+���
"���� ��,��$��"-�"���� ��,��-+��$����+
なので,
=�<Hは
,
��,�-文
法でない.
���
次が
�$��
なら,
�
�$��"
を採用することにする.
���$��� ���5���
�������$��������
����
��� ��� ���L���
��$����������������
��� �9:OJR�
�$��
������� � ���
�
���$��� ���L���
���$����4�
��������������
����
���E���$�� �������������� � ���
��� ���9���
���E��� �� �������������� � ���
�� ���L���4�� ���5���
��� ���.�����$��F��F����4��
��$���������������
������
���E����<�������������� � ���
�� ���9���
���E�������-�$���������������� � ���
��� ���.�����$��FF�����
��$��
������� � ���
�
���
��
構文解析の場合
=�<
の正準集合(抜粋):
� ���� ����
�
�
・
����
���
�
�
・
�����
・
���������
・
������������
��
・
���
� ������ ��������
��・
�������
��・
����������
� ������ �������� �����
��� ・
������
���・
����������
����
��� ・
������
���・
�����������
・
��
� ������ ��������
����
・
�����
����
・
��������
� ������ �������� �����
����� ・
����
�����・
��������
����
�����・
����
�����・
�������
��
・
���������
・
��������������
・
���
� ������ ��������
������
・
���
������
・������
不都合な状態
0 �
について
#�����,"-+�D��$���
なので,
=�<
は
���,�-文
法ではない.
シフトすると決めてしまえば
���,�-構
文解析は可能.
$� ���,0���$��-+*
として動作表を作る.
=�<
は
��,�-文
法でも
�$��,�-文
法でもない.
同様に対処すれば,
��,�-・
�$��,�-構
文解析も可能.
���
����
の場合
����
のルール
��
還元よりもシフトを優先する.
�
先に与えた生成規則による還元を優先する.
+-��S��0
���
中略
���
L�
?12O5N9NO5NL�,,��.�����$��F��F�,��,#�9:OJR���
G?12O5N9NO5NL92L9L�,,��.�����$��F��F�,��,#�,'���
G?>9=J?1?9N9T9L9:?K@2@=�,,��.�����$��FF�,��,����
9�
?>9=J?1?9N�,,,���
���
中略
���
+�--&(S��0
-���$�-���������I �(�-�
+--0���0-$��00-&$&$$
+�0���
�������������$�����
J��������
J��������
J�������J��J��
J��������J��&�
+
���
エラーリカバリ
�
回のコンパイルで,できるだけ多くのエラーを検出
エラー検出で構文解析をただちに終了しないで,
なんらかの処置を行って実行を継続.
����構
文解析のエラーリカバリ
�� ���
がエラーを検出するのは:
��
次の入力が,どの
"���� ��,��-に
も属さない.
��
�
の解析中に,次の入力が,期待した終端記号と異なる.
例:
=�<Hの
�� ���L
から生成されたであろうトークン列を予測し,それらを読み飛ばす.
�
の場合:
� �
����
である終端記号
�
まで
または,
#�����,-の
要素の直前まで読み飛ばす.
の場合:
期待する終端記号の自動挿入(読み飛ばしなし)
または,期待する終端記号まで読み飛ばす.
���
��
構文解析のエラーリカバリ
動作表の値が「未定義」のときにエラー検出
非終端記号ごとのエラーリカバリは困難
�
大きな単位(文,宣言,関数定義など)について
非終端記号
についてのエラーリカバリ:
,����� ������� ������������D-
の配置で,
$� ���,�����-が
未定義
エラーがなく
への還元が成功していれば,
,����� ������������������D-
/����
,�����
,
�+=� �,� ��-
スタックの巻き戻し:
=� �,� ��-が定義されている
� �
が見つかるまで
入力トークンの読み飛ばし:
#�����,-の
要素
��
が見つかるまで
=�<
の
"
についてのエラーリカバリ:
D��$��������$��.���B����������������L��A*��
������������������$�����
� ������$������������$���9NN@N��
D��$��E����������//E����$�����������
���
����
のエラーリカバリ
�
エラー規則を使用
L�
?12O5N9NO5NL�000�
G?12O5N9NO5NL92L9L�000�
G?>9=J?1?9N9T9L9:?K@2@=�000�
G� � 9T9L9:?K@2@=�
� �����F9 � ���($�� 0C�F��,,,���
G?>9=J?1?9N� � 9L9:?K@2@=�
� �����F9 � �33����-��(0C�F��
,,��.�����$��FF�,��,����
「
"�
�$�
」に対応するエラー規則
"�
� � $�
"�
�� � $�
+�0���
��������$�����
9 � ���($�� 0
J��������
J����������J��
+�0���
���������$�����
9 � �33����-��(0
J��������
J��������
J��������J��J��
+
���
「
�
��� � ��
」の
� �
の位置で構文エラー:
「
�
��・
� � ��
」を含む状態で検出
��
エラートークンを生成して,
�
��� �
・
��
にシフト.
���
に還元できるトークン列を探し,
へ還元.
(トークンを読み飛ばしながら,通常の解析)
'�
通常の構文解析を再開.
���
第5章
意 味 解 析
���
Cコンパイラの主要な意味解析処理
��
名前とオブジェクトとの対応づけ
�
型チェック
オブジェクト
�名前をつけられる構成要素
変数,関数,ラベル,構造体,共用体,
構造体
�共用体のメンバ,
����
定数,型
例: �
������������
�������
��� ����
� (���$��� �������
(���$�����
��� ����
�
��
オブジェクト構造体
オブジェクトを表現する構造体
・オブジェクトの種類
,変数,関数,ラベルなど
-
・オブジェクトの名前
・型情報
・属性
,�� �
,
��3� ��
,
� ��
など
-
・最適化のための情報
・オブジェクトを割り当てる場所
*+
x
x
y
xy
2
関数定義
指定子リスト
パラメータリスト
複合文
宣言リスト
文リスト
指定子リスト
パラメータ
retu
rn
int
int
int
foo
変数宣言
+
2
関数定義
指定子リスト
パラメータリスト
複合文
宣言リスト
文リスト
指定子リスト
パラメータ
retu
rn
int
int
int
変数宣言
foo
y
*
x���
名前空間とスコープ
名前空間:名前が表すオブジェクトの検索空間
C言語の主要な名前空間:
・変数,関数,
�����<
名,
����
定数の名前空間
・ラベルの名前空間
・構造体と共用体の名前空間
例: �
� �-��� ���
����� ���
��� ���
�� �-��� ����� ���
スコープ:オブジェクトを参照できる範囲
�������������
�������
��� ����
�
�������������
���
����
��� ����
�
���
スコープ間の関係
・二つのスコープには共通部分がない.
・二つのスコープはまったく一致する.
・片方のスコープが,もう一方に含まれる.
同じ名前空間に属する二つのオブジェクトのスコープが一致するときは,異なる
名前をつけなければならない.
例:C言語の関数パラメータ
���
名前とオブジェクトの対応づけ
��
まず,
�
の現れているプログラム中の位置によって,
�
が属する名前空間を特
定する.
�
その名前空間に登録されているオブジェクトのうち,
�
の現れている位置を
スコープに含むものを,内側のスコープを持つものから順に調べる.
'��
を名前とするオブジェクトが見つかれば,最初に見つかったオブジェクト
を,
�
は表す.そのようなオブジェクトがなければ,
�
の表すオブジェクトは
未定義である.
スタックを使った実装
(a)
(b)
(c)
(d)
大域変数
や関数等
大域変数
や関数等
大域変数
や関数等
大域変数
や関数等
y
x
foo
x foo
foo
大域変数,関数,
�����<
名などは,ハッシュ表等に登録するほうが検索効率が
良い.
���
前方参照
�����B���������
����*��*�
B��������
$���� �
���
����� �
�����A��B���$����
��� ���
� ��BB��������C
で,未定義ラベル
����
をラベル表に登録.
������
,未定義,参照済
�
�B$����C
で,ラベル
$���
を登録.
������
,未定義,参照済
��$���
,定義済,未参照
�
'�B�����C
で,ラベル
����
が「定義済」に.
������
,定義済,参照済
��$���
,定義済,未参照
�
!�BB���$����C
で,ラベル
$���
が「参照済」に.
������
,定義済,参照済
��$���
,定義済,参照済
�
)�
関数の意味解析終了時に,ラベル表を調べ,
「未定義」のラベルがあればエラー.「未参照」のラベルがあれば警告.
���
型チェックと型変換
型表現:型を表すデータ
�-�� �,��B��(G����B��(G&-
�����,��B��(G����B��(G&-�,$��BG��� �G&-
��$���
�(���$��,$��BG&-
������
多くのプログラミング言語(C言語を含む)では,構文木を葉から根の方向に向
かって調べれば,式の型が決定できる.
例:
) ��) �
の型チェック
:
) �
の型(型表現)
�
:
) �
の型(型表現)
���J(���$���
-��-.(���$����� ��� ��
��$������J(���$���
-��-.(���$���� ��� ���
��$�����J�$�����
-��-.�$������� ��� ��
��$������J�$�����
-��-.�$������ ��� ���
��$���
-��-.������-��-.������� ��� �
J����� �
��
第6章
コード生成
���
実行環境のモデル
メモリ領域
�>�
領域(場所・サイズは固定)
�
ユーザ領域
�
コード領域(ロード時に確定)
�
データ領域
�
大域データ領域(ロード時に確定)
�
スタック(実行時に拡大・縮小)
�
ヒープ(実行時に拡大)
上位番地
下位番地
OS領域
コード領域
大域データ領域
ヒープ
スタック
���
���
とレジスタ
中央処理装置
,(�� ����������3��� E(��-�
コード領域から機械語命令を一つずつ取り出し実行
算術論理装置
,$�� ��� ����3����� E$��-�
算術演算や比較演算を実行
��� ���
のレジスタ
��
汎用レジスタ
,3���������������3� ��-�
オペランドとして使用できる
'
ビット長レジスタ
ベースポインタ
���
,スタックポインタ
���
,���
,
���
,
�-�
,
�(�
など
�
条件フラグ
,����� ���;�3-�
比較命令の結果を格納する
�ビット長レジスタ
ゼロフラグ
4�
,符号フラグ
��
など
'�
命令ポインタ
,プログラムカウンタ,�� ��� ������� ��-�
次の命令の場所を指す
'
ビット長レジスタ
���
(��
は次の動作を繰り返す
�
�����
の指す位置から命令を一つ取り出す
�
次の命令を指すように
���
を更新する
'�
取り出した命令を実行する
���
アセンブリ命令
ラベル宣言
�ラベル
�
アセンブリ命令
�
命令名
�オペランド
����オ
ペランド
�
まとめて
�ラベル
��
命令名
�オ
ペランド
��
オペランド
�
�
汎用レジスタ
�
メモリ番地
�
ラベル
�
相対番地
��!�"
�
整数定数
��
算術命令
�
�((
�������
����
に
���
の値を足す
���
�����
����
から
!
を引く
���$������
����
に
�
の値を掛ける
移動命令
�
���
�����
����
に整数
!
を格納する
���
�������
����
の値を
���
に格納する
無条件ジャンプ命令
�
U��
ラベル
比較命令
�
-��
���
条件付きジャンプ命令
�
U
…ラベル
命令条件意味
UB
��������<=��� ��
UB�
��������<=��� ����M4���
U�
�+������<M4���
U��
��+������<6� M4���
U$
��������<��
U$�
��������<����M4���
���
スタック操作命令
�
�������
���
���
ボトム
上位番地
下位番地
(a) 実行前
esp
eax
esp
ebx
eax
ebx
eax
esp
ebx
1010
10
00
10
10
55
5
(b)
push
eax
実行後
(c)
pop
ebx 実行後
���
関数呼出し命令
�-�$$
ラベル
リターン命令
� ��
戻り番地
(b) 呼出し直後
(d) リターン直前
(c) 関数実行中
esp
esp
戻り番地
(a) 呼出し直前
(e)リターン直後
esp
���
関数呼出し
�������������
�������
��� ����
�
�
���������
���
�
���
�������
�
���
�����
000
000
)
���
�������
�*
���
���
��
��
esp
実引数
上位番地
下位番地
戻り番地
ebp
実引数
戻り番地
(a) 呼出し直後
実引数
戻り番地
esp
ebp
(c) 本体実行中
xy
ebp
esp
(b)
ebp の値の保存
���
���
の呼出し
����
#
-�$$
����
�((
�����
一般の関数
1
のコード
�1�
�������
���
�������
���
����� ���
本体の実行
�����
���
�������
���
���
��
ボトム
上位番地
下位番地
ebp
(a) 呼出し直後
(b) 本体実行中
第n引数
第1引数
戻り番地
第n引数
第1引数
戻り番地
局所変数1
局所変数m
esp
.... ....
....
esp
ebp
���
関数呼出し式
1�) ��) ���) ��
のコード
) �
を計算し,結果をプッシュする
���
) �
を計算し,結果をプッシュする
) �
を計算し,結果をプッシュする
-�$$�1
�((
������!
例
�1���2��������
のコード
�����
�1
への第
'
引数
�����
�2
への第
引数
�����
�2
への第
�
引数
-�$$�2
�((
����
�������
�1
への第
引数
�����
�1
への第
�引数
-�$$�1
�((
������
���
例
�
階乗を求める関数
��-�
のコードとその実行
�����-��������
������ ��� ���
�$�� ��� �����-���&���
�
��-���������
���
�������
-��
!���"��
��+�
かどうか
U��
��
���+�
なら
��
へ
���
�����
��+�
なら戻り値は
�
U��
��
������
���� !���"
����
の計算
���
�����
�������
-�$$���-�
�
再帰呼出しで
,���-Nの
計算
�((
�����
���$���� !���"
���,���-Nの
計算
������
���
��
���
戻り番地1
(a)
実行中
戻り番地2
(b)
実行中
(c)
実行中
n
戻り番地1
n
戻り番地1
戻り番地2
戻り番地2
n
esp
ebp
esp
ebp
esp
ebp
321
33
2
fact
(3)
fact
(2)
fact
(1)
���
局所変数等の割当て
��
局所変数領域のサイズ
� ��� を
できるだけ
小さく
�
同じ位置に複数の局所変数を割り当てる
�
スコープが重なる局所変数は,同じ位置に割
り当てない
x のスコープ
y のスコープ
z のスコープ
w のスコープ
順序動作
相対番地
$����$$�-����$$�-
/
初期化
/
/
�
�
の割当て
�!
�
�
の割当て
�:
'
4
の割当て
��
'
'
!
4
の解放
'
)
の解放
�
'
*
D
の割当て
�:
'
9
D
の解放
�
'
:
�
の解放
/
'
� ��� +'�!+�
バイト使用
���
レジスタの退避
��� ���
の汎用レジスタは,
���
と
���
の他に
*
個だけ
��
呼出し後保存レジスタ
,��������.����3� ��-
呼び出す側が使用中かもしれない汎用レジスタ.
呼び出される関数は,使用前に退避
�
呼出し前保存レジスタ
,��������.����3� ��-
上記以外の汎用レジスタ.
呼び出される関数は,退避せずに使用してよい
別の関数を呼び出すときは,退避しておく
少なくとも
���
レジスタは呼出し前保存
�
全レジスタが呼出し前保存と仮定
��
文のコード生成
複合文のコード
�,����,�
� ����� ��
,�
の初期化
���
,�
の初期化
� �
の実行
���
� �
の実行
宣言
�����*�
の初期化
����!���"��*
���
��
文のコード
���)�� ��$��� �
)
を計算し,結果が偽ならば
��
へジャンプ
� �
の実行
U��
��
���
� �
の実行
��� �
��)��
)
を計算し,結果が偽ならば
��
へジャンプ
�
の実行
���
真
偽
s 1 s 2e ?
L1
L2
真
偽
se ?
L1
���
!���
文のコード
D��$��)��
���
)
を計算し,結果が偽ならば
��
へジャンプ
�
の実行
U��
��
���
"���#
文のコード
U����
��������文
のコード
U����
真
偽
se ?L
1
L2
���
式文と代入式のコード
式文
)�)
の計算(結果は破棄)
変数
&
への代入式
&)�
)�
の計算(
�
に結果)
���
���,&-��
例
��4���
���
�����,4-
�((
���
���
���,-��
���
���,�-��
���
ラベルとジャンプ命令の抑制
���) ���
���) ��� ��$��� �
�
) �
を計算し,結果が偽なら
��
へジャンプ
) �
を計算し,結果が偽なら
��
へジャンプ
� �
の実行
U��
��
���
� �
の実行
���
���
��
と
��
は融合可能
抑制の方法
��
まったく参照されないラベルを抑制する
�
直後に来るラベル(もしあれば)を再利用する
'�
直後が無条件ジャンプなら,そのラベルへジャンプする
���
算術式のコード生成
演算式
) ��) ��
��) �
の値をあるレジスタ
�
にロードし,
��
を第
�
オペランド,
) �
の値を第
オペランドとして,
G�Hに対応する命令
���
を実行する.
例
���
���
�����,�-
�((
�����,-
例
�����
���
�����,�-
���$�����,�-
�((
�����,-
例
�������
���
������,�-
���$������,�-
���
������,�-
���$������,-
�((
�����
���
例
���
だけを使って
������
を計算
���
������,�-
���$������,�-
���
�������
���
������,�-
���$������,-
�((
�������
可換演算と非可換演算
例
���
だけを使って
���&��
を計算
���
������,�-
���$������,�-
���
�������
���
������,�-
���$������,-
���
�������
ではなく
���
������,�-
���$������,-
���
�������
���
������,�-
���$������,�-
���
�������
���
利用可能なレジスタ数が
3
,
) �
と
) �
の計算に必要なレジスタ数も
3
のとき,
) �&) �
は
) �
の計算(
��
に結果)
���
�������
) �
の計算(
��
に結果)
���
�������
���
�����
よりも ) �
の計算(
��
に結果)
���
�������
) �
の計算(
��
に結果)
���
�������
右辺の計算を先に!
���
算術式のコード生成アルゴリズム
3�
式の計算に利用できるレジスタ数(
3�
)
4,)-�)
の計算に必要なレジスタ数
3�4,)-�/
4,)-+/�
)
は変数か定数
アルゴリズム
�
算術式
) ��) �
に対して,
まず
4,)�-と
4,)�-を求め
各
) �
のコード生成開始時点で,
4,)�-
個以上のレジスタを空ける
���
�������������� ��
型
4,)�-+4,)�-+3
のとき
) �
の計算(
��
に結果)
���
�������
) �
の計算(
��
に結果)
���
�������
���������� ��
型
4,)�-�3
のとき
) �
の計算(
��
に結果)
) �
の計算(
��
に結果)
���
�����
��������
型
) �
が変数
�定数
&
で,演算が可換のとき
) �
の計算(
��
に結果)
���
������,&-
����� �������
型
4,)�-�3
のとき
) �
の計算(
��
に結果)
) �
の計算(
��
に結果)
���
�����
���� ��
型
) �
が変数
�定数
&
のとき
) �の計算(
��
に結果)
���
������,�-
4,)�-+3
その他
4,)�-+/
4,)�-+3
���
��
�
3�4,)�-�/
��
�����
�
4,)�-+/(
非可換)
��
��
�
4,)�-+/(
可換)
�
�
�
��
���
型コード生成ルーチン
�B�����NL2�-�(��-�� ������� ������ ������
�BN��N��������� �����
$�-�����$$�-�����������
�����F���F������N���
�$����� �B���� �N���
N��������� �����
����������N��������
�$����������������
��� �N��
�
��
型コード生成ルーチン
�B�����N2�-�(��-�� ������� ������ ������
�BN��������� �����
�BN��������� �����
����������N��N���
�$����� �B���� �N���
��� �N��
�
���
使用レジスタ数の計算
算術式
) ��) �
の使用レジスタ数
�����の
値
その他
�
������
その他
��
型
������������������������
��
型
�������������������
�������(
非可換)
������������
�
�������(
可換)
�����
�
4,)�-+3
または
4,)�-+3
なら
4,)��) �-+3
��
型なら
4,)��) �-+���,4,)�-5��4,)�--
) �
の計算(
��
に結果)
4,)�-個使用
) �
の計算(
��
に結果)
4,)�-5�
個使用
���
�����
例
����&��
4,�-+4,�-+/
より
4,���-+�,
同様に
4,��-+�
したがって,
���&��
は��
型
���
�����,�-
���$�����,-
���
������,�-
���$������,�-
���
����
���
例
�3+'
のとき,
���&����-�(����&����B��������U�.&$���
*
-
+
*
*
*
+
+
--
1,L
1,L
1,L
1,R
2,R
L
2,R
L
3,L
R
3,R
L
1,L
1,L
1,L
*
*
ab
cd
ef
g
hi
jk
lm
2,R
L
���
�����
���
����-
���
����$
���$�����
�((
����(
���$�����
�((
����B
���
�-���
���
����U
���
�����
���
�-���
���$����.
���
�����
���$�-�����
���
�������
���$�������
�((
�-�����
���$�-�����
���
関数呼出し式の使用レジスタ数
1�) ���) ��
各
) �
の値をスタックにプッシュ
) �
の計算(
�
に結果)
�����
4,)�-
個のレジスタを使用
すべての実引数をスタックにプッシュ
使用レジスタ数は
���,��4,)�-��4,)�--
1
の使用レジスタ数は,分からない.
�
最大の
3個と仮定
4,1�) ���) ��-+���,3�4,)�-��4,)�--+3
例
����&��
4,���-+3
,
4,��-+�
だから
��
型
-�$$��
���
�����,�-
���$�����,-
���
�����
���
条件ジャンプのコード生成
「
)
を計算し,結果が偽なら
�
へジャンプ」
)
の計算(
�
に結果)
-��
��*
�/
と比較
U�
�
�
等しければジャンプ
「真なら」の場合は,
U�
を
U��
で置き換える.
例
����������*�
のコード
-�$$��
-��
����*
U�
�
���
���,�-��*
��
「
) �P) �
が真なら
�
へ」(
) �P) �
が��型のとき)
) �
の計算(
��
に結果)
) �
の計算(
��
に結果)
-��
�����
UB�
�
���
「
) �//) �
が偽なら
�
へ」
) �
が偽なら
�
へ
) �
が偽なら
�
へ
「
) �//) �
が真なら
�
へ」
) �
が偽なら
��
へ
) �
が真なら
�
へ
���
真
偽e 1
真
偽e 2
L L
真
偽e 1
真
偽
e 2L
L’
「
) �GG) �
が真なら
�
へ」
) �
が真なら
�
へ
) �
が真なら
�
へ
「) �GG) �
が偽なら
�
へ」
) �
が真なら
��
へ
) �
が偽なら
�
へ
���
「
E)
が真なら
�
へ」
)
が偽なら
�
へ
「
E)
が偽なら
�
へ」
)
が真なら
�
へ
���
例
�
「
��//��GGE�-GG(�
が真なら
�
へ」
��//��GGE�-GG(�
が真なら
�
へ
�//�
が真なら
�
へ
�
が偽なら
��
へ
-�����,�-�*
U���
�
が真なら
�
へ
-�����,�-�*
U���
���
E�-GG(�
が真なら
�
へ
-GG(
が偽なら
�
へ
-
が真なら
��
へ
-�����,--�*
U����
(
が偽なら
�
へ
-�����,(-�*
U��
���
���
戻り値の計算コード
��� �)�
)
の計算(
�
に結果)
���
�����
U��
����
モード指定で移動命令を削除
���
モード
�
結果をできるだけ
���
に
������
モード
�
結果をできるだけ
���
以外に
<���
モード
�
どのレジスタでもよい
例
� ��� ����&���
のコード
���&��
全体は
���
モード,
���&��
は��型
��
の計算(
��
に結果)
������
モード
���
の計算(
��
に結果)
���
モード
���
�����
生成結果(移動命令削除)
���
�������,�-
���$
�������,-
���
�������,�-
���$
�������,�-
���
�������
U��
����
���
関数コードの生成例
��-���������
���
�������
本体
�������
の実行
�<
文
����������$�����の
実行
��
が偽なら
��
へ
-��
!���"��
U��
��
��� ���
の実行
���
�����
U��
��
���
��� �����-���&���
の実行
����-���&��
の計算
��-���&��
の計算
�&�
を計算し,結果をプッシュ
���
���� !���"
���
�����
�������
-�$$���-�
�((
�����
���$���� !���"
������
���
�� �
��
その他のトピック
��
局所関数
�
定義を包含する他の局所関数・最上位関数のフレーム参照
�
静的リンクまたはディスプレイを使用
�
3オペランド命令と1オペランド命令
�
2オペランド命令と同様に考察
'�
呼出し後保存レジスタ
�
呼出し前保存レジスタを優先的に割り当てる
�
関数呼出しを含む式は,呼出し後保存レジスタを使って高速化
��