diff options
Diffstat (limited to 'graphs/piscine/evalexpr/src/shunting_yard.c')
| -rw-r--r-- | graphs/piscine/evalexpr/src/shunting_yard.c | 199 |
1 files changed, 0 insertions, 199 deletions
diff --git a/graphs/piscine/evalexpr/src/shunting_yard.c b/graphs/piscine/evalexpr/src/shunting_yard.c deleted file mode 100644 index 2db5fc8..0000000 --- a/graphs/piscine/evalexpr/src/shunting_yard.c +++ /dev/null @@ -1,199 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -#include "evalexpr.h" - -enum assoc -{ - NONE, - RIGHT, - LEFT, -}; - -int opcmp(struct token *op1, struct token *op2) -{ - return op1->type - op2->type; -} - -enum assoc get_assoc(struct token *op) -{ - if (op->type == EXP) - { - return RIGHT; - } - return LEFT; -} - -enum token_type get_type(char op) -{ - switch (op) - { - case '*': - return MUL; - case '/': - return DIV; - case '-': - return SUB; - case '+': - return ADD; - case '%': - return MOD; - case '^': - return EXP; - case '(': - return PAR_LEFT; - case ')': - return PAR_RIGHT; - default: - return WRONG_TOKEN; - } -} - -char *fifo_to_expr(struct fifo *output, size_t size_offset) -{ - char *res = malloc((2 * fifo_size(output) + size_offset) * sizeof(char)); - if (!res) - { - fifo_destroy(output); - return NULL; - } - res[2 * fifo_size(output) + size_offset - 1] = '\0'; - size_t i = 0; - while (fifo_size(output) > 0) - { - if (fifo_head(output)->type == NUMBER) - { - i += sprintf(res + i, "%d", fifo_head(output)->value) - 1; - } - else - { - res[i] = fifo_head(output)->value; - } - fifo_pop(output); - i++; - if (fifo_size(output) != 0) - { - res[i] = ' '; - i++; - } - } - fifo_destroy(output); - return res; -} - -int handle_rpar(struct tstack **opstack, struct fifo *output, struct token **t) -{ - while (*opstack) - { - struct token *o2 = tstack_peek(*opstack); - if (o2->value == '(') - { - free(o2); - break; - } - *opstack = tstack_pop(*opstack); - fifo_push(output, o2); - } - if (*opstack == NULL) - { - free(*t); - fifo_destroy(output); - return 2; - } - free(*t); - *opstack = tstack_pop(*opstack); - return 0; -} - -int empty_opstack(struct tstack **opstack, struct fifo *output) -{ - while (*opstack) - { - struct token *t = tstack_peek(*opstack); - if (t->value == '(' || t->value == ')') - { - fifo_destroy(output); - return 1; - } - *opstack = tstack_pop(*opstack); - fifo_push(output, t); - } - return 0; -} - -void pop_ops(struct tstack **opstack, struct fifo *output, struct token *t) -{ - while (*opstack) - { - struct token *o2 = tstack_peek(*opstack); - if (!(o2->value != '(' - && (opcmp(t, o2) < 0 - || (opcmp(t, o2) == 0 && get_assoc(t) == LEFT)))) - { - break; - } - - *opstack = tstack_pop(*opstack); - fifo_push(output, o2); - } -} - -void handle_numbers(struct fifo *output, size_t *i, int *size_offset, - const char *expr) -{ - size_t offset; - int val = parse_number(expr + *i, &offset); - struct token *t = malloc(sizeof(struct token)); - t->type = NUMBER; - t->value = val; - fifo_push(output, t); - *i += offset; - *size_offset += offset; -} - -int shunting_yard(const char *expr, char **rpn) -{ - struct fifo *output = fifo_init(); - struct tstack *opstack = NULL; - int size_offset = 0; - for (size_t i = 0; expr[i]; i++) - { - if (expr[i] >= '0' && expr[i] <= '9') - { - handle_numbers(output, &i, &size_offset, expr); - } - else if (expr[i] != ' ') - { - struct token *t = malloc(sizeof(struct token)); - t->value = expr[i]; - if ((t->type = get_type(expr[i])) == WRONG_TOKEN) - { - free(t); - return 1; - } - if (t->value == '(') - { - opstack = tstack_push(opstack, t); - continue; - } - else if (t->value == ')') - { - if (handle_rpar(&opstack, output, &t) != 0) - return 2; - continue; - } - pop_ops(&opstack, output, t); - opstack = tstack_push(opstack, t); - } - } - - if (empty_opstack(&opstack, output) != 0) - { - return 1; - } - *rpn = fifo_to_expr(output, size_offset); - if (!*rpn) - return 4; - - return 0; -} |
