[Help]Parsing String to Contain inputted int

Hi guys,

this is the first time I am posting in this site. I have been here for almost 3 months looking for answers in my C++ problems.
I do have this problem that I cannot solve, and I think has not been done before.

here's some type of code for this.

cout << "Enter value of x: " << endl; //Let's say 5.
cin >> x;
cout << "Enter equation: "; //Let's say x+1
cin >> equation;

Then the program analyzes that this character "x" has an initial value of 5.
I already have the parser for the equation functions (+,-,*,/)
This is the only thing lacking. Is there some type of function that i missed?

Thank you for some hints regarding this one. :)
Create a symbol table. std::map could be used.
http://www.cplusplus.com/reference/map/map/

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
#include <iostream>
#include <map>
#include <string>
#include <cctype>

std::string trim( std::string str )
{
    std::string result ;
    for( char c : str ) if( !std::isspace(c) ) result += c ;
    return result ;
}

struct symbol_table // integers
{
    void define_symbol()
    {
        std::string name ;
        std::cout << "enter name of variable: " ;
        std::cin >> name ;
        name = trim(name) ;
        // validate name
        int value ;
        std::cout << "enter value of " << name << ": " ;
        std::cin >> value ;
        symbols[name] = value ;
    }

    int operator[] ( std::string name ) const
    {
        auto iter = symbols.find(name) ;
        return iter != symbols.end() ? iter->second : 0 ; // pearl-like
    }

    int& operator[] ( std::string name ) { return symbols[ trim(name) ] ; }

    std::map< std::string, int > symbols ;
};


int main()
{
    symbol_table sym_tab ;
    sym_tab.define_symbol() ;

    std::string equation ;
    std::cout << "equation? " ;
    std::cin >> equation ;

    // parser p ; p.parse(equation) ; etc. (write a parser class)

    // for exposition; just do something crude to evaluate the first symbol
    // for brevity, assume that equation starts with a symbol
    std::size_t pos = equation.find_first_of( "=+-*/ " ) ;
    std::string symbol = equation.substr( 0, pos ) ;
    symbol = trim(symbol) ;

    std::cout << "\n\nsymbol: '" << symbol << "'  value: " << sym_tab[symbol] << '\n' ;
}

http://coliru.stacked-crooked.com/a/b6c9d4f7c1869980
Yes, Thank you for the idea sir.

I have something like this.

cout << "Input value of x: ";
cin >> Xval;

#define x Xval;

then x+2 becomes possible..

