#include <stdio.
h>
#include <string.h>
#define MAX_INPUT_SIZE 1005
typedef struct Node Node;
typedef struct Stack Stack;
typedef struct Token Token;
typedef enum TYPE TYPE;
enum TYPE {
NUMBER,
OPER,
RIGHT_BRACKET,
LEFT_BRACKET,
UNDEFINED
};
struct Token {
int val;
TYPE type;
};
struct Node {
Node* next;
Token x;
};
struct Stack {
size_t size;
Node* top;
};
Node* create_node(int val, TYPE type) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->next = NULL;
new_node->x.type = type;
new_node->x.val = val;
return new_node;
}
Stack* empty_stack() {
Stack* new_stack = (Stack*)malloc(sizeof(Stack));
new_stack->size = 0;
new_stack->top = NULL;
}
void push(Node* x, Stack* stack) {
stack->size++;
x->next = stack->top;
stack->top = x;
}
Token pop(Stack* stack) {
if (stack->size == 0)return;
stack->size--;
Node* buf = stack->top;
Token result = buf->x;
stack->top = stack->top->next;
free(buf);
return result;
}
int is_digit(char c) {
if (c >= '0' && c <= '9')return 1;
return 0;
}
void delete_stack(Stack* stack) {
while (stack->size > 0) {
pop(stack);
}
free(stack);
}
int chr_to_int(char c) {
return c - '0';
}
int correct_chr(char c) {
if (c == '(' || c == ')' || c == '*' || c == '/' || c == '+' || c ==
'-')return 1;
return 0;
}
int oper_priority(char c) {
if (c == '(')return 0;
if (c == '+' || c == '-')return 1;
if (c == '*' || c == '/')return 2;
}
Token* input_to_pol_notation(char* input, int *error_type) {
Token* pol_not = (Token*)malloc(sizeof(Token)*MAX_INPUT_SIZE);
//!!!!!!!!!
for (size_t i = 0; i < MAX_INPUT_SIZE; i++) {
pol_not[i].type = UNDEFINED;
}
Stack* operators = empty_stack();
size_t input_len = strlen(input);
if (input[input_len - 1] == '\n')input[input_len--] = '\0';
int count = 0;
int number = 0;
TYPE last_type = UNDEFINED;
int k = 0;
for (size_t i = 0; i < input_len; i++) {
if (is_digit(input[i])) {
if (last_type != NUMBER) {
last_type = NUMBER;
k = chr_to_int(input[i]);
}
else {
k = k * 10 + chr_to_int(input[i]);
}
if (i + 1 != input_len && is_digit(input[i + 1]))continue;
else {
pol_not[count].type = NUMBER;
pol_not[count++].val = k;
k = 0;
continue;
}
}
if (correct_chr(input[i])) {
if (input[i] == '(') {
if (last_type != RIGHT_BRACKET && last_type != NUMBER) {
last_type = LEFT_BRACKET;
push(create_node(input[i], OPER), operators);
}
else {
*error_type = 2;
delete_stack(operators);
return pol_not;
}
}
else if (input[i] == ')') {
while (operators->size > 0 && operators->top->x.val != '(')
{
pol_not[count++] = pop(operators);
}
if (operators->size > 0 && (last_type == NUMBER ||
last_type == RIGHT_BRACKET)) {
pop(operators);
last_type = RIGHT_BRACKET;
}
else {
*error_type = 2;
delete_stack(operators);
return pol_not;
}
}
else {
if (last_type != NUMBER && last_type != RIGHT_BRACKET) {
*error_type = 2;
delete_stack(operators);
return pol_not;
}
last_type = OPER;
while (operators->size > 0 && oper_priority(operators->top-
>x.val) >= oper_priority(input[i])) {
pol_not[count++] = pop(operators);
}
push(create_node(input[i], OPER), operators);
}
}
else {
*error_type = 2;
delete_stack(operators);
return pol_not;
}
}
while (operators->size > 0) {
pol_not[count++] = pop(operators);
}
delete_stack(operators);
return pol_not;
}
int use_operator(char c, int a, int b, int *error_type) {
if (c == '+')return a + b;
if (c == '-')return a - b;
if (c == '*')return a*b;
if (c == '/') {
if (b == 0) {
*error_type = 1;
return 0;
}
return a / b;
}
*error_type = 2;
return 0;
}
int get_result(Token* pol_not, int *error_type) {
int pos = 0;
Stack *operands = empty_stack();
while (pol_not[pos].type != UNDEFINED) {
if (pol_not[pos].type == NUMBER) {
push(create_node(pol_not[pos].val, pol_not[pos].type), operands);
}
if (pol_not[pos].type == OPER) {
int a, b;
if (operands->size >= 2) {
b = pop(operands).val;
a = pop(operands).val;
}
else {
*error_type = 2;
delete_stack(operands);
return 0;
}
int c = use_operator(pol_not[pos].val, a, b, error_type);
if (*error_type == 1) {
delete_stack(operands);
return 0;
}
push(create_node(c, NUMBER), operands);
}
pos++;
}
if (operands->size != 1) {
*error_type = 2;
delete_stack(operands);
return 0;
}
else {
int result = pop(operands).val;
delete_stack(operands);
return result;
}
}
int check_errors(int *error_type, Token* pol_not) {
if (*error_type == 1) {
printf("division by zero");
free(pol_not);
return 1;
}
if (*error_type == 2) {
printf("syntax error");
free(pol_not);
return 1;
}
return 0;
}
int main() {
char input[MAX_INPUT_SIZE];
fgets(input, MAX_INPUT_SIZE - 1, stdin);
int error_type = 0;
Token* pol_not = input_to_pol_notation(input, &error_type);
if (check_errors(&error_type, pol_not))return 0;
int result = get_result(pol_not, &error_type);
if (check_errors(&error_type, pol_not))return 0;
printf("%d", result);
free(pol_not);
return 0;
}