Skip to content

Instantly share code, notes, and snippets.

@dannysauer
Created April 14, 2019 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dannysauer/5b80a1469c2a9e9fa8310cf2bfc54fab to your computer and use it in GitHub Desktop.
Save dannysauer/5b80a1469c2a9e9fa8310cf2bfc54fab to your computer and use it in GitHub Desktop.
Arithmatic parser
// 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