Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include <ctype.h>
- #include <string.h>
- typedef enum operation_type{
- plus, minus,
- times, divide
- } operation_type;
- typedef struct operation{
- operation_type type;
- double *lnum, *rnum;
- int priority;
- struct operation *next;
- } operation;
- double evop(operation_type type, double lnum, double rnum){
- switch(type){
- case plus:
- return lnum + rnum;
- case minus:
- return lnum - rnum;
- case times:
- return lnum * rnum;
- case divide:
- return lnum / rnum;
- }
- }
- void ev(operation **root){
- if((*root) -> next && (*root) -> next -> priority > (*root) -> priority)
- ev(&(*root) -> next);
- * (*root) -> lnum = evop((*root) -> type, * (*root) -> lnum, * (*root) -> rnum);
- free((*root) -> rnum);
- if((*root) -> next){
- (*root) -> next -> lnum = (*root) -> lnum;
- (*root) = (*root) -> next;
- ev(root);
- free(root);
- }
- }
- int main(){
- char *exprMem = malloc(sizeof(char)), *expr = exprMem;
- assert(scanf("%100[^\n]", &expr));
- char *end = strlen(expr) + expr;
- double result;
- operation *opptr, *root = malloc(sizeof(operation));
- opptr = root;
- root -> lnum = &result;
- int adpr = 0; //Additional priority
- while(expr <= end && (isspace(*expr) || *expr == '(')){
- if(*expr == '(') adpr += 2;
- }
- sscanf(expr, "%lf", root -> lnum);
- while(expr <= end){
- expr += strspn(expr, ".0123456789");
- opptr -> next = malloc(sizeof(operation));
- opptr -> next -> lnum = opptr -> rnum;
- opptr = opptr -> next;
- opptr -> next = NULL;
- opptr -> rnum = malloc(sizeof(double));
- while(expr <= end && (isspace(*expr) || *expr == ')')){
- if(*expr == ')') adpr -= 2;
- }
- char op;
- expr += sscanf(expr, "%c", &op); //symbol is 1 byte long, so if pattern was read, there was only one byte
- switch(op){
- case '+':
- opptr -> type = plus;
- opptr -> priority = 0 + adpr;
- break;
- case '-':
- opptr -> type = minus;
- opptr -> priority = 0 + adpr;
- break;
- case '*':
- opptr -> type = times;
- opptr -> priority = 1 + adpr;
- break;
- case ':':
- case '/':
- opptr -> type = divide;
- opptr -> priority = 1 + adpr;
- break;
- default:
- fprintf(stderr, "Error, operation %c is not allowed!", op);
- }
- while(expr <= end && (isspace(*expr) || *expr == '(')){
- if(*expr == '(') adpr += 2;
- }
- expr += sscanf(expr, "%lf", opptr -> rnum);
- }
- ev(&root);
- free(root);
- free(exprMem);
- printf("=%lf\n", result);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement