Pascalがやるといってたore言語実装講習会に1時間遅れで参加。
最近は研究でRacc使ってParser書いてるから内容がよく分かる。
昼まで四則演算が出来る程度のParserを書いてから御飯を食べに学食へ。
N嶋研のM2の人々がいたので合流して御飯を食べた。
昼からも参加しようとしたのだが、
無性に眠かったのとノートPCのバッテリーがもたないので研究室へ行くことに。
研究室でまた少しParserを書いて、意識が飛びそうになるので仮眠をとる。
予定より30分長く寝た。
おかげですっきりした。
参考サイト:
Racc ユーザマニュアル
Racc で遊ぼう
RaccでSchemeパーサを作る - 趣味的にっき
参考図書:
今日の成果物 calc.y
#racc calc.y -o calc.rb class Calcp prechigh nonassoc UMINUS left '*' '/' left '+' '-' preclow rule target: exp | /* none */ { result = 0 } exp: exp '+' exp { result += val[2] } | exp '-' exp { result -= val[2] } | exp '*' exp { result *= val[2] } | exp '/' exp { result /= val[2] } | '(' exp ')' { result = val[1] } | '-' NUMBER =UMINUS { result = -val[1] } | NUMBER end ---- header require 'strscan' ---- inner def parse(str) @tokens = StringScanner.new(str).collect_token do |scanner| case when scanner.skip(/\s+/) when scanner.scan(/\d+/) [:NUMBER, scanner[0].to_i] when scanner.scan(/\A.|\n/o) s = scanner[0] [s, s] else raise RuntimeError, 'must not happen!' end end #p @tokens do_parse end def next_token @tokens.shift end ---- footer class StringScanner def collect_token tokens = [] until eos? token = yield(self) tokens << token if token end tokens end end parser = Calcp.new puts puts 'type "Q or q" to quit.' puts while true puts print '? ' str = gets.chop! break if /q/i =~ str begin puts "= #{parser.parse(str)}" rescue ParseError puts $! end end