我必须编写一个代码来评估Smalltalk中的后缀表示法(反向波兰语评估)。我已经阅读了文档并且还实现了堆栈。这是我到目前为止编写的代码:
Object subclass: #Rpcalc
instanceVariableNames: 'anArray top'
classVariableNames: ''
poolDictionaries: ''
category: nil !
pop:
| item |
item := anArray at: top.
top := top - 1.
^item!
push: item
top := top + 1.
anArray at: top put: item!
setsize: n
anArray := Array new: n.
top := 0!
evaluate:
| expression aToken op1 op2 operator answer|
Transcript show: 'Enter Expression' .
expression :- stdin nextLine.
| aStack |
aStack := Array new: 10 .
aToken := self getNextToken.
((aToken key) = 'operand')
ifTrue: [push : aToken].
aToken := self getNextToken.
((aToken key) = 'operator')
ifTrue: [op1 := pop.
op2 := pop.
operator := aToken.
"if(operator := +)"
"answer := op1 + op2"
我想知道如何标记表达式中的每个元素。例如, 为了表达, 10 3 + 3 7 * - 我需要把它等同于一个令牌。如果是一个操作数,它应该将它推入堆栈。如果是运算符,则弹出堆栈两次以获取操作数并计算表达式。我对smalltalk完全不熟悉,所以我对语法一无所知。
答案 0 :(得分:2)
您没有指定您使用的是哪种Smalltalk方言。在Squeak中,您可以使用findTokens:
方法:
'336 8 4 2 1 + - * /' findTokens: ' '
==> an OrderedCollection('336' '8' '4' '2' '1' '+' '-' '*' '/')
使用isDigit
来测试令牌是否为数字:
'336' first isDigit
==> true
'+' first isDigit
==> false
要将字符串转换为数字,请使用asNumber
:
'336' asNumber
==> 336
整个RPN解析器/评估器可以用少于10行的代码轻松实现,但显然这是你的功课(提示:不需要实现堆栈,已经有一个)。
答案 1 :(得分:1)
我建议你看看PetitParser。您可以将表达式10 3 + 3 7 *
解析为一个标记,例如:NumberToken(10),OperatorTocken(+),然后根据标记执行您需要的操作。也不要做
operator = '+' ifTrue: [op1 + op2]
做的:
op1 perform: operator with: op2
代替,