indexing description: "Reverse polish notation calculator" copyright: "Copyright (c) 1999-2003, Eric Bezault and others" license: "MIT License" date: "$Date$" revision: "$Revision$" class RPCALC inherit YY_PARSER_SKELETON KL_IMPORTED_STRING_ROUTINES create make, execute feature -- Last values last_any_value: ANY last_double_value: DOUBLE feature -- Access token_name (a_token: INTEGER): STRING is -- Name of token `a_token' do inspect a_token when 0 then Result := "EOF token" when -1 then Result := "Error token" when NUM then Result := "NUM" else Result := yy_character_token_name (a_token) end end feature -- Token codes NUM: INTEGER is 258 feature {NONE} -- Implementation yy_build_parser_tables is -- Build parser tables. do yytranslate := yytranslate_template yyr1 := yyr1_template yytypes1 := yytypes1_template yytypes2 := yytypes2_template yydefact := yydefact_template yydefgoto := yydefgoto_template yypact := yypact_template yypgoto := yypgoto_template yytable := yytable_template yycheck := yycheck_template end yy_create_value_stacks is -- Create value stacks. do end yy_init_value_stacks is -- Initialize value stacks. do yyvsp1 := -1 yyvsp2 := -1 end yy_clear_value_stacks is -- Clear objects in semantic value stacks so that -- they can be collected by the garbage collector. do if yyvs1 /= Void then yyvs1.clear_all end if yyvs2 /= Void then yyvs2.clear_all end end yy_push_last_value (yychar1: INTEGER) is -- Push semantic value associated with token `last_token' -- (with internal id `yychar1') on top of corresponding -- value stack. do inspect yytypes2.item (yychar1) when 1 then yyvsp1 := yyvsp1 + 1 if yyvsp1 >= yyvsc1 then if yyvs1 = Void then debug ("GEYACC") std.error.put_line ("Create yyvs1") end create yyspecial_routines1 yyvsc1 := yyInitial_yyvs_size yyvs1 := yyspecial_routines1.make (yyvsc1) else debug ("GEYACC") std.error.put_line ("Resize yyvs1") end yyvsc1 := yyvsc1 + yyInitial_yyvs_size yyvs1 := yyspecial_routines1.resize (yyvs1, yyvsc1) end end yyvs1.put (last_any_value, yyvsp1) when 2 then yyvsp2 := yyvsp2 + 1 if yyvsp2 >= yyvsc2 then if yyvs2 = Void then debug ("GEYACC") std.error.put_line ("Create yyvs2") end create yyspecial_routines2 yyvsc2 := yyInitial_yyvs_size yyvs2 := yyspecial_routines2.make (yyvsc2) else debug ("GEYACC") std.error.put_line ("Resize yyvs2") end yyvsc2 := yyvsc2 + yyInitial_yyvs_size yyvs2 := yyspecial_routines2.resize (yyvs2, yyvsc2) end end yyvs2.put (last_double_value, yyvsp2) else debug ("GEYACC") std.error.put_string ("Error in parser: not a token type: ") std.error.put_integer (yytypes2.item (yychar1)) std.error.put_new_line end abort end end yy_push_error_value is -- Push semantic value associated with token 'error' -- on top of corresponding value stack. local yyval1: ANY do yyvsp1 := yyvsp1 + 1 if yyvsp1 >= yyvsc1 then if yyvs1 = Void then debug ("GEYACC") std.error.put_line ("Create yyvs1") end create yyspecial_routines1 yyvsc1 := yyInitial_yyvs_size yyvs1 := yyspecial_routines1.make (yyvsc1) else debug ("GEYACC") std.error.put_line ("Resize yyvs1") end yyvsc1 := yyvsc1 + yyInitial_yyvs_size yyvs1 := yyspecial_routines1.resize (yyvs1, yyvsc1) end end yyvs1.put (yyval1, yyvsp1) end yy_pop_last_value (yystate: INTEGER) is -- Pop semantic value from stack when in state `yystate'. local yy_type_id: INTEGER do yy_type_id := yytypes1.item (yystate) inspect yy_type_id when 1 then yyvsp1 := yyvsp1 - 1 when 2 then yyvsp2 := yyvsp2 - 1 else debug ("GEYACC") std.error.put_string ("Error in parser: unknown type id: ") std.error.put_integer (yy_type_id) std.error.put_new_line end abort end end feature {NONE} -- Semantic actions yy_do_action (yy_act: INTEGER) is -- Execute semantic action. local yyval1: ANY yyval2: DOUBLE do inspect yy_act when 1 then --|#line 32 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 32") end if yy_parsing_status = yyContinue then yyssp := yyssp - 0 yyvsp1 := yyvsp1 + 1 if yyvsp1 >= yyvsc1 then if yyvs1 = Void then debug ("GEYACC") std.error.put_line ("Create yyvs1") end create yyspecial_routines1 yyvsc1 := yyInitial_yyvs_size yyvs1 := yyspecial_routines1.make (yyvsc1) else debug ("GEYACC") std.error.put_line ("Resize yyvs1") end yyvsc1 := yyvsc1 + yyInitial_yyvs_size yyvs1 := yyspecial_routines1.resize (yyvs1, yyvsc1) end end yyvs1.put (yyval1, yyvsp1) end when 2 then --|#line 33 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 33") end if yy_parsing_status = yyContinue then yyssp := yyssp - 2 yyvsp1 := yyvsp1 -1 yyvs1.put (yyval1, yyvsp1) end when 3 then --|#line 36 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 36") end if yy_parsing_status = yyContinue then yyssp := yyssp - 1 yyvs1.put (yyval1, yyvsp1) end when 4 then --|#line 37 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 37") end print (yyvs2.item (yyvsp2).out); print ("%N") if yy_parsing_status = yyContinue then yyssp := yyssp - 2 yyvsp2 := yyvsp2 -1 yyvs1.put (yyval1, yyvsp1) end when 5 then --|#line 40 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 40") end yyval2 := yyvs2.item (yyvsp2) if yy_parsing_status = yyContinue then yyssp := yyssp - 1 yyvs2.put (yyval2, yyvsp2) end when 6 then --|#line 41 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 41") end yyval2 := yyvs2.item (yyvsp2 - 1) + yyvs2.item (yyvsp2) if yy_parsing_status = yyContinue then yyssp := yyssp - 3 yyvsp2 := yyvsp2 -1 yyvsp1 := yyvsp1 -1 yyvs2.put (yyval2, yyvsp2) end when 7 then --|#line 42 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 42") end yyval2 := yyvs2.item (yyvsp2 - 1) - yyvs2.item (yyvsp2) if yy_parsing_status = yyContinue then yyssp := yyssp - 3 yyvsp2 := yyvsp2 -1 yyvsp1 := yyvsp1 -1 yyvs2.put (yyval2, yyvsp2) end when 8 then --|#line 43 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 43") end yyval2 := yyvs2.item (yyvsp2 - 1) * yyvs2.item (yyvsp2) if yy_parsing_status = yyContinue then yyssp := yyssp - 3 yyvsp2 := yyvsp2 -1 yyvsp1 := yyvsp1 -1 yyvs2.put (yyval2, yyvsp2) end when 9 then --|#line 44 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 44") end yyval2 := yyvs2.item (yyvsp2 - 1) / yyvs2.item (yyvsp2) if yy_parsing_status = yyContinue then yyssp := yyssp - 3 yyvsp2 := yyvsp2 -1 yyvsp1 := yyvsp1 -1 yyvs2.put (yyval2, yyvsp2) end when 10 then --|#line 46 "rpcalc.y" debug ("GEYACC") std.error.put_line ("Executing parser user-code from file 'rpcalc.y' at line 46") end yyval2 := -yyvs2.item (yyvsp2) if yy_parsing_status = yyContinue then yyssp := yyssp - 2 yyvsp1 := yyvsp1 -1 yyvs2.put (yyval2, yyvsp2) end else debug ("GEYACC") std.error.put_string ("Error in parser: unknown rule id: ") std.error.put_integer (yy_act) std.error.put_new_line end abort end end yy_do_error_action (yy_act: INTEGER) is -- Execute error action. do inspect yy_act when 12 then -- End-of-file expected action. report_eof_expected_error else -- Default action. report_error ("parse error") end end feature {NONE} -- Table templates yytranslate_template: SPECIAL [INTEGER] is -- Template for `yytranslate' once Result := yyfixed_array (<< 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 5, 2, 6, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, yyDummy>>) end yyr1_template: SPECIAL [INTEGER] is -- Template for `yyr1' once Result := yyfixed_array (<< 0, 11, 11, 12, 12, 10, 10, 10, 10, 10, 10, yyDummy>>) end yytypes1_template: SPECIAL [INTEGER] is -- Template for `yytypes1' once Result := yyfixed_array (<< 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, yyDummy>>) end yytypes2_template: SPECIAL [INTEGER] is -- Template for `yytypes2' once Result := yyfixed_array (<< 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, yyDummy>>) end yydefact_template: SPECIAL [INTEGER] is -- Template for `yydefact' once Result := yyfixed_array (<< 1, 0, 3, 5, 0, 2, 10, 4, 0, 9, 8, 7, 6, 0, 0, yyDummy>>) end yydefgoto_template: SPECIAL [INTEGER] is -- Template for `yydefgoto' once Result := yyfixed_array (<< 8, 1, 5, yyDummy>>) end yypact_template: SPECIAL [INTEGER] is -- Template for `yypact' once Result := yyfixed_array (<< -32768, 11, -32768, -32768, 4, -32768, -32768, -32768, -3, -32768, -32768, -32768, -32768, 1, -32768, yyDummy>>) end yypgoto_template: SPECIAL [INTEGER] is -- Template for `yypgoto' once Result := yyfixed_array (<< 8, -32768, -32768, yyDummy>>) end yytable_template: SPECIAL [INTEGER] is -- Template for `yytable' once Result := yyfixed_array (<< 3, 14, 12, 11, 10, 9, 6, 3, 7, 4, 0, 13, 0, 6, 3, 2, yyDummy>>) end yycheck_template: SPECIAL [INTEGER] is -- Template for `yycheck' once Result := yyfixed_array (<< 3, 0, 5, 6, 7, 8, 9, 3, 4, 1, -1, 0, -1, 9, 3, 4, yyDummy>>) end feature {NONE} -- Semantic value stacks yyvs1: SPECIAL [ANY] -- Stack for semantic values of type ANY yyvsc1: INTEGER -- Capacity of semantic value stack `yyvs1' yyvsp1: INTEGER -- Top of semantic value stack `yyvs1' yyspecial_routines1: KL_SPECIAL_ROUTINES [ANY] -- Routines that ought to be in SPECIAL [ANY] yyvs2: SPECIAL [DOUBLE] -- Stack for semantic values of type DOUBLE yyvsc2: INTEGER -- Capacity of semantic value stack `yyvs2' yyvsp2: INTEGER -- Top of semantic value stack `yyvs2' yyspecial_routines2: KL_SPECIAL_ROUTINES [DOUBLE] -- Routines that ought to be in SPECIAL [DOUBLE] feature {NONE} -- Constants yyFinal: INTEGER is 14 -- Termination state id yyFlag: INTEGER is -32768 -- Most negative INTEGER yyNtbase: INTEGER is 10 -- Number of tokens yyLast: INTEGER is 15 -- Upper bound of `yytable' and `yycheck' yyMax_token: INTEGER is 258 -- Maximum token id -- (upper bound of `yytranslate'.) yyNsyms: INTEGER is 13 -- Number of symbols -- (terminal and nonterminal) feature -- User-defined features feature {NONE} -- Initialization execute is -- Run calculator. do make parse end feature {NONE} -- Scanner read_token is -- Lexical analyzer returns a double floating point -- number on the stack and the token NUM, or the ASCII -- character read if not a number. Skips all blanks -- and tabs, returns 0 for EOF. local c: CHARACTER buffer: STRING do -- Skip white space from if has_pending_character then c := pending_character has_pending_character := False elseif not std.input.end_of_file then std.input.read_character c := std.input.last_character end until std.input.end_of_file or else (c /= ' ' and c /= '%T') loop std.input.read_character c := std.input.last_character end if std.input.end_of_file then -- Return end-of-file last_token := 0 elseif (c >= '0' and c <= '9') then -- Process numbers last_token := NUM from create buffer.make (10) buffer.append_character (c) std.input.read_character c := std.input.last_character until std.input.end_of_file or else (c < '0' or c > '9') loop buffer.append_character (c) std.input.read_character c := std.input.last_character end if not std.input.end_of_file and then c = '.' then from buffer.append_character ('.') std.input.read_character c := std.input.last_character until std.input.end_of_file or else (c < '0' or c > '9') loop buffer.append_character (c) std.input.read_character c := std.input.last_character end end if not std.input.end_of_file then pending_character := c has_pending_character := True end last_double_value := buffer.to_double elseif c = '%R' then -- Bug in Visual Eiffel 2.1: when the Enter Key -- is pressed, `read_character' gets '%R' instead -- of '%N' or instead of the sequence '%R''%N'. last_token := ('%N').code else -- Return single character last_token := c.code end end last_token: INTEGER -- Last token read feature {NONE} -- Implementation pending_character: CHARACTER has_pending_character: BOOLEAN end