calculator from Bjarnes book

Hi guys so I've come across a snag when trying to get my code working for a calculator using tokens anyway in the book Bjarne helps you and gives you the code for the primary() term() and expression() but he leaves out the getToken() function so I tried to implement this myself

after working on this with a piece of paper for 2 hours I can't seem to get the code working on paper it should work but when I run the program all it prints is the first number I entered in

for example

enter an expression
4 + 2 + 2 q // input
4 // output
enter an expression
error
5.18496e+006




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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

#include <iostream>
#include <vector>
#include <exception>
using namespace std;

double term();
int primary();

class Token{

public:

	char kind;
	double value;

	Token(char kind)
	:kind(kind),value(0)
	{}
	Token(char kind,double value)
	:kind(kind),value(value)
	{}
};

vector<Token> tokens;
int number = 0;

void populateTokens(){

	cout << "enter an expression" << endl;

	int number;
	char op;

	while(cin >> number >> op){

		Token token1('8',number);
		tokens.push_back(token1);

		if(op == 'q'){
			return;
		}

		Token token2(op);
		tokens.push_back(token2);
	}
}

Token getToken(){

	for(int i = 0; i < tokens.size(); i++){

		if(i == number){

			return tokens[i];
		}
	}
	return NULL;
}

double expression(){

	int left = term();
	Token t = getToken();
    number++;
    char kind = t.kind;

    while(true){

    	switch(kind){

    	case '+': left += term();
    	kind = '0';
    	break;
    	case '-': left -= term();
    	break;
    	default : return left;

    	}
    }
}

double term(){

	double left = primary();
	Token t = getToken();
	number++;

	while(true){

		switch(t.kind){

		case '*' :
			left *= primary();
			break;
		case '/' :
			left /= primary();
			break;
		default :
			return left;
		}
	}
}

int primary(){

      Token t = getToken();
      number++;
      switch(t.kind){
      case '(' :{
    	  double d = expression();
    	  t = getToken();
    	  number++;
          if(t.kind != ')'){
        	  cout << "error" << endl;
          }
          return d;
      }
      case '8':
    	  return t.value;
      default: cout << "error" << endl;

      }
      }

int main() {

   try{
   while(cin){

	   populateTokens();
	   cout << expression() << endl;

   }
   }catch(exception& e){

	   cerr << e.what() << endl;
   }
   catch(...){

	   cout << "exception" << endl;
   }
}



this is a pretty tricky one

thanks
Last edited on
Last edited on
thanks kbw much appreciated

but for my own sanity how would I get my code to work AKA write my own getToken() function,I mean I populate the vector of Tokens with the populateTokens() function then I use the getToken() function to get the next Token in the vector,

any ideas how I can tweak my code to make it work,or at least so it calculates the sum (doesn't have to be in the correct order just want to get it working)

thanks
I thought when I incremented the global number variable this would make the program work but to no avail


also the token function is for later code as far as I know it's for the third version of the program I'm working on the first

thanks
hi people for anybody reading this in the future I have came up with a solution

It took me about 90 mins but I reviewed the code and found I could use an incremental solution this isn't the most pretty solution but it works

Bjarne implements his own token stream in the book anyway I'm pretty happy I was able to implement my own

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

#include <iostream>
#include <vector>
#include <exception>
using namespace std;

double term();
int primary();

class Token {

public:

	char kind;
	double value;

	Token(char kind) :
			kind(kind), value(0) {
	}
	Token(char kind, double value) :
			kind(kind), value(value) {
	}
};

vector<Token> tokens;
int number = 0;

void populateTokens() {

	cout << "enter an expression" << endl;

	int number;
	char op;

	while (cin >> number >> op) {

		Token token1('8', number);
		tokens.push_back(token1);

		if (op == 'q') {

			Token quitToken(op);
			tokens.push_back(quitToken);
			return;
		}

		Token token2(op);
		tokens.push_back(token2);

	}
}

Token getToken() {

	for (int i = 0; i < tokens.size(); i++) {

		if (i == number) {

			return tokens[i];
		}
	}

	return NULL;
}

double expression() {

	int left = term();
	Token t = getToken();

	while (true) {

		switch (t.kind) {

		case '+':
			number++;
			left += term();
			t = getToken();
			break;
		case '-':
			number++;
			left -= term();
			t = getToken();
			break;
		default:
			number--;
			return left;

		}
	}
}

double term() {

	double left = primary();
	Token t = getToken();

	while (true) {

		switch (t.kind) {

		case '*':
			number++;
			left *= primary();
			t = getToken();
			break;
		case '/':
			number++;
			left /= primary();
			t = getToken();
			break;
		default:
			return left;

		}
	}
}

int primary() {

	Token t = getToken();
// maybe remove
	number++;

	switch (t.kind) {
	case '(': {
		double d = expression();
		t = getToken();

		if (t.kind != ')') {
			cout << "error" << endl;
		}
		return d;
	}
	case '8':
		return t.value;
	default:
		cout << "error" << endl;

	}
}

int main() {

	try {
		while (cin) {

			populateTokens();
			cout << expression() << endl;
			number = 0;

		}
	} catch (exception& e) {

		cerr << e.what() << endl;

	} catch (...) {
		cout << "exception" << endl;
	}
}
there is a major flaw with this still,if anybody wants to try solve it feel free =)

and if you solve whats wrong (I already know) please tell me your solution if you have one =)

thanks
I'm not quite sure what the problem is that you've found.
Topic archived. No new replies allowed.