blob: 2965d9c77164f7fbdda4da3956c370ba472438e7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/* main rpn parser and lexical analysis, part of the RPN calculator */
#include <rational>
#include <string>
enum token
{
t_type, /* operator or token type */
Rational: t_value, /* value, if t_type is "Number" */
t_word[20], /* raw string */
}
const Number = '0'
const EndOfExpr = '#'
rpncalc(const string[])
{
new index
new field[token]
for ( ;; )
{
field = gettoken(string, index)
switch (field[t_type])
{
case Number:
push field[t_value]
case '+':
push pop() + pop()
case '-':
push - pop() + pop()
case '*':
push pop() * pop()
case '/', ':':
push 1.0 / pop() * pop()
case EndOfExpr:
break /* exit "for" loop */
default:
printf "Unknown operator '%s'\n", field[t_word]
}
}
printf "Result = %r\n", pop()
if (clearstack())
print "Stack not empty\n", red
}
gettoken(const string[], &index)
{
/* first get the next "word" from the string */
new word[20]
word = strtok(string, index)
/* then parse it */
new field[token]
field[t_word] = word
if (strlen(word) == 0)
{
field[t_type] = EndOfExpr /* special "stop" symbol */
field[t_value] = 0
}
else if ('0' <= word[0] <= '9')
{
field[t_type] = Number
field[t_value] = rationalstr(word)
}
else
{
field[t_type] = word[0]
field[t_value] = 0
}
return field
}
|