27++'s Report

東京大学で行われた「大規模ソフトウェアを手探る」実験においてgccコンパイラーに機能の追加を行った。その際の奮闘を描いた日記(風レポート)。


このブログには東京大学電子情報・電気電子工学科にて行われた「外規模ソフトウェアを手探る」実験において使用の変更、追加を行ったgccについて書かれています。実験日に沿った日記風レポートとなっていますが、実際の進捗とブログの進捗には多少の差があることをここに断らせていただきます。
行ったことは"-o"オプションなしでhoge.cをコンパイルしたときhoge.outとなる変更、及び文末の";"の抜けを自動で補填する変更である。

まとめ(変更箇所の紹介記事リンクとgccの仕組み)

手探るgccのソースコードのダウンロード方法(初日)



文の意味変わらないし、句読点ってなんなん?(3)

最終日を残して(実際の最終日は投稿日ではないのだがトップで断っている)だいたい実装を終えてしまった僕達であったが、";"落としたらいけない反例が見つかってしまった…

それは変数宣言後の";"である。つまり、
int main(){
  int i
  i=1
  printf("%d\n",i)
}
コンパイラーを通らないのだ。中間報告の際に友人や先生方から、「int ihoge」となっている可能性が";"によって否定されるからではないか、というアドバイスを頂いていたので(つまり変数宣言時は";"は単なる句読点としての役割以外にも役割があるのだ!)早速その構造の解明にとりかかった。

…のだが、結論から言うとわからなかった。一体どこで宣言の処理をしているのか皆目見当がつかない。
make_treeのような関数があり、そのなかで構文解析をしているように考えられるが再起の回数が多く追い切ることができなかった。もし次にまたgccを手探ることがあったならばここに再チャレンジしてみたい。

文の意味変わらないし、句読点ってなんなん?(2)

さて、前回アセンブリの領域に入ってしまい詰んでしまったように思われたがエラーを吐いている関数obj->func->exec_child()の引数に実行可能ファイルcc1が入っていることがわかった。
ここで/home/denjo/gcc_install/libexec/…/cc1をデバッグすることにした。与える引数は、"$ ./gcc -v wrong.c"で確認したところ
/home/denjo/repo/lecture_doss/gcc_install/libexec/gcc/x86_64-pc-linux-gnu/6.2.0/cc1 -quiet -v -imultiarch x86_64-linux-gnu test.c -quiet -dumpbase test.c -mtune=generic -march=x86-64 -auxbase test -version -o /tmp/ccrITzFM.s

であることがわかった。

cc1をデバッグしていくとdo_compileなどという関数に入り、デバッグを続けていくとc_parser_skip_until_found()という関数で文法の正当性を評価していることがわかった。
f:id:bigsoftExp:20161201143741p:plain
この関数のc_parser_requireに分け入ってみると、 f:id:bigsoftExp:20161201143853p:plain
このような関数になっており、ここがtrueになることがコンパイラを通過するための必要条件になっていることがわかった。

ここで各引数の値をチェックしてみる。trueを返している時の画像が
f:id:bigsoftExp:20161201145347p:plain
上であり、この時parser[0]->tokens[0]->typeとtypeを比較して、合致している時にtrueを返していることがわかった。

ちなみに落ちた時には parser[0]->tokens[0]->type=CPP_KEYBOARDS(?) みたいな感じだった。

というわけで文末の";"がないときにもあることにしちゃうためには
if(type=CPP_SEMICOLON){return ture;}
の一文を加えてやればいいのでは?という淡い期待を乗せて変更、makeしたところ…

$ ./gcc wrong.c
$ ./wrong.out
Hello World!
できた〜!

文の意味変わらないし、句読点ってなんなん?(1)

さて、前回で"hoge.c"をコンパイルしたときコマンド無しで"hode.out"となるような改造を実装できた。そこで次の目標を立てることにした。

みなさん、こんにちわ

みなさん、こんにちわ。
とで相手に伝わる意味が変わるのだろうか。変わらない。

あくまで句読点は文法上のルールであって意味が通じればいいじゃん!って場面では必要ないのではないか?

これって、C言語でも同じじゃないか??
printf("Hello World");

printf("Hello World")
とで意味変わらないだろ!理解しろよ、gcc

と御託を並べたが、僕はたまに打ち漏らす";"によってコンパイラーに弾かれるとき「許してくれよ〜」ってなり書きなおすのが億劫だなって。

ここで次の目標を
test.c: In function ‘main’:
test.c:5:5: error: expected ‘;’ before ‘}’ token
}
^
このエラーを吐かないようにすること、とした。

続きを読む