The only problem i have now is that my equation parser automatically says "ERROR" when a character is inputted. :(


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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
//************************************
// C++ BEGINNER PARSER CLASS TUTORIAL
//************************************
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cstring>
using namespace std;

enum types { DELIMITER = 1, VARIABLE, NUMBER};	//DEL = 1; VAR = 2; NUM = 3.

class analyzer
{
	private:
	  char *pExpresion;		// Points to the exp<b></b>ression.
	  char token[80];		// Holds current token.
	  char tokenType;		// Holds token's type.

	  void recursive1(double &culmination);
	  void recursive2(double &culmination);
	  void recursive3(double &culmination);
	  void recursive4(double &culmination);
	  void recursive5(double &culmination);
	  void bomb(double &culmination);
	  void nextToken();
	  void serror(int error);
	  int isdelim(char c);

	public:
	  analyzer();					   // analyzer constructor.
	  double sniff(char *exp);			// analyzer entry point.
	  ~analyzer();						// analyzer destructor.
};

//************************************
// 13 analyzer constructor.
//************************************
analyzer::analyzer()
{

	pExpresion = NULL;
  
}

//************************************
// 14 analyzer entry point.
//************************************
double analyzer::sniff(char *exp)
{

	double culmination;

	pExpresion = exp;

	nextToken();
	if(!*token)
	{
	serror(2);						// No exp<b></b>ression present.
	return 0.0;
	}
	recursive1(culmination);
	if(*token) serror(0);			// Last token must be null.
	return culmination;
}

//************************************
// 4 Add or subtract two terms.
//************************************
void analyzer::recursive1(double &culmination)
{

	register char beer;
	double bucket;

	recursive2(culmination);
	while((beer = *token) == '+' || beer == '-')
	{
		nextToken();
		recursive2(bucket);
			switch(beer)
		{
		  case '-':
			culmination = culmination - bucket;
			break;
		  case '+':
			culmination = culmination + bucket;
			break;
		}
	}
}

//************************************
// 5 Multiply or divide two factors.
//************************************
void analyzer::recursive2(double &culmination)
{

	register char beer;
	double bucket;

	recursive3(culmination);
	while((beer = *token) == '*' || beer == '/' || beer == '%')
	{
		nextToken();
		recursive3(bucket);
		switch(beer)
		{
		  case '*':
			culmination = culmination * bucket;
			break;
		  case '/':
			culmination = culmination / bucket;
			break;
		  case '%':
			culmination = (int) culmination % (int) bucket;
			break;
		}
	}
}

//************************************
// 6 Process an exponent.
//************************************
void analyzer::recursive3(double &culmination)
{

	double bucket, ex;
	register int t;

	recursive4(culmination);
	if(*token == '^')
	{
		nextToken();
		recursive3(bucket);
		ex = culmination;
		if(bucket == 0.0)
		{
			culmination = 1.0;
			return;
		}
		for(t=(int)bucket-1; t>0; --t) culmination = culmination * (double)ex;
	}
}

//************************************
// 7 Evaluate a unary + or -.
//************************************
void analyzer::recursive4(double &culmination)
{
	register char  beer;

	beer = 0;
	if((tokenType == DELIMITER) && *token == '+' || *token == '-')
	{
		beer = *token;
		nextToken();
	}
	recursive5(culmination);
	if(beer == '-') culmination = -culmination;
}

//************************************
// 8 Process a parenthesized exp<b></b>ression.
//************************************
void analyzer::recursive5(double &culmination)
{

	if((*token == '('))
	{
		nextToken();
		recursive1(culmination);
		if(*token != ')')
			serror(1);
		nextToken();
	}
	else bomb(culmination);
}

//************************************
// 9 Get the value of a number.
//************************************
void analyzer::bomb(double &culmination)
{

  switch(tokenType)
  {
	case NUMBER:
	  culmination = atof(token);
	  nextToken();
	  return;
	default:
	  serror(0);
  }
}

//************************************
// 11 Display a syntax error.
//************************************
void analyzer::serror(int error)
{

	static char *e[]= 
	{
		"Syntax Error",
		"Unbalanced Parentheses",
		"No exp<b></b>ression Present"
	};

	cout << e[error] << endl;
}

//************************************
// 10 Obtain the next token.
//************************************
void analyzer::nextToken()
{

	register char *bucket;

	tokenType = 0;
	bucket = token;
	*bucket = '\0';

	if(!*pExpresion) return; // At end of exp<b></b>ression.

	while(isspace(*pExpresion)) ++pExpresion; // Skip over white space.

	if(strchr("+-*/%^=()", *pExpresion))
	{
		tokenType = DELIMITER;
		// Advance to next char.
		*bucket++ = *pExpresion++;
	}
	else if(isalpha(*pExpresion))
	{
		while(!isdelim(*pExpresion)) *bucket++ = *pExpresion++;
		tokenType = VARIABLE;
	}
	else if(isdigit(*pExpresion))
	{
		while(!isdelim(*pExpresion)) *bucket++ = *pExpresion++;
		tokenType = NUMBER;
	}

	*bucket = '\0';
}

//************************************
// 12 Return true if c is a delimiter.
//************************************
int analyzer::isdelim(char c)
{

	if(strchr(" +-/*%^=()x", c) || c == 9 || c == '\r' || c == 0)
		return 1;
	return 0;
}

//************************************
// 15 analyzer destructor.
//************************************
analyzer::~analyzer()
{
	  
}

//************************************
//************************************
// Main function Hahahahaahaha
//************************************
int main(int argc, char* argv[])
{
  char expstr[80];
  
  analyzer equation; // Instantiates equation as an object of type analyzer.

  for(;;)	// Creates an infinite loop.
  {
	cout << endl << endl << endl;
	cout << "  To stop the program" << endl << endl;
	cout << "  enter a period then press return." << endl << endl;
	cout << "  To run the program" << endl << endl;
	cout << "  enter an algebraic express; for example, (12+5)*6 " << endl << endl;
	cout << "  then press return ==> ";

	cin.getline(expstr, 79);

	if(*expstr == '.')
	{
		equation.~analyzer();

		break;		// Infinite loop exited by typing a period.
	}
	
	cout << endl << endl << "  Answer is: " << equation.sniff(expstr) << "\n\n";

	cout << endl << endl << endl;
	cout << "  ";
	system("PAUSE");

	system("CLS");

  };

	cout << endl << endl << endl;
	cout << "  ";
	system("PAUSE");

	return 0;
}

//************************************ 


I only took this one from
http://www.dreamincode.net/forums/topic/110782-c-beginner-parser-class-tutorial/

Credits.

Note: I am not majoring in C++. I only need C++ to accept equations because we will be using such in solving equations. :( (i dont know why our prof wanted us to use C++ instead of MATLAB.)

I need this code to stop acting weird when i am inputting x or X..
Can you help me?
In function void analyzer::recursive4( double &culmination ) line 153:
1
2
// if( ( tokenType == DELIMITER ) && *token == '+' || *token == '-' ) // ****
   if( ( tokenType == DELIMITER ) && ( *token == '+' || *token == '-' ) ) // for clarity 


In function void analyzer::bomb( double &culmination ) added case VARIABLE:
1
2
3
4
5
6
7
        case VARIABLE:
        {
            std::cout << "looking up value of variable '" << token << "' => assuming result == 999\n" ;
            culmination = 999 ; // *** hard-coded *** TODO: look up symbol table, get the actual value
            nextToken();
            return ;
        }


In function void analyzer::serror( int error ) line 202:
1
2
    // static char *e[] = // ****
    static const char *e[] = // literal strings are arrays of const char 


In function int analyzer::isdelim( char c ) line 254:
1
2
    //if( strchr( " +-/*%^=()x", c ) || c == 9 || c == '\r' || c == 0 ) // ***
    if( strchr( " +-/*%^=()", c ) || c == 9 || c == '\r' || c == 0 ) // identifier 'x' is not a delimiter 


In function int main() lines 288-293:
1
2
3
4
5
6
7
8
        if( *expstr == '.' )
        {
            // equation.~analyzer(); // *** avoid this
            // instead, move the definition of equation into the loop
            // a new analyser object will be created each time through the loop 

            break; 		// Infinite loop exited by typing a period.
        }

http://coliru.stacked-crooked.com/a/27528f280bd0de17
Last edited on
Thank you very much JLBorges. :)
I appreciate your help. Mwuaaaaaaahhhh. :D

Will this be the same if I am going to edit this to parse trigonometric functions, logarithmic functions, inverse hyperbolic functions., etc..
Example:

if x = 3.1416/2

INPUT: 2*x+tan(x)

Should have an output something like this..

4.1416


Edit: I think I just need to input something like codes,
Example: L is for log10
S is for sine function
C is for cosine,
T for Trigonometric function, so on.. :)

