コンパイラ作成(106) バグ修正
バグ
エラー処理周りのチェックをしていてバグを見つけたよ。
// 配列 int main() { double a[10], *p = a; a[0) = 42; a[1] = 55; printf("*p = %f\n", *p); }
配列の閉じ括弧が間違ってる場合。エラーにならずにコンパイル通っちゃってたよ。
read_el
# 式の最後までのトークンを読み込む # 返り値 # el : expression's token list # kind : 処理しなかったトークン(セミコロンもしくは閉じ括弧) # str : 処理しなかったトークン(セミコロンもしくは閉じ括弧) def read_el(fkind,fstr,skind,sstr) el = [] if fkind == TK::ID && sstr == "(" then # 関数呼出の処理 sel = [] sel << Token.new(fkind,fstr) sel << Token.new(skind,"()") skind, sstr = @lex.gettoken loop do if skind == TK::SYMBOL && sstr == ")" then break end fkind, fstr = skind, sstr skind, sstr = @lex.gettoken pel, skind, sstr = read_modify_el fkind, fstr, skind, sstr sel << pel if skind == TK::SYMBOL && sstr == "," then skind, sstr = @lex.gettoken elsif skind != TK::SYMBOL || sstr != ")" then perror end end el << sel if skind != TK::SYMBOL || sstr != ")" then perror end skind, sstr = @lex.gettoken elsif fstr == "(" then # 括弧の処理 fkind, fstr = skind, sstr skind, sstr = @lex.gettoken sel, skind, sstr = read_el fkind, fstr, skind, sstr el << sel skind, sstr = @lex.gettoken elsif sstr == "[" then # 配列の処理 el << Token.new(fkind,fstr) el << Token.new(skind,"[]") fkind, fstr = @lex.gettoken skind, sstr = @lex.gettoken sel, skind, sstr = read_el fkind, fstr, skind, sstr if sel.size > 1 then el << sel else el << sel[0] end if skind != TK::SYMBOL || sstr != "]" then perror "expected ']'" end skind, sstr = @lex.gettoken else el << Token.new(fkind,fstr) end loop do if skind == TK::EOF then break end if sstr == ";" then break end if sstr == ")" then break end if sstr == "]" then break end if sstr == "," then break end if sstr == "}" then break end fkind, fstr = skind, sstr skind, sstr = @lex.gettoken if fkind == TK::ID && sstr == "(" then # 関数呼出の処理 sel = [] sel << Token.new(fkind,fstr) sel << Token.new(skind,"()") skind, sstr = @lex.gettoken loop do if skind == TK::SYMBOL && sstr == ")" then break end fkind, fstr = skind, sstr skind, sstr = @lex.gettoken pel, skind, sstr = read_el fkind, fstr, skind, sstr sel << pel if skind == TK::SYMBOL && sstr == "," then skind, sstr = @lex.gettoken elsif skind != TK::SYMBOL || sstr != ")" then perror end end el << sel if skind != TK::SYMBOL || sstr != ")" then perror end skind, sstr = @lex.gettoken elsif fstr == "(" then # 括弧の処理 fkind, fstr = skind, sstr skind, sstr = @lex.gettoken sel, skind, sstr = read_el fkind, fstr, skind, sstr el << sel skind, sstr = @lex.gettoken elsif sstr == "[" then # 配列の処理 el << Token.new(fkind,fstr) el << Token.new(skind,"[]") fkind, fstr = @lex.gettoken skind, sstr = @lex.gettoken sel, skind, sstr = read_el fkind, fstr, skind, sstr if sel.size > 1 then el << sel else el << sel[0] end if skind != TK::SYMBOL || sstr != "]" then perror "expected ']'" end skind, sstr = @lex.gettoken else el << Token.new(fkind,fstr) end end return el, skind, sstr end
チェックが抜けてたよ。
動作テスト
~/myc$ myc err50.myc err50.myc:5:8 error: expected ']' ~/myc$
ちゃんとエラーになったよ。次回なにやろうかな。うーん駄目だ。もう頭が働かなくなってる。明日起きてから考えよう。