Created
April 14, 2019 23:11
-
-
Save dannysauer/5b80a1469c2a9e9fa8310cf2bfc54fab to your computer and use it in GitHub Desktop.
Arithmatic parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// process arbitrary 1+2-(3+(5-1))-2 style equations | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
int parse(char[]); | |
int process(int, char, int); | |
struct State { | |
int total; | |
char operator; | |
struct State* prevstate; | |
}; | |
int main(int argc, char* argv[]){ | |
if( argc != 2 ){ | |
printf("Fail.\n"); | |
exit(1); | |
} | |
char* equation = argv[1]; | |
int result = parse(equation); | |
printf("%s = %d\n", equation, result); | |
exit( 0 ); | |
} | |
// assume all numbers, operators, or parens | |
// spaces or anything else will break | |
int parse(char equation[]){ | |
// largest 32-bit integer is 10 chars | |
int maxintlen = 10; | |
char rhs[maxintlen + 1]; | |
char operator; | |
char c2s[2]; // for single-char string conversion | |
char c = '\0'; | |
int i = 0; | |
int total = 0; | |
struct State* currentstate = NULL; | |
struct State* newstate = NULL; | |
c2s[1] = '\0'; | |
//strcpy(rhs, ""); | |
rhs[0] = '\0'; | |
operator = '+'; | |
total = 0; | |
for ( i=0; i < strlen(equation); i++ ){ | |
c = equation[i]; | |
switch(c){ | |
case '+': | |
case '-': | |
// hit an operator; perform last operation then proceed | |
// atoi is dangerous, but we're ignoring error conditions here | |
total = process(total, operator, atoi(rhs)); | |
operator = c; | |
rhs[0] = '\0'; | |
break; | |
case '(': | |
// only comes after operator, so just save state and | |
// essentially start over | |
newstate = malloc(sizeof(struct State)); | |
newstate->total = total; | |
newstate->operator = operator; | |
newstate->prevstate = currentstate; | |
currentstate = newstate; | |
total = 0; | |
operator = '+'; | |
rhs[0] = '\0'; | |
break; | |
case ')': | |
// end of block; total is new RHS, so prepare for next operator | |
// finish the math in the block | |
total = process(total, operator, atoi(rhs)); | |
// prepare current total to be processed | |
sprintf( rhs, "%d", total ); | |
total = currentstate->total; | |
operator = currentstate->operator, | |
currentstate = currentstate->prevstate; | |
break; | |
default: | |
// still working on a number | |
c2s[0] = c; | |
strcat(rhs, c2s); | |
} | |
} | |
// process final value | |
total = process(total, operator, atoi(rhs)); | |
return total; | |
} | |
int process(int lhs, char operator, int rhs){ | |
printf( "processing '%d%c%d'\n", lhs, operator, rhs ); | |
switch(operator){ | |
case '+': | |
return( lhs + rhs ); | |
case '-': | |
return( lhs - rhs ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment