Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
12 views5 pages

Source

The document contains a C program that implements a stack-based calculator to evaluate mathematical expressions in Polish notation. It defines structures for tokens, nodes, and stacks, and includes functions for parsing input, handling operators, and calculating results while managing errors such as division by zero and syntax errors. The main function reads an expression, processes it, and outputs the result or an error message if applicable.

Uploaded by

S
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views5 pages

Source

The document contains a C program that implements a stack-based calculator to evaluate mathematical expressions in Polish notation. It defines structures for tokens, nodes, and stacks, and includes functions for parsing input, handling operators, and calculating results while managing errors such as division by zero and syntax errors. The main function reads an expression, processes it, and outputs the result or an error message if applicable.

Uploaded by

S
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

#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;
}

You might also like