This is in regards to a class lab project on building a top down parser using flex in Linux as scanner/lexer and parser should convert valid infix expressions to postfix & calculate the result of the expression. Took me a while to comprehend what to do but I managed to almost complete the parser. It may not be optimal but it works. Unfortunately, I ran into some snags along the way, haven't figured it out yet, and my back's starting to ache. So in case I haven't solved it yet later on, hope someone can point out my logic errors.
Here's my problems:
1) infix 2 postfix conversion works 99% -- the left parenthesis still shows up in the postfix expression when it should not.
input: (1-2)*(3+4)
output: 12-34+(*(
expected: 12-34+*
2) calculator doesn't functioning right--it not really calculating. I thought my code is logically correct but maybe not.
Both 1 & 2 were based on algorithms found on net. I'm including snippets of the problem code. If you think the problem is not in those code snippets, let me know & I'll post other portions of the code.
Code:
//this is mostly C except for var++, etc.
int handleTokenData(char *data){
int len = strlen(data);
//store input for error handling
inputStack[isIndex] = malloc(sizeof(char)*len);
strcpy(inputStack[isIndex++],data);
//infix 2 postfix conversion
if((token == TOKID) || (token == TOKNUM)){
//put operand into postfix string
postfixStrStack[pssIndex] = malloc(sizeof(char)*len);
strcpy(postfixStrStack[pssIndex++],data);
}else if(token == TOKADDOP){
//while stack !empty
while(psIndex != -1){
//if top of stack is (, skip poping
if(!strcmp(postfixStack[psIndex],"(")){
break;
}
//else pop top of stack into postfix string
len = strlen(postfixStack[psIndex]);
postfixStrStack[pssIndex] = malloc(sizeof(char)*len);
strcpy(postfixStrStack[pssIndex++],postfixStack[psIndex]);
free(postfixStack[psIndex--]);
}
//then push + or - to stack
len = strlen(data);
postfixStack[++psIndex] = malloc(sizeof(char)*len);
strcpy(postfixStack[psIndex],data);
}else if(token == TOKMULOP){
//push * or / to stack
postfixStack[++psIndex] = malloc(sizeof(char)*len);
strcpy(postfixStack[psIndex],data);
}else if(token == TOKLPAREN){
//push ( to stack
postfixStack[++psIndex] = malloc(sizeof(char)*len);
strcpy(postfixStack[psIndex],data);
}else if(token == TOKRPAREN){
//pop top off stack into postfix string until find (
while(strcmp(postfixStack[psIndex],"(") != 0){
len = strlen(postfixStack[psIndex]);
postfixStrStack[pssIndex] = malloc(sizeof(char)*len);
strcpy(postfixStrStack[pssIndex++],postfixStack[psIndex]);
free(postfixStack[psIndex--]);
}
}else{
//not a valid input, do nothing
}
return 1;
}
int printPostfix(){
//while stack not empty, pop stack top to finalize postfix string
int len;
while(psIndex != -1){
len = strlen(postfixStack[psIndex]);
postfixStrStack[pssIndex] = malloc(sizeof(char)*len);
strcpy(postfixStrStack[pssIndex++],postfixStack[psIndex]);
free(postfixStack[psIndex--]);
}
int i;
printf("Postfix translation: ");
for(i = 0; i < pssIndex; i++)
printf("%s",postfixStrStack[i]);
printf("\n");
return 1;
}
int calcExpr(){
//initialize temp stack for postfix expr calc
double temp = 0;
double result = 0;
double calcStack[100];
int i;
int csIndex = 0;
//scan thru postfix expr to parse & calculate
for(i = 0; i < pssIndex; i++){
//if item is operator:
// 1) pop operand in stack top to temp var
// 2) evaluate temp operator stack top, (poping
// stack top in process) & store in result,
// 3) push result to stack
if(!strcmp(postfixStrStack[i],"*")){
temp = calcStack[csIndex--];
result = temp * calcStack[csIndex--];
calcStack[csIndex] = result;
printf("* now ");
}else if(!strcmp(postfixStrStack[i],"/")){
temp = calcStack[csIndex--];
result = temp / calcStack[csIndex--];
calcStack[csIndex] = result;
printf("/ now ");
}else if(!strcmp(postfixStrStack[i],"+")){
temp = calcStack[csIndex--];
result = temp + calcStack[csIndex--];
calcStack[csIndex] = result;
printf("+ now ");
}else if(!strcmp(postfixStrStack[i],"-")){
temp = calcStack[csIndex--];
result = temp - calcStack[csIndex--];
calcStack[csIndex] = result;
printf("- now ");
}else{ //item is operand: push to stack
calcStack[csIndex++] = atof(postfixStrStack[i]);
printf("#id ");
}
printf("%s %f %f %f\n",postfixStrStack[i],calcStack[csIndex],temp,result);
}
//after scan, pop result from stack
printf("Calculated value of expression: %f\n",calcStack[csIndex]);
return 1;
}