#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <stddef.h> #include <math.h> #include <stdbool.h> typedef enum { PLUS, //0 MINUS, //1 DIVIDE, //2 MULT, //3 REMAINDER, //4 POWER, //5 LPAREN, //6 RPAREN, //7 NUMBER, //8 ERROR, //9 EOL //10 } TokenType; struct Token { TokenType type; int value; }; int compute(struct Token, struct Token, struct Token); void parse(void); void rebuild(struct Token, int); void gather(void); struct Token getToken(void); bool isFinished(void); int main(); //The current character char ch; //The input array char arr[20]; //The Token input array struct Token tok[200]; //The size of the Token array int tokSize = 0; //A Token struct Token tk; //the last call for compute bool isLast = false; int main(void) { scanf("%s", arr); parse(); bool fin = false; while (!fin) { gather(); fin = isFinished(); } printf("Result: "); printf("%i\n", tok[0].value); return 0; } //Checks to see if all operators have been removed from the token array bool isFinished() { int fin = 0; for (int i = 0; i < tokSize; i++) { if (tok[i].type >= 0 && tok[i].type < 6) { fin = fin + 1; } } if (fin == 0) { return true; } return false; } //This method seems to still have some bugs in the code //but does work in a few situations such as 5+5+5+5 and 5*5+5*5 //This method searches for the current highest operator (PEMDAS) //along with the two adjecent numbers in the index before and after //the highest operator. Once found, it makes duplicates of the values //and sends them to compute() which calculates the value of the operation. //Once returned, gather() then creates a new token with the calculated value //and passes the value, as well as the initial index to rebuild(). void gather() { int oIndex = 0; int aIndex = 0; int bIndex = 0; bool fail = true; struct Token o; struct Token a; struct Token b; struct Token nToken; for (int i = 0; i < tokSize; i++) { if (tok[i].type >= 0 && tok[i].type < 6) { if (tok[i].type >= oIndex) { oIndex = i; aIndex = i - 1; bIndex = i + 1; fail = false; } } } if (fail) { printf("\n<No More Operators>\n"); } else { o = tok[oIndex]; a = tok[aIndex]; b = tok[bIndex]; int t = compute(a, o, b); nToken.type = NUMBER; nToken.value = t; } rebuild(nToken, oIndex); } //Rebuild takes the new computed value from gather() as well as the index of //the original operator and begins to rebuild the token array. //The first loop skips the 3 values that have been computed while adding all //other values back into a secondary array. //when the array reaches the former operators index - 1, it places the new //calculated token back into the array for further calculation. //and fills in the location of the original operator and the operators index + 1 //which have been computed. After the new array has been completed, the old //array is then overwritten by the new array. gather() is then called again by //the main method and continues until the array no longer contains any operators //While I had intended to add the functionality of numbers greater than //9 as well as accounting for LPAREN and RPAREN, I seem to have run short on //time as this assignment had taken significantly longer than I had anticipated. void rebuild(struct Token item, int oIndex) { struct Token newTok[200]; int oi = oIndex - 1; int k = 0; for (int i = 0; i < tokSize; i++) { if (oi == i) { newTok[k] = item; k++; } else if (i != oIndex && i != oIndex + 1) { newTok[k] = tok[i]; k++; } } struct Token empty; empty.type = EOL; empty.value = 0; for (int i = 0; i < tokSize; i++) { if (i < k) { tok[i] = newTok[i]; } else { tok[i] = empty; } } } //Takes in three tokens, two number tokens and one operator token //returns the computed values int compute(struct Token a, struct Token b, struct Token c) { int x = a.value; int o = b.type; int y = c.value; int response = 0; int k = x; switch (o) { case 0: response = x + y; break; case 1: response = x - y; break; case 2: response = x / y; break; case 3: response = x * x; break; case 4: response = x % y; break; case 5: for (int i = 1; i < y; i++) { x = x * k; } response = x; break; default : printf("ERROR"); } return response; } //Creates the Token and prints the value as it's created. struct Token getToken() { struct Token to; if (isdigit(ch)) { to.type = NUMBER; to.value = ch - '0'; printf("%i", to.value); printf(" NUMBER\n"); return to; } else { switch (ch) { case '+': to.type = PLUS; to.value = 0; printf("+ PLUS\n"); break; case '-': to.type = MINUS; to.value = 0; printf("- MINUS\n"); break; case '/': to.type = DIVIDE; to.value = 0; printf("/ DIVIDE\n"); break; case '*': to.type = MULT; to.value = 0; printf("* MULT\n"); break; case '^': to.type = POWER; to.value = 0; printf("^ POWER\n"); break; case '(': to.type = LPAREN; to.value = 0; printf("( LPAREN\n"); break; case ')': to.type = RPAREN; to.value = 0; printf(") RPAREN\n"); break; case '%': to.type = REMAINDER; to.value = 0; printf("%% REMAINDER\n"); break; default : to.type = ERROR; to.value = 0; printf("! ERROR\n"); break; } } return to; } //calls the getToken method and parses the char array void parse() { int i = 0; while (arr[i]) { ch = arr[i]; tk = getToken(); tok[i] = tk; i++; tokSize = tokSize + 1; } }
We use cookies to provide and improve our services. By using our site, you consent to our Cookies Policy. Accept Learn more