4

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 * という式の場合、これをトークンと同一視する必要があります。オペランドの場合は、スタックにプッシュする必要があります。演算子の場合、スタックを 2 回ポップしてオペランドを取得し、式を評価します。私は smalltalk にまったく慣れていないので、構文についてはわかりません。

4

2 に答える 2

2

使用している Smalltalk 方言を指定していません。findTokens:Squeak では、次の方法を使用できます。

'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 行未満のコードで簡単に実装できますが、明らかにそれは宿題です (ヒント: スタックを実装する必要はありません。既にスタックがあります)。

于 2013-04-05T17:57:56.237 に答える
1

PetitParserをご覧になることをお勧めします。あなたが持っている式を解析することができます10 3 + 3 7 *: NumberToken(10)、OperatorTocken(+) のようなトークンに変換し、トークンに応じて必要なことを行います。また、しないでください

operator = '+' ifTrue: [op1 + op2]

行う:

op1 perform: operator with: op2

代わりは、

于 2013-04-04T20:58:00.543 に答える