Postfix calculation in smalltalk

I need to write code to evaluate postfix notation (reverse Polish evaluation) in Smalltalk. I went through the documentation and also implemented the stack. This is the code that I have written so far:

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" 

I want to know how tokenize each element in an expression. For example, for example, for expression, 10 3 + 3 7 * - I need to equate this to a token. If it is an operand, it should push it onto the stack. If an operator, pop the stack twice to get the operands and evaluate the expression. I am completely new to smalltalk, so I don't know about the syntax.

+4
source share
2 answers

You did not indicate which Smalltalk dialect you are using. In Squeak, you can use the findTokens: method:

 '336 8 4 2 1 + - * /' findTokens: ' ' ==> an OrderedCollection('336' '8' '4' '2' '1' '+' '-' '*' '/') 

Use isDigit to check if the token is a number:

 '336' first isDigit ==> true '+' first isDigit ==> false 

To convert from string to number, use asNumber :

 '336' asNumber ==> 336 

The entire RPN parser / evaluator can be easily implemented with less than 10 lines of code, but obviously this is your homework (hint: there is no need to implement a stack, there is already one).

+2
source

I suggest you take a look at PetitParser . You can analyze the expression that you have: 10 3 + 3 7 * in tokens, for example: NumberToken (10), OperatorTocken (+), and then depending on the marker you are doing, what you need. Also do not

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

make:

 op1 perform: operator with: op2 

instead

+1
source

All Articles