逆ポーランド記法の式を解く。整数の四則演算(+-*/)のみ対応。
数値は1ケタ限定だが、容易に拡張できると思われる。
エラー報告を比較的丁寧にやっているため、標準エラーは出現しないはず。
関連:
#module
#enum global NO_ERROR = 0
#enum global ERROR_DIVIDE_BY_ZERO
#enum global ERROR_NO_OPERAND
#enum global ERROR_UNKNOWN_CHARCTER
// モジュールで利用するためのスタック
#deffunc _put int p1
stack(count) = p1
count++
return
#defcfunc _get
if count > 0 {
count--
} else {
// なにもないスタックから取り出そうとした → エラー
iStat = ERROR_NO_OPERAND
}
return stack(count)
#deffunc calc var ans, str p1, local sExp, local iTmp
sExp = p1
iStat = NO_ERROR
count = 0
repeat strlen(sExp)
i = peek(sExp, cnt)
switch i
case '0':case '1':case '2':case '3':case '4'
case '5':case '6':case '7':case '8':case '9'
// 数値の場合はスタックに積む
_put i - '0'
swbreak
// 以下、オペランドの場合はスタックから2つ取り出して演算する
case '+'
_put _get() + _get()
swbreak
case '-'
iTmp = _get()
_put _get() - iTmp
swbreak
case '*'
_put _get() * _get()
swbreak
case '/'
iTmp = _get()
if iTmp == 0 {
// 0で割ろうとした → エラー
iStat = ERROR_DIVIDE_BY_ZERO
} else {
_put _get() / iTmp
}
swbreak
default
// 規定されていない文字 → エラー
iStat = ERROR_UNKNOWN_CHARCTER
swbreak
swend
if iStat != NO_ERROR : break
loop
if iStat == NO_ERROR : ans = _get()
return iStat
#global
question = "12+5*", "10/", "123*1+-2/", "12~", "1+1"
repeat length(question)
calc answer, question(cnt)
switch stat
case NO_ERROR
mes question(cnt) + " = " + answer
swbreak
case ERROR_DIVIDE_BY_ZERO
mes question(cnt) + " = エラー:0で除算しました"
swbreak
case ERROR_NO_OPERAND
mes question(cnt) + " = エラー:オペランドが不足しています"
swbreak
case ERROR_UNKNOWN_CHARCTER
mes question(cnt) + " = エラー:規定されていない文字が含まれています"
swbreak
default
mes question(cnt) + " = エラー:規定されていないエラーです"
swbreak
swend
loop
0 件のコメント:
コメントを投稿