From 9a9e9b28f75c3554c950204e1c3859c2e868cd57 Mon Sep 17 00:00:00 2001 From: inex Date: Wed, 6 May 2020 17:55:30 +0300 Subject: [PATCH] Finished task 4, closes #3 --- task4/Makefile | 14 ++++ task4/stacks.c | 116 ++++++++++++++++++++++++++++++ task4/stacks.h | 35 +++++++++ task4/task4.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 352 insertions(+) create mode 100644 task4/Makefile create mode 100644 task4/stacks.c create mode 100644 task4/stacks.h create mode 100644 task4/task4.c diff --git a/task4/Makefile b/task4/Makefile new file mode 100644 index 0000000..a403b81 --- /dev/null +++ b/task4/Makefile @@ -0,0 +1,14 @@ +binary.o: task4.o libstacks.a + gcc -o binary.o task4.o -L. -lstacks + +task4.o: task4.c + gcc -c task4.c + +libstacks.a: stacks.o + ar cr libstacks.a stacks.o + +stacks.o: stacks.c + gcc -c stacks.c + +clean: + rm -f *.o *.a diff --git a/task4/stacks.c b/task4/stacks.c new file mode 100644 index 0000000..7e19422 --- /dev/null +++ b/task4/stacks.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include "stacks.h" + +STACK *init_stack(int size) { + if (size <= 0) { + return NULL; + } + STACK *buf; + buf = malloc(sizeof(STACK)); + if (buf == NULL) { + fprintf(stderr, "Error allocating structure\n"); + return NULL; + } + buf->st = malloc(sizeof(int) * size); + if (buf->st == NULL) { + fprintf(stderr, "Error allocating array\n"); + free(buf); + return NULL; + } + buf->cnt = 0; + buf->size = size; + return buf; +} + +void destroy_stack(STACK *s) { + free(s->st); + free(s); +} + +void push(STACK *st, double val) { + if ((st->cnt) < (st->size)) { + st->st[st->cnt] = val; + (st->cnt)++; + } else { + fprintf(stderr, "Stack is full! Stack size is %d, value to add is %f\n", + st->size, val); + } +} + +double pop(STACK *st) { + if ((st->cnt) > 0) { + (st->cnt)--; + return st->st[st->cnt]; + + } else { + fprintf(stderr, "Attempted to pop an empty stack\n"); + return 0; + } +} + +double top(STACK* st) { + if ((st->cnt) > 0) { + return st->st[(st->cnt)-1]; + } else { + return 0; + } +} + +// char stack + +CHAR_STACK *init_char_stack(int size) { + if (size <= 0) { + return NULL; + } + CHAR_STACK *buf; + buf = malloc(sizeof(CHAR_STACK)); + if (buf == NULL) { + fprintf(stderr, "Error allocating structure\n"); + return NULL; + } + buf->st = malloc(sizeof(int) * size); + if (buf->st == NULL) { + fprintf(stderr, "Error allocating array\n"); + free(buf); + return NULL; + } + buf->cnt = 0; + buf->size = size; + return buf; +} + +void destroy_char_stack(CHAR_STACK *s) { + free(s->st); + free(s); +} + +void char_push(CHAR_STACK *st, char val) { + if ((st->cnt) < (st->size)) { + st->st[st->cnt] = val; + (st->cnt)++; + } else { + fprintf(stderr, "Stack is full! Stack size is %d, value to add is %c\n", + st->size, val); + } +} + +char char_pop(CHAR_STACK *st) { + if ((st->cnt) > 0) { + (st->cnt)--; + return st->st[st->cnt]; + + } else { + fprintf(stderr, "Attempted to pop an empty stack\n"); + return 0; + } +} + +char* char_top(CHAR_STACK* st) { + if ((st->cnt) > 0) { + return &(st->st[(st->cnt)-1]); + } else { + return NULL; + } +} \ No newline at end of file diff --git a/task4/stacks.h b/task4/stacks.h new file mode 100644 index 0000000..b6b0d0f --- /dev/null +++ b/task4/stacks.h @@ -0,0 +1,35 @@ +#include +#include +#include + +typedef struct { + double *st; + int cnt; + int size; +} STACK; + +STACK *init_stack(int size); + +void destroy_stack(STACK *s); + +void push(STACK *st, double val); + +double pop(STACK *st); + +double top(STACK* st); + +typedef struct { + char *st; + int cnt; + int size; +} CHAR_STACK; + +CHAR_STACK *init_char_stack(int size); + +void destroy_char_stack(CHAR_STACK *s); + +void char_push(CHAR_STACK *st, char val); + +char char_pop(CHAR_STACK *st); + +char* char_top(CHAR_STACK* st); \ No newline at end of file diff --git a/task4/task4.c b/task4/task4.c new file mode 100644 index 0000000..cc2b78c --- /dev/null +++ b/task4/task4.c @@ -0,0 +1,187 @@ +#include +#include +#include + +#include "stacks.h" + +void add(STACK *st) { + if ((st->cnt) > 1) { + (st->cnt)--; + st->st[(st->cnt) - 1] = st->st[(st->cnt) - 1] + st->st[st->cnt]; + } else { + fprintf(stderr, "Not enough operands to add\n"); + } +} + +void substract(STACK *st) { + if ((st->cnt) > 1) { + (st->cnt)--; + st->st[(st->cnt) - 1] = st->st[(st->cnt) - 1] - st->st[st->cnt]; + } else { + fprintf(stderr, "Not enough operands to substract\n"); + } +} + +void multiply(STACK *st) { + if ((st->cnt) > 1) { + (st->cnt)--; + st->st[(st->cnt) - 1] = st->st[(st->cnt) - 1] * st->st[st->cnt]; + } else { + fprintf(stderr, "Not enough operands to multiply\n"); + } +} + +void divide(STACK *st) { + if ((st->cnt) > 1) { + (st->cnt)--; + st->st[(st->cnt) - 1] = st->st[(st->cnt) - 1] / st->st[st->cnt]; + } else { + fprintf(stderr, "Not enough operands to divide\n"); + } +} + +int parse(char *s, STACK *stack) { + double operand = 0; + char *endptr; + if ((*s == '-') && (*(s + 1) == '\0')) { + substract(stack); + return 0; + } else if (*s == '+') { + add(stack); + return 0; + } else if (*s == '/') { + if ((stack->st[(stack->cnt) - 1]) == 0) { + return -2; + } + divide(stack); + return 0; + } else if (*s == 'x') { + multiply(stack); + return 0; + } + errno = 0; + operand = strtod(s, &endptr); + if (errno != 0 || *endptr != '\0') + return -1; + push(stack, operand); + return 0; +} + +int sorting_station(STACK *operands, CHAR_STACK *operators, char *token) { + int error; + if (((*token == '-') && (*(token + 1) == '\0')) || (*token == '+') || + (*token == 'x') || (*token == '/')) { + if (char_top(operators) != NULL) { + switch (*char_top(operators)) { + case '[': + char_push(operators, *token); + break; + case '+': + case '-': + if (*token == '/' || *token == 'x') { + char_push(operators, *token); + break; + } + case 'x': + case '/': + if (*token == '/' || *token == 'x') { + while (char_top(operators) != NULL && (*char_top(operators) == '/' || *char_top(operators) == 'x')) { + error = parse(char_top(operators), operands); + if (error != 0) { + return error; + } + char_pop(operators); + } + char_push(operators, *token); + break; + } else { + while (char_top(operators) != NULL && *char_top(operators) != '[') { + error = parse(char_top(operators), operands); + if (error != 0) { + return error; + } + char_pop(operators); + } + char_push(operators, *token); + break; + } + } + return (0); + } else { + char_push(operators, *token); + return (0); + } + } + + if (*token == '[') { + char_push(operators, *token); + return (0); + } + + if (*token == ']') { + while (char_top(operators) != NULL && *char_top(operators) != '[') { + error = parse(char_top(operators), operands); + if (error != 0) { + return error; + } + char_pop(operators); + } + if (char_top(operators) == NULL) { + fprintf(stderr, "Opening bracket not found!\n"); + return (-3); + } else { + char_pop(operators); + return (0); + } + } + + error = parse(token, operands); + return (error); +} + +int main(int argc, char **argv) { + STACK *operands = init_stack(argc); + CHAR_STACK *operators = init_char_stack(argc); + + if (operands == NULL) { + fprintf(stderr, "Error creating operand stack.\n"); + return (2); + } + if (operators == NULL) { + fprintf(stderr, "Error creating operator stack.\n"); + return (2); + } + int error; + while (*++argv) { + error = sorting_station(operands, operators, *argv); + if (error == -1) { + fprintf(stderr, "Error parsing operand.\n"); + return (1); + } else if (error == -2) { + fprintf(stderr, "Division by zero!"); + return (2); + } else if (error == -3) { + return (3); + } + } + + while (char_top(operators) != NULL) { + error = parse(char_top(operators), operands); + if (error == -1) { + fprintf(stderr, "Error parsing operand.\n"); + return (1); + } else if (error == -2) { + fprintf(stderr, "Division by zero!"); + return (2); + } + char_pop(operators); + } + + int i; + printf("Stack status:\n"); + for (i = (operands->cnt); i > 0; i--) + printf("%f\n", pop(operands)); + destroy_stack(operands); + destroy_char_stack(operators); + return 0; +}