Skip to content

Instantly share code, notes, and snippets.

@mizukmb
Last active February 7, 2017 12:21
Show Gist options
  • Save mizukmb/f5911b97b030b043c14759abc7b2046a to your computer and use it in GitHub Desktop.
Save mizukmb/f5911b97b030b043c14759abc7b2046a to your computer and use it in GitHub Desktop.
# x.yE+-z 形式の浮動小数点定数を読み込む
# e.g 12.3E-1, .333E+3
class MzFloat
def initialize(num)
@chars = num.split('')
@index = 0
@ch = chars[index]
@sign = '+'
@b = 0
@e = 0
@i = 0
end
def run
if @ch == '.' # 小数点で開始するとき
@ch = next_char!
raise 'parse error!!' unless digit?(@ch)
@b = @ch.to_i
@e = 1
elsif digit?(@ch)
loop do
@b = @b * 10 + @ch.to_i
@ch = next_char!
break unless digit?(@ch)
end
if @ch == 'E'
exp
return print_parse
end
raise 'parse error!!' if @ch != '.'
else
raise 'parse error!!'
end
@ch = next_char!
while digit?(@ch)
@b = @b * 10 + @ch.to_i
@e += 1
@ch = next_char!
end
if ch != 'E'
print_parse # 本当は計算する
return
end
exp
print_parse
end
private
def exp # E 以降の認識
@ch = next_char!
if %w(+ -).include?(@ch)
@sign = @ch
@ch = next_char!
end
while digit?(@ch)
@i = @i * 10 + @ch.to_i
@ch = next_char!
end
end
def next_char!
@index += 1
return if index >= chars.size
@chars[index]
end
def digit?(ch)
%w(0 1 2 3 4 5 6 7 8 9).include?(ch)
end
def print_parse
"#{@b} * 10 #{@sign} #{@i} - #{@e}"
end
end
MzFloat.new('0.5E+2').run # => "5 * 10 + 2 - 1"
@mizukmb
Copy link
Author

mizukmb commented Feb 7, 2017

コンパイラ 演習問題 2 より

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment