• 検索結果がありません。

Microsoft PowerPoint ppt

N/A
N/A
Protected

Academic year: 2021

シェア "Microsoft PowerPoint ppt"

Copied!
34
0
0

読み込み中.... (全文を見る)

全文

(1)

コード生成(2)

http://cis.k.hosei.ac.jp/~asasaki /lect/compiler/2007-1211.pdf

(2)

概要

• 宣言文と記号表

(3)

宣言

a = 1; b = a+2; putint(b); int main(){ int a; int b; a = 1; b = a+2; putint(b); } PUSH 0 26 LDC 0 1 STV 0 0 LDV 0 0 LDC 0 2 AD 0 0 STV 0 1 LDV 0 1 WRI 0 0 POP 0 26 HLT 0 0

(4)

宣言

a = 1; b = a+2; putint(b); int main(){ int a; int b; a = 1; b = a+2; putint(b); } PUSH 0 2 LDC 0 1 STV 0 0 LDV 0 0 LDC 0 2 AD 0 0 STV 0 1 LDV 0 1 WRI 0 0 POP 0 2 HLT 0 0

(5)

記号表(変数表)を使った記憶域の管理(再掲)

• 宣言された変数の記憶場所などを管理するために、記号表

が必要となる。

int main() { int abc; int cd; int efg; cd = 10; putint(cd); } ident=“abc” address=0 ident=“cd” address=1 ident=“efg” address=2

記号表

ident=“abc” address=0

名前(エントリ)..

記号表に登録する内容 つづり 値を保持する アドレス

(6)

宣言(Declaration)

<MAIN>::= 'int' 'main' '(' ')' <BLOCK>

<BLOCK>::= '{' <INTDECLLIST> <STATEMENTLIST> '}' <INTDECL>::= 'int' <IDENTLIST> ';'

<IDENTLIST>::= <IDENT>

| <IDENT> '[' <NUMBER> ']' | <IDENTLIST> ',' <IDENT>

| <IDENTLIST> ',' <IDENT> '[' <NUMBER> ']

int a, array[3]; int b;

http://cis.k.hosei.ac.jp/~asasaki/lectureCompiler/problem3.htm

宣言部の文法

(7)

int main() main Block { IDECLLIST } IDECL int IDENT:a IDECL int IDENT:b a = 1; STMLIST b = a+ 2; putint(b) int main(){ int a; int b; a = 1; b = a+2; putint(b); }

構文木(概要)

(8)

宣言と記号表への登録

IDECLLIST IDECL int IDENT:a IDECL int IDENT:b addName(“a”) addName(“b”) ident=“a” address=0 ident=“b” address=1

記号表

(9)

メモリ(記憶域)の確保

Block { IDECLLIST } IDECL int IDENT:a IDECL int IDENT:b a = 1; STMLIST b = a+ 2; putint(b) PUSH 0 2 POP 0 2 LDC 0 1 STV 0 0 LDV 0 0 LDC 0 2 AD 0 0 STV 0 1 LDV 0 1 WRI 0 0

(10)

練習問題1

• 下記のプログラムに対する構文解析木を書け。また、構文

解析と同時にコード生成をする過程を、スライド9を参考に図

示せよ。(文の部分の木も省略せず書いてみよ)

int main(){ int abc; int de; int fghi; abc = 1; fghi = 4; de = (2 + abc) * fghi; putint(de); }

(11)

配列(1)

int main(){ int i; int a[3]; a[0]=0; a[1]=1; a[2]=2; } a[2]の値 a[1]の値 a[0]の値 iの値 3 2 1 0 S(スタック) PUSH 0 4 LDC 0 0 STV 0 1 LDC 0 1 STV 0 2 … a[3]のための領域

(12)

配列(2)

int main(){ int i; int a[9]; i = 3 + 4; a[i]=1; a[i+1]=2; } a[7]の値 …… a[0]の値 iの値 8 … 1 0 a[8]の値 9 S(スタック) PUSH 0 10 LDC 0 3 LDC 0 4 AD 0 0 STV 0 0 LDC 0 1 STV 0 8 LDC 0 2 STV 0 9 …

(13)

配列(3)

