前期試験 ・ 2005 年 7 月 29 日 2 時限実施 ・ ページ
授業 科目 |
言語理論とコンパイラ | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ | 評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
コンパイラが行う主な五つの処理を順番通りに列挙しなさい。
次の表の空白を埋めなさい。
文法 | Type | 言語 | オートマトン |
---|---|---|---|
句構造文法 | 0 | 句構造言語 | チューリング機械 |
文脈依存文法 | 1 | 文脈依存言語 | 線形拘束オートマトン |
文脈自由文法 | 2 | 文脈自由言語 | プッシュダウンオートマトン |
正規文法 | 3 | 正規言語 | 有限オートマトン |
なぜコンパイラなどで字句解析と構文解析が分けられているかを簡単に説明しなさい。
字句解析は文字毎の処理なので効率が非常に大事。 正規表現・有限オートマトンで効率のよい実装ができる。構文解析には文脈自由言語が必要だが、 効率は少し落ちてもよい。全体に二つに分けると構造的にコンパイラが作れる。 (字句解析と構文解析は自然言語の単語の輸出と文の解析にも相当する。)
次の形式言語を受理する正規表現を作りなさい。使える記号は |
, *
,
(
, )
と ε
である。
説明 | 正規表現 | |
---|---|---|
例 | a が偶数個の語の集合 | (aa)* |
a が奇数個で b がゼロ個以上の語の集合 | b*(ab*a)*b* | |
c の個数を 3 で割って余りが 0 か 2 の語の集合 | (ccc)*(cc|ε) | |
g と h 両方がゼロ個以上の語の集合。但し、g が三つ以上連続しない。 | h*((gg|g)hh*)*(gg|g|ε) |
前期試験 ・ 2005 年 7 月 29 日 2 時限実施 ・ ページ
授業 科目 |
言語理論とコンパイラ | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ | 評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
次の遷移図で定義されている有限オートマトンがある。
(非決定性) 有限オートマトンは次の 5字組で定義されている: <Q, Σ, δ, q0, F>。次の表にぞれそれの定義と上記の遷移図の 場合の値を記入しなさい。
文字 | 定義 | 値 |
---|---|---|
Q | 状態の有限集合 | {A, B, C, D} |
Σ | 入力記号の有限集合 | {0, 1} |
δ | 動作関数 | (値は不要) |
q0 | 初期状態 | A |
F | 受理状態の有限集合 | {C, D} |
上記の図の NFA を DFA に変更し、そのオートマトンの遷移図を示しなさい。
0 -> ( E ) --------> (( F )) -----> (( G )) 1, 0 ^ | |______________| 1
この問題は次ページに続く。
前期試験 ・ 2005 年 7 月 29 日 2 時限実施 ・ ページ
授業 科目 |
言語理論とコンパイラ | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ | 評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
前ページのオートマトンを簡単化しなさい。
このオートマトンはそれ以上簡単化できません
前ページのオートマトンに相当する文法を作りなさい (NFA からでも DFA からでもよい)
E -> 1 E -> 0 E -> 1 F E -> 0 F F -> 0 G F -> 0 G -> 1 G -> 1 F
1 や 0 一個の後に、0 を 前頭に 0 と 1 が交互に 0 記号以上来る。
次の表の正規表現に合う語を三つ例づつ記述しなさい。
番号 | 正規表現 | 語 1 | 語 2 | 語 3 |
---|---|---|---|---|
例 | ab|c* | ab | ε | c |
abc* | ab | abc | abcc | |
e(f|g|h) | ef | eg | eh | |
e|(f|g)* | e | f | gf |
コンパイラでの解析中のエラー処理は難しいとされている。よいエラー処理に要求されるものを三つ列挙しなさい。
1. 分かりやすいエラーメッセージを出す; 2. 一つだけではなく、複数のエラーを見つける; 3. 二次エラーをできるだけ出さない
前期試験 ・ 2005 年 7 月 29 日 2 時限実施 ・ ページ
授業 科目 |
言語理論とコンパイラ | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ | 評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
bison
用) (合計 15 点)Perl プログラム言語には文字列の足し算と掛け算みたいなものがある。足し算の演算子は
"." (ドット) で、二つの文字列をつなぐ。掛け算の演算子は "x" で、左にある文字列
を右にある整数で繰り返すことになる。掛け算は足し算より優先で、結合は二つの演算とも左結合である。
例: ("aA" . "bB") x 2 . "c" x 3
の値は aAbBaAbBccc
である。
この簡単な文法を受理して、式の値を計算するプログラムを bison で段階的に作る。そのために使えるものは 次のとおりである。
次のトークンが定義されていて、字句解析で識別される: DOT
: ドット、
EKS
: "x"、
STRING
: 文字列、
INT
: 整数、
OPENP
: 始め丸括弧
CLOSEP
: 終わり丸括弧。
実装のために string
のデータ型と string concat(string, string);
の二つの文字列をつなぐ関数と int i;
の繰り返し用の変数が用意されている。(bison
なので C
言語だが、文字列のメモリの用意は気にしなくてよい。)
expr : term { printf ("Result is: %s\n", $1); } ; term : STRING DOT STRING { $$ = concat ($1, $2); } ;
expr : term { printf ("Result is: %s\n", $1); } ; term : term DOT STRING { $$ = concat ($1, $2); } ; | STRING { $$ = $1; } ;
expr : term { printf ("Result is: %s\n", $1); } ; term : term DOT factor { $$ = concat ($1, $2); } ; | factor { $$ = $1; } ; factor: factor EKS INT { $$ = ""; for (i=0; i<$3; i++) $$ = concat($$, $1); } | OPENP STRING CLOSEP { $$ = $2; } | STRING { $$ = $1; } ;
前期試験 ・ 2005 年 7 月 29 日 2 時限実施 ・ ページ
授業 科目 |
言語理論とコンパイラ | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ | 評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
bison
の動作 (5 点)次に bison -v
で作られている file.output
の
一部 (一つの状態についての情報) を示す。
state 17 21 addExpression: mulExpression . 22 mulExpression: mulExpression . '*' unaryExpression 23 | mulExpression . '/' unaryExpression 24 | mulExpression . '%' unaryExpression '*' shift, and go to state 34 '/' shift, and go to state 35 '%' shift, and go to state 36 $default reduce using rule 21 (addExpression)
以上のファイルの一部を簡単に説明しなさい。
bison が作っている状態表の一つの状態の情報です。 分析の現在の現状は '.' で示されている。 mulExpression (因子) を認識したところで、次になにをするのかを決めるところです。 '*', '/' と '%' ではその演算子を shift して、それそれ 34, 35, 36 番の 状態に移る。それ以外のトーケンでしたら 21 番の文法規則を使って単独の mulExpression を addExpression として認識する。
前期試験 ・ 2005 年 7 月 29 日 2 時限実施 ・ ページ
授業 科目 |
言語理論とコンパイラ | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ | 評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
次の機械命令を使って C のプログラムの部分のコードを生成しなさい。
Command Operand Comment LOAD a, R1 変数 a の値をレジスタ R1 に代入 STORE R1, a レジスタ R1 の値を変数 a に代入 CONST 5, R1 レジスタ R1 に 5 と言う定数を代入 JUMP label 無条件のジャンプ JUMP< R1, label レジスタ R1 が 0 より小さい時 label へジャンプ (同様に JUMP<=, JUMP==, JUMP!=, JUMP>= と JUMP> がある。) ADD R1, R2, R3 R1 と R2 を足して R3 に代入。同じレジスタ を何回使ってもよい。 SUB R1, R2, R3 ADD と同様の引き算 (R1 から R2 を引く)
if (a > 2) { b = a; } |
Label Command Operand LOAD a, R1 CONST 2, R2 SUB R1, R2, R2 |
Label Command Operand JUMP<= R2, endif STORE R1, b endif |
if - else
のコード生成 (9 点)左欄にある C
のプログラム部分のコードを右の二欄に書きなさい。
if (a > 2 && b > 2) { b = a; } else if (b < 0) { a = b; } |
LOAD a, R1 CONST 2, R2 SUB R1, R2, R2 JUMP<= R2, else LOAD b, R1 CONST 2, R2 SUB R1, R2, R2 JUMP<= R2, else |
LOAD a, R1 STORE R1, b JUMP endif else LOAD b, R1 JUMP>= R1, endif LOAD a, R1 STORE R1, b endif |
この問題は次ページに続く。
前期試験 ・ 2005 年 7 月 29 日 2 時限実施 ・ ページ
授業 科目 |
言語理論とコンパイラ | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ | 評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
for
文の最適化 (9 点)次の非常に簡単な for
文の最適前のコードは表の左にある。このコードの最適化したものを表の右に書き込みなさい。
(ヒント: レジスタの数を増やし (例えば R1-R5)、有効に使う。繰り返し実行される命令は現在の 13個から
5個まで減らせる。繰り返しの外の命令は若干増えても大丈夫。)
コメントは必要ない。
for (i=0; i<100; i++) sum += i;
Label Command Operand Comment CONST 0, R1 i = 0 STORE R1, i next LOAD i, R2 i < 100 CONST 100, R3 SUB R2, R3, R3 JUMP>= R3, endfor i-100 >= 0 LOAD sum, R1 sum += i; LOAD i, R2 ADD R1, R2, R2 STORE R2, sum LOAD i, R1 i++; CONST 1, R2 ADD R1, R2, R2 STORE R2, i JUMP next continue endfor after loop |
Label Command Operand CONST 0, R1 LOAD sum, R2 CONST 100, R3 CONST 1, R5 label1 SUB R1, R3, R4 JUMP>= R4, label2 ADD R1, R2, R2 ADD R1, R5, R1 JUMP label1 label2 STORE R2, sum STORE R1, i |
次の言語の簡単な例をあげなさい。(ヒント: 決定可能と言うことは受理できる機械がつくれると言うこと)