ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙclass Calculator prechigh left '*' '/' left '+' '-' preclow convert NUMBER 'Number' end rule target : exp | /* none */ { result = 0 } exp : exp '+' exp { result += val[2]; a = 'plus' } | exp '-' exp { result -= val[2]; a = "string test" } | exp '*' exp { result *= val[2] } | exp '/' exp { result /= val[2] } | '(' { $emb = true } exp ')' { raise 'must not happen' unless $emb result = val[2] } | '-' NUMBER { result = -val[1] } | NUMBER ----header class Number end ----inner def initialize @racc_debug_out = $stdout @yydebug = false end def validate(expected, src) result = parse(src) unless result == expected raise "test #{@test_number} fail" end @test_number += 1 end def parse(src) @src = src @test_number = 1 yyparse self, :scan end def scan(&block) @src.each(&block) end ----footer calc = Calculator.new calc.validate(9, [[Number, 9], nil]) calc.validate(-3, [[Number, 5], ['*', '*'], [Number, 1], ['-', '*'], [Number, 1], ['*', '*'], [Number, 8], nil]) calc.validate(-1, [[Number, 5], ['+', '+'], [Number, 2], ['-', '-'], [Number, 5], ['+', '+'], [Number, 2], ['-', '-'], [Number, 5], nil]) calc.validate(-4, [['-', 'UMINUS'], [Number, 4], nil]) calc.validate(40, [[Number, 7], ['*', '*'], ['(', '('], [Number, 4], ['+', '+'], [Number, 3], [')', ')'], ['-', '-'], [Number, 9], nil])