Finished task 4, closes #3
This commit is contained in:
parent
0183aea610
commit
9a9e9b28f7
14
task4/Makefile
Normal file
14
task4/Makefile
Normal file
|
@ -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
|
116
task4/stacks.c
Normal file
116
task4/stacks.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#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;
|
||||
}
|
||||
}
|
35
task4/stacks.h
Normal file
35
task4/stacks.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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);
|
187
task4/task4.c
Normal file
187
task4/task4.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
Loading…
Reference in a new issue