初めてこういった質問サイトに投稿しますため、読みづらい文章ではあると思いますが、ご容赦ください。
###前提・実現したいこと
現在、OpenCOBOLを使ってCOBOLの学習を進めています。
学習の一環として、以前学校で習ったC言語で逆ポーランド記法を用いて、電卓を作成した経験から、
COBOLでも同じことをしてみようと思いGoogleで検索したところ、
先駆者様が既にネットワーク上に、COBOLで実装したコードをアップロードしていらっしゃったので、
それをサンプルコードとして、読み進めながら自分でもCOBOLで実装を試みました。
エラーメッセージも出ずにすんなりとコンパイルが通り、
3 4 + と入力してみたところ、
予想される結果は”7”のはずなのですが、
私の作成したプログラムでは”8”が出力されてしまいました。
先駆者様のプログラムも同じPC上で実行し、同じ値を入力してみたところ、
しっかりと7が出力されていました。
その後、サンプルコードと自分の書いたコードを見比べて確認してみても、
自分の目にはおかしいなと思うところが見当たらず、煮詰まっています。
期待される動作とは矛盾しているコードがあるのはわかりきっているのですが、
私には見つけることが困難なため、お力添えをいただければと思います。
先駆者様のソースコード
お手数をお掛けしますが、直に他人のソースコードを貼るのはどうかと思い、リンクを貼らさせて頂きました。
##私のソースコード
COBOL
1DENTIFICATION DIVISION. 2 PROGRAM-ID. rpncalc. *>逆ポーランド記法を用いた計算機のプログラム 3 4DATA DIVISION. 5 WORKING-STORAGE SECTION. 6 01 fomula PIC X(20). *> 計算式を格納する変数(100はとりすぎ) 7 01 fomula_pos PIC 99. *> 格納した計算式を解析するための字数カウント(position)- 8 *> -厳密には FUNCTION LENGTH(fomula)と組み合わせて使う 9 01 token PIC X. *> 文字や数字を汲み取るための変数 10 11 01 temp PIC 9(4). *> 保持用変数 12 13 01 first_term PIC 9(4). *> 初項 14 01 second_term PIC 9(4). *> 次項 15 16 01 stack_pos PIC 9(2) VALUE 1. *> スタック位置を見る変数 17 18 01 stack 19 03 stack_data PIC 9999 OCCURS 10 VALUE 0. 20 *> 実際のスタック領域 長さは10 21 01 result PIC Z(4). *> 最終的に表示される結果 22 23 24PROCEDURE DIVISION. 25 26 27 Main SECTION. 28 29 DISPLAY "enter the fomula > " WITH NO ADVANCING. 30 *> 計算式を入力 31 ACCEPT fomula. 32 MOVE 1 TO fomula_pos. 33 34 PERFORM UNTIL fomula_pos > FUNCTION LENGTH(fomula) 35 *> fomulaの字数分をwhileする 36 37 MOVE fomula(fomula_pos:fomula_pos) TO token 38 *> MOVEの部分参照を利用して、posの"今いる"部分を参照し、TOKENにより判定 39 40 IF token NOT = " " THEN 41 PERFORM Evaluate_Token 42 END-IF 43 44 *> もし現在位置が空白じゃなかったらEvaluate_Token節に飛ぶ(外PERFORM文) 45 *> 現在位置が空白であればそのままpos++でスルー 46 47 ADD 1 TO fomula_pos 48 49 END-PERFORM. 50 51 PERFORM Result_Display. 52 53 STOP RUN. 54 55 Evaluate_Token SECTION. 56 57 IF token IS NUMERIC THEN 58 *> もしtokenに数字が格納されていたら 59 60 MOVE token TO temp 61 *> tempにtokenを格納し、その値をスタック 62 63 ELSE 64 *> もし演算子がfomula_posに観測されたら、 65 66 PERFORM Pop 67 MOVE temp TO first_term 68 *> 先頭の数値を初項に移す 69 PERFORM Pop 70 MOVE temp TO second_term 71 *> 2つ目の数値(と考えられるもの)を2項目に移す 72 73 EVALUATE token 74 WHEN "+" 75 COMPUTE temp = first_term + second_term ; 76 WHEN "-" 77 COMPUTE temp = first_term - second_term ; 78 WHEN "*" 79 COMPUTE temp = first_term * second_term ; 80 WHEN "/" 81 COMPUTE temp = first_term / second_term ; 82 83 END-EVALUATE 84 85 PERFORM Push 86 *> もし数字であればtempはそのままpushされることになる (remind: ) 87 88 END-IF. 89 90 91 Push SECTION. 92 *> tempに保持されている値をスタック領域にpush(保存・投げ込む) 93 94 IF stack_pos <= 10 THEN 95 MOVE temp TO stack_data(stack_pos) 96 ADD 1 TO stack_pos 97 END-IF. 98 99 Pop SECTION. 100 *> tempに、スタックに保存されている値をpopして格納(取り出す) 101 102 IF stack_pos > 1 THEN 103 SUBTRACT 1 FROM stack_pos 104 MOVE stack_data(stack_pos) TO temp 105 106 END-IF. 107 108 Result_Display SECTION. 109 110 PERFORM Pop. 111 MOVE temp TO result. 112 DISPLAY "Result : " result. 113
###試したこと
・ > 4 3 + で7が出るところに8が出力されてしまいます。
・ > 4 4 + では8が出力されます。
よろしくお願いいたします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/04/18 08:02