Huhuhuuhuh.. It's eating all the RAM i my head >.<
Last edited on
How can I ever thank you guys? :)

Edit:
I just have 1 question..
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <math.h>
#include <cmath>
using namespace std;

enum types { DELIMITER = 1, VARIABLE, NUMBER };    

class analyzer
{
    private:
    char *pExpresion;		
    char token[80];		
    char tokenType;		

    void recursive1( double &culmination );
    void recursive2( double &culmination );
    void recursive3( double &culmination );
    void recursive4( double &culmination );
    void recursive5( double &culmination );
    void bomb( double &culmination );
    void nextToken();
    void serror( int error );
    int isdelim( char c );

    public:
    analyzer();					   
    double sniff( char *exp );			
    ~analyzer();						
};

analyzer::analyzer()
{

    pExpresion = NULL;

}

double analyzer::sniff( char *exp )
{

    double culmination;

    pExpresion = exp;

    nextToken();
    if( !*token )
    {
        serror( 2 );						
        return 0.0;
    }
    recursive1( culmination );
    if( *token ) serror( 0 );			
    return culmination;
}

void analyzer::recursive1( double &culmination )
{

    register char beer;
    double bucket;

    recursive2( culmination );
    while( ( beer = *token ) == '+' || beer == '-' )
    {
        nextToken();
        recursive2( bucket );
        switch( beer )
        {
            case '-':
                culmination = culmination - bucket;
                break;
            case '+':
                culmination = culmination + bucket;
                break;
        }
    }
}

