summaryrefslogtreecommitdiff
path: root/rushs/tinyprintf/evalexpr/src/shunting_yard.c
diff options
context:
space:
mode:
Diffstat (limited to 'rushs/tinyprintf/evalexpr/src/shunting_yard.c')
-rw-r--r--rushs/tinyprintf/evalexpr/src/shunting_yard.c199
1 files changed, 0 insertions, 199 deletions
diff --git a/rushs/tinyprintf/evalexpr/src/shunting_yard.c b/rushs/tinyprintf/evalexpr/src/shunting_yard.c
deleted file mode 100644
index 2db5fc8..0000000
--- a/rushs/tinyprintf/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;
-}