int main(){ int i; int a[9]; i = 3 + 4; a[i]=1; a[i+1]=2; } a[7]の値 …… a[0]の値 iの値 8 … 1 0 a[8]の値 9 S(スタック) PUSH 0 10 LDC 0 3 LDC 0 4 AD 0 0 STV 0 0 LDC 0 1 STV 0 8 LDC 0 2 STV 0 9 … int main(){ int i; int a[9]; i = 1; while (i <9){ a[i]=i; i=i+1; このような場合、配列への代入

(14)

ロード命令、ストア命令(暫定版再掲)

STV 0 N ストア命令 S[N] ←S[sp]; sp--; pc++ LDV 0 N ロード命令 sp++; S[sp]←S[N]; pc++ LDC 0 N 即値ロード命令 sp++; S[sp]←N; pc++ Hsmのwebページの説明では、 STV p q s[base(p)+q]=s[t];t=t-1;pc=pc+1; となっている。p=0のときは、base(p)=0である。pが0以外 の場合については後の講義で説明する。

(15)

ロード命令、ストア命令(暫定版2)

STV 0 N ストア命令 S[N] ←S[sp]; sp--; pc++ STI 0 0 間接ストア命令 S[S[sp-1]]←S[sp]; sp=sp-2; pc++; LDV 0 N ロード命令 sp++; S[sp]←S[N]; pc++ LDC 0 N 即値ロード命令 sp++; S[sp]←N; pc++ LDA 0 N アドレスロード命令 sp++; S[sp]←N; pc++ LDI 0 0 間接ロード命令 S[sp]←S[S[sp]]; pc++

(16)

STI命令

STI 0 0 間接ストア命令 S[S[sp-1]]←S[sp]; sp=sp-2; pc++; STI 0 0 1000 2 sp sp-1 S(スタック) (s[sp]=1000, s[sp-1]=2) …… … 0 2 1 0 S(スタック) …… … 1000 2 1 0 s[s[sp-1]]←s[sp] s[2]←1000 格納する値 格納する アドレス LDA 0 2 LDC 0 1000 STI 0 0 LDC 0 1000 STV 0 2 STV命令 は左の形 に書き換 えられる

(17)

配列(4)

int main(){ int i; int a[9]; i = 3 + 4; a[i]=1; a[i+1]=2; } PUSH 0 10 LDC 0 3 LDC 0 4 AD 0 0 STV 0 0 LDA 0 1 LDV 0 0 AD 0 0 LDC 0 1 STI 0 0 a[7]の値 …… a[0]の値 iの値 8 … 1 0 a[8]の値 9 1+i (= 8) a[i]のiの値を求める(=7) aの開始アドレス=1をロード 左辺の定数1をロード a[i] (S[8])にストア 格納するア ドレス 格納する 値

(18)

配列(5)

int main(){ int i; int a[9]; i = 3 + 4; a[i]=1; a[i+1]=2; } LDA 0 1 LDV 0 0 LDC 0 1 AD 0 0 AD 0 0 LDC 0 2 STI 0 0 POP 0 10 a[7]の値 …… a[0]の値 iの値 8 … 1 0 a[8]の値 9 aの開始アドレスにi+1を足す(=9) aの開始アドレス=1をロード a[i+1]のi+1(=8)の計算 左辺の2をロード a[8] (S[9])へストア 格納する値 格納する アドレス

(19)

LDI命令

LDI 0 0 間接ロード命令 S[sp]←S[S[sp]]; pc++ LDI 0 0 2 sp S(スタック) (s[sp]=2) …… … 1000 2 1 0 S(スタック) …… … 1000 2 1 0 s[sp]←s[s[sp]](=s[2]) s[sp]←1000 1000 sp ロードしたい変 数のアドレス LDA 0 2 LDI 0 0 LDV 0 2 LDV命令 は左の形 に書き換 えられる

(20)

配列(6)

int main(){ int i; int a[9]; i = 3 + 4; a[i]=1; a[i+1]=a[i]+2; } LDA 0 1 LDV 0 0 LDC 0 1 AD 0 0 AD 0 0 LDA 0 1 LDV 0 0 AD 0 0 LDI 0 0 LDC 0 2 AD 0 0 a[7]の値 …… a[0]の値 iの値 8 … 1 0 a[8]の値 9 a[7](=S[8])の値をロード aの開始アドレスにi+1を足す(=9) aの開始アドレス=1をロード a[i+1]のi+1(=8)の計算 a[i]のアドレス計算 (=1+7=8) +2 格納する値 格納する アドレス =ロードしたい変 数のアドレス

(21)

宣言と記号表登録(配列)

int i; int a[10], j; a[8]の値 …… a[0]の値 iの値 9 … 1 0 a[9]の値 10 jの値 11 ident=“i” address=0 ident=“a” address=1 ident=“j” address=10

記号表

(22)

宣言と記号表登録(配列)

int i; int a[10], j; a[8]の値 …… a[0]の値 iの値 9 … 1 0 a[9]の値 10 jの値 11 ident=“i” address=0 ident=“a” address=1 ident=“j” address=10

記号表

type=var size=1 type=array size=10 type=var size=1

(23)

記号表の拡張

ident=“abc” address=0

名前(エントリ)..

記号表に登録する内容(拡張版) つづり 値を保持する アドレス type=variable size=1 変数の種類 variable or array 記憶域の大きさ Intならば1, 配列ならば 配列のサイズ

(24)

配列要素の代入、参照

<STATEMENT>::= <SUBSTITUTION> '=' <EXPRESSION> ';' ... <SUBSTITUTION>::= <IDENT> | <IDENT> '[' <EXPRESSION> ']' <EXPRESSION>::= .. <TERM>::= <UNARY>::= <FACTOR>::= <IDENT> | <IDENT> '[' <EXPRESSION> ']' | <NUMBER> | '(' <EXPRESSION> ')'

(25)

代入文(1)

<STATEMENT>::= <SUBSTITUTION> '=' <EXPRESSION> ';' <SUBSTITUTION>::= <IDENT> | <IDENT> '[' <EXPRESSION> ']' a[8]=200; 格納するアドレ スを計算する コード 格納する値を計 算するコード LDA 0 1 (aのアドレス) a[8]の値 …… a[0]の値 iの値 9 … 1 0 a[9]の値 10 jの値 11 LDC 0 8 AD 0 0 LDC 0 200

(26)

代入文(2)

<STATEMENT>::= <SUBSTITUTION> '=' <EXPRESSION> ';' <SUBSTITUTION>::= <IDENT> | <IDENT> '[' <EXPRESSION> ']' a[i+3]=200; 格納するアドレ スを計算する コード 格納する値を計 算するコード LDA 0 1 (aのアドレス) a[8]の値 …… a[0]の値 iの値 9 … 1 0 a[9]の値 10 jの値 11 LDV 0 0 (LDA 0 0; LDI 0 0 ) LDC 0 3 AD 0 0 AD 0 0 LDC 0 200

(27)

= STM a[i+3]=200;

代入文の構文木(配列の場合,,概要)

SUBSTITUTION IDENT:a [ EXP ] EXP NUM:200 + IDENT:i NUM:3 LDA 0,「aのアドレス」 LDV 0,「iのアドレス」 LDC 0 3 AD 0 0 AD 0 0 LDC 0 200 STI 0 0

(28)

= STM i=200;

代入文の構文木(概要)

SUBSTITUTION IDENT:i EXP NUM:200 LDA 0,「iのアドレス」 LDC 0 200 STI 0 0 LDC 0 200 STV 0 「iのアドレス」 LDA 0 「iのアドレス」 LDC 0 200

(29)

配列参照式

<EXPRESSION>::= .. <TERM>::= <UNARY>::= <FACTOR>::= <IDENT> | <IDENT> ‘[’ <EXPRESSION> ‘]‘ | … a[i-3]+200 ロードする配列 要素のアドレス 計算のコード LDI 0 0 LDA 0 1 (aのアドレス) LDV 0 0 LDC 0 3 SB 0 0 AD 0 0 LDI 0 0 LDC 0 200

(30)

+ EXP a[i-3]+200;

配列参照の構文木(概要)

F IDENT:a [ EXP ] F + IDENT:i NUM:3 LDA 0,「aのアドレス」 LDV 0,「iのアドレス」 LDC 0 3 SB 0 0 AD 0 0 LDC 0 200 AD 0 0 NUM:200 LDI 0 0

(31)

練習問題2

int main(){ int i; int a[2], b[2]; a[0]=100; a[1]=200; i = 0; b[i]=a[1-i]*4; i = i + 1; b[i]=a[1-i]*4; } 左のプログラムについて下記を示せ。 (1) 記憶域の状態 (2) hsmのコード (3) (2)のコードの実行の状態 (4) 記号表の登録内容 (5) コード生成の過程

(32)

入出力文

<STATEMENT>::= <SUBSTITUTION> '=' <EXPRESSION> ';' | '{' <STATEMENTLIST> '}' | 'putchar' '(' <CHARACTER> ')' ';' | 'getchar' '(' <SUBSTITUTION> ')' ';' | 'putint' '(' <EXPRESSION> ')' ';' | 'getint' '(' <SUBSTITUTION> ')' ';' | 'putnl'';' putchar 引数文字をコンソールに出力 getchar <SUBSTITUTION>に割り当てられた場所にコンソールからの入力文字の コードの値(整数値)を代入する. putint <EXPRESSION>の値を整数で出力 getint <SUBSTITUTION>に割り当てられた場所にコンソールからの入力整数を 代入する. putnl 改行コードをコンソールに出力する

(33)

入力命令

RDI 0 0 整数入力命令 S[S[sp]] に読み込んだ整数を保存; sp--; pc++ RDC 0 0 文字入力命令 S[S[sp]]に読み込んだ文字コードを保存; sp--; pc++

(34)

課題3(Problem3)

• コンパイラの作成3

自由に変数名をつけられる。 (配列を扱うことができる。)…今日は必要なし。 入出力文を扱える。 http://cis.k.hosei.ac.jp/~asasaki/lectureCompiler/problem3.htm

参照

関連したドキュメント

これはつまり十進法ではなく、一進法を用いて自然数を表記するということである。とは いえ数が大きくなると見にくくなるので、.. 0, 1,

口腔の持つ,種々の働き ( 機能)が障害された場 合,これらの働きがより健全に機能するよう手当

被保険者証等の記号及び番号を記載すること。 なお、記号と番号の間にスペース「・」又は「-」を挿入すること。

各テーマ領域ではすべての変数につきできるだけ連続変量に表現してある。そのため

調査対象について図−5に示す考え方に基づき選定した結果、 実用炉則に定める記 録 に係る記録項目の数は延べ約 620 項目、 実用炉則に定める定期報告書

である水産動植物の種類の特定によってなされる︒但し︑第五種共同漁業を内容とする共同漁業権については水産動

北区では、地域振興室管内のさまざまな団体がさらなる連携を深め、地域のき

※優良緑地として登録を 希望する場合は、第 6 条各 号の中から2つ以上の要 件について取組内容を記