void analyzer::recursive2( double &culmination )
{

    register char beer;
    double bucket;

    recursive3( culmination );
    while( ( beer = *token ) == '*' || beer == '/' || beer == '%' )
    {
        nextToken();
        recursive3( bucket );
        switch( beer )
        {
            case '*':
                culmination = culmination * bucket;
                break;
            case '/':
                culmination = culmination / bucket;
                break;
            case '%':
                culmination = ( int )culmination % ( int )bucket;
                break;
        }
    }
}

void analyzer::recursive3( double &culmination )
{

    double bucket, ex;
    register int t;

    recursive4( culmination );
    if( *token == '^' )
    {
        nextToken();
        recursive3( bucket );
        ex = culmination;
        if( bucket == 0.0 )
        {
            culmination = 1.0;
            return;
        }
        for( t = ( int )bucket - 1; t>0; --t ) culmination = culmination * ( double )ex;
    }
}

void analyzer::recursive4( double &culmination )
{
    register char  beer;

    beer = 0;

    if( ( tokenType == DELIMITER ) && ( *token == '+' || *token == '-' ) ) 
    {
        beer = *token;
        nextToken();
    }
    recursive5( culmination );
    if( beer == '-' ) culmination = -culmination;
}

void analyzer::recursive5( double &culmination )
{

    if( ( *token == '(' ) )
    {
        nextToken();
        recursive1( culmination );
        if( *token != ')' )
            serror( 1 );
        nextToken();
    }
    else bomb( culmination );
}

void analyzer::bomb( double &culmination )
{
    switch( tokenType )
    {
        case NUMBER:
		{
            culmination = atof( token );
            nextToken();
            return;
		}
		
        case VARIABLE:
        {
            std::cout << "looking up value of variable '" << token << "' => assuming result == 999\n" ;
            culmination = 999 ; // *** hard-coded *** TODO: look up symbol table, get the actual value
            nextToken();
            return ;
        }
        
        default:
            serror( 0 );
    }
}

void analyzer::serror( int error )
{

    
    static const char *e[] = 
    {
        "Syntax Error",
        "Unbalanced Parentheses",
        "No exp<b></b>ression Present"
    };

    cout << e[error] << endl;
}

void analyzer::nextToken()
{

    register char *bucket;

    tokenType = 0;
    bucket = token;
    *bucket = '\0';

    if( !*pExpresion ) return;

    while( isspace( *pExpresion ) ) ++pExpresion;

    if( strchr( "+-*/%^=()", *pExpresion ) )
    {
        tokenType = DELIMITER;
        *bucket++ = *pExpresion++;
    }
    else if( isalpha( *pExpresion ) )
    {
        while( !isdelim( *pExpresion ) ) *bucket++ = *pExpresion++;
        tokenType = VARIABLE;
    }
    else if( isdigit( *pExpresion ) )
    {
        while( !isdelim( *pExpresion ) ) *bucket++ = *pExpresion++;
        tokenType = NUMBER;
    }

    *bucket = '\0';
}

int analyzer::isdelim( char c )
{
    if( strchr( " +-/*%^=()", c ) || c == 9 || c == '\r' || c == 0 )
        return 1;
    return 0;
}

analyzer::~analyzer()
{

}

int main( )
{
    char expstr[80];
    {
        analyzer equation;
		cout << "Enter Equation: ";
        cin.getline( expstr, 79 );
        std::cout << "expression: '" << expstr << "'\n\n" ;
        
        if( *expstr == '.' )
        {
            return 0 ;
        }
        cout << endl << endl << "  Answer is: " << equation.sniff( expstr ) << "\n\n";
        cout << endl << endl << endl;
        cout << "  ";
       
        system( "CLS" );

    };

    cout << endl << endl << endl;
    cout << "  ";
    system( "PAUSE" );

    return 0;
}


Why does the compiler doesn't read line 245
cout << "Enter Equation: ";

I want to improve my user interface through some intro codes. :)

Does my compiler just have problems?
Last edited on
YESSSSS!!

I think I made it. :) Thank you for the help guys. :)
Topic archived. No new replies allowed.