コンパイラ作成(6) 色々修正
コンパイルはできるようになったけど、問題ありありだったんで修正してくよ。まずは構文解析、コード生成をParserクラスに分離した。前回のコードはさぼりだったね。んで、アセンブリコードの出力先もファイルへ変更。この辺は簡単なんでさっくりできたよ。(だったら最初からそうしとけよ、俺)
~/myc$ ./myc.rb err1.myc Syntax error ~/myc$ cat err1.s .intel_syntax noprefix .global main main: mov rax, 42 ret ~/myc$
できたできた。ついでなんでエラーの表示もちょっとだけ分かりやすくするか。
~/myc$ ./myc.rb err1.myc err1.myc:3:14 error: expected ';' after return statement ~/myc$
やってみたらちょこっとした修正でできたよ。
# コンパイルエラーを表示 def perror(emsg = "Syntax error" ) fname, lineno, pos = @lex.position print fname,":",lineno,":",pos," error: ", emsg, "\n" exit -1; # コンパイル処理を打ち切る end
Lexerクラスでgettokenが呼ばれた時の行、桁情報を保持するようにして、perrorでそれを表示してる。
# 文の構文解析 def statement() kind, str = @lex.gettoken if kind == TK::SYMBOL && str == "}" then return false end if kind == TK::ID && str == "return" then # return文の処理 kind, str = @lex.gettoken if kind == TK::NUMBER then codegen " mov rax, "+str codegen " ret" end kind, str = @lex.gettoken if kind == TK::SYMBOL && str == ";" then return false end perror "expected ';' after return statement" return true; end perror return true; end
return文の処理のところ。perrorにエラーメッセージを渡してる。他のところのperrorもおいおい修正してく必要あるなあ。とりあえずまあこんなところかな。次はもうちょっと複雑なプログラムのコンパイルに挑戦したいなあ。