よくある質問とその回答(FAQ)

Q. token構造体,position構造体をRacket対話環境上で表示しても実験資料のように中身が見えない.

A. 演習室のRacketのバージョンが古いため,token構造体やposition構造体が #:transparent をつけて定義されていないようです.実験資料3節の最後(12ページ)に書かれているように,フィールドの値を取得するためのアクセサ関数がそれぞれに用意されていますので,明示的にそれらを呼び出すことで値を確認してください.

なお,実際のSmall Cコンパイラでは,構文解析中のアクションで各トークンの位置情報を取得することになりますが,それには14ページで説明している $n-start-pos, $n-end-pos のような変数へのアクセスを利用できます.(そうして得られたposition構造体中のフィールドアクセスには相変わらずアクセサ関数を使う必要があります.)


Q. void print(int i)に関する暗黙のプロトタイプ宣言とは?

A. 課題7までは,print という名前の通常の関数が存在するものとして扱うだけで十分です. 暗黙のプロトタイプ宣言を追加しなくても構文解析は通ります.

課題8以降は,void print(int i) というプロトタイプ宣言がプログラムの先頭に含まれているものとして(他のユーザ定義関数と同様に)意味解析を行ってください.これは,Small Cソースプログラム中でprint関数が定義されていたりプロトタイプ宣言されていたりすると,二重定義エラーとして扱われることを意味します.

課題16のコード生成では,print関数の呼出しをMIPSの端末へ出力するためのシステムコールを行うコードへと変換してください.つまり,他のユーザ定義関数とは扱いが異なります.


Q. 返り値型が void 以外の関数の実行が return 文で終わらないようなSmall Cプログラムを,コンパイラはどう扱えば良いでしょうか?

A. そのようなSmall Cプログラムの動作は未定義です.そのようなプログラムを書いたプログラマの責任なので,たとえば,適当な値(スタック上のゴミとか以前の$v0レジスタの値)を返してかまわないです.

なお,関数本体のどこにも return 文がないような場合にはコンパイラが警告を出してあげるのが新設ですが,実験では要求しません.また,一般には,本体中に書かれているreturn文が必ず実行されるかどうかは決定不可能です.


Q. 「e1, e2, ..., en」という式は何ですか?

A. これは,通常のC言語にもある式で,Schemeのbegin式と同じだと思ってください.つまり,e1から順に値を計算し(結果の値は捨てていって),最後の式enの値が全体の式の値になります.

関数呼出し式の実引数リストとは違いますので,混同しないように注意してください.