I have an abstract syntax tree that I made from an expression with reverse polarity. Tree nodes are all rows.
#include <stdlib.h> #include <ctype.h> #include <stdio.h> #include <string.h> struct snode { char *datum; struct snode* bottom; }; struct tnode { char *datum; struct tnode* left; struct tnode*right; }; struct snode* push(struct snode* stack, char *x) { struct snode *S = (struct snode*)malloc(sizeof(struct snode)); S->datum = (char *)malloc(strlen(x) + 1); strcpy(S->datum, x); S->bottom = stack; return S; } void pop(struct snode **stack) { struct snode *S; if (*stack == NULL) return; S = (*stack)->bottom; free(*stack); *stack = S; } char * peek(struct snode* stack){ return stack->datum; } struct tnode* create_node(char *x){ struct tnode* tmp = (struct tnode*)malloc(sizeof(struct tnode)); tmp->datum = (char *)malloc(strlen(x) + 1); strcpy(tmp->datum, x); tmp->right = NULL; tmp->left = NULL; return tmp; } void print_table(struct tnode *AST){ if(AST !=NULL){ printf("("); print_table(AST->left); printf("%s", AST->datum); print_table(AST->right); printf(")"); } } int is_operator(char *tok) { return !strcmp(tok, "A") || !strcmp(tok, "S") || !strcmp(tok, "X") || !strcmp(tok, "D") || !strcmp(tok, "M"); } struct tnode* build_tree(struct snode **S) { struct tnode* root; if (*S == NULL) return NULL; char *top = peek(*S); if (is_operator(top)) { root = create_node(top); pop(S); root->right = build_tree(S); pop(S); root->left = build_tree(S); return root; } root = create_node(top); return root; } int isoperator(struct tnode *AST) { return !strcmp(AST->datum, "A") || !strcmp(AST->datum, "S") || !strcmp(AST->datum, "X") || !strcmp(AST->datum, "D") || !strcmp(AST->datum, "M"); } int main(int argc, char *argv[]) { int i = 1; struct tnode *tree = NULL; struct snode *stack = NULL; char *value; while (argv[i]!= NULL) { value = argv[i]; stack = push(stack, value); i++; } tree = build_tree(&stack); print_table(tree); printf("\n"); return EXIT_SUCCESS; }
This is the code I have. For the evaluation function, I thought about using this:
int evaluate( struct tnode* AST ) { int x, y, z; if ( AST != NULL ){ if (isoperator(AST->datum)){ x = evaluate( AST->left); y = evaluate( AST->right ); switch ( AST->datum ) { case 'A': z = x + y; break; case 'S': z = x - y; break; case 'X': z = x * y; break; case 'D': z = x / y; break; case 'M': z = x % y; break; } return z; } return AST->datum; } }
but I don't think this will work, because I use strings instead of ints. What can I change in my evaluation function?
EDIT: I noticed that the code I wrote was a bit dirty. I cleaned it so that it looks a little better.
EDIT2:
int evaluate( struct tnode* AST ) { int x, y, z; if ( AST != NULL ){ if (isoperator(AST->datum)){ x = evaluate( AST->left); y = evaluate( AST->right ); if(strcmp(AST->datum,"A")==0){ z = x + y; }else if(strcmp(AST->datum,"S")==0){ z = x - y; }else if(strcmp(AST->datum,"X")==0){ z = x * y; }else if(strcmp(AST->datum,"D")==0){ z = x / y; }else if(strcmp(AST->datum,"M")==0){ z = x % y; } return z; } return atoi(AST->datum); } return 0; }
I tried to get rid of the switch statement, but now I get a kernel dump. This is what I wanted to try. I would prefer to set my previous rating function