言語理論とコンパイラ

第十二回: 中間表現、意味解析

2014 年 6 月 27 日

http://www.sw.it.aoyama.ac.jp/2014/Compiler/lecture12.html

Martin J. Dürst

AGU

© 2005-14 Martin J. Dürst 青山学院大学

今日の予定

前回のまとめ

 

宿題のヒント

 

コンパイラの段階

字句解析 (lexical analysis)

構文解析 (parsing; syntax analysis)

意味解析 (semantic analysis)

最適化 (optimization)

コード生成 (code generation)

中間表現: 名前表

(symbol table)

名前表が扱うデータ

中間表現: 構文木

構文木の生成: 書換規則ごとの処理で生成。例:

expression: expression '+' term { $$ = $1 + $3; }

を次に変える:

expression: expression '+' term
{ $$ = newnode(PLUS, $1, $3); }

(YYSTYPE も変更)

構文木では二分木が多いが、関数の引数などに特別な措置が必要

(簡単なプログラム言語 (例: Pascal)と簡単な計算機構造 (例: スタック・マシーン)
の場合、構文解析しながらのコード生成 (構文木を生成しない) が可能)

 

意味解析

(semantic analysis)

型の等価

(type equivalence)

型が同じかどうか複数の定義がある:

C の例: type-equivalence.c (コンパイル可能か)

型の等価: Haskell の例

 

超単純アセンブリ言語

命令の種類
命令 被演算子 説明 (コメント)
LOAD R1, a メモリの変数 a の値をレジスタ R1 に代入
STORE a, R1 レジスタ R1 の値をメモリの変数 a に代入
CONST R1, 5 レジスタ R1 に 5 の定数を代入
JUMP label 無条件に label へジャンプ
JUMP< R1, label レジスタ R1 が 0 より小さい時 label へジャンプ (JUMP>=, JUMP!= などは同様)
ADD R1, R2, R3 R2 と R3 を足して R1 に代入。同じレジスタを何回使ってもよい。同様に SUB、MUL、DIV がある。

 

構文木からのコード生成