From 48448091d63007a41632eb99543109a3d08a1be2 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 20 Oct 2025 19:45:52 +0300 Subject: [PATCH 1/5] Add stack struct --- HW4/modules/stack/stack.c | 37 +++++++++++++++++++++++++++++++++++++ HW4/modules/stack/stack.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 HW4/modules/stack/stack.c create mode 100644 HW4/modules/stack/stack.h diff --git a/HW4/modules/stack/stack.c b/HW4/modules/stack/stack.c new file mode 100644 index 0000000..ac95e12 --- /dev/null +++ b/HW4/modules/stack/stack.c @@ -0,0 +1,37 @@ +#include "stack.h" +#include +#include + +int pushToStack(char data, Stack **head) { + Stack *newNode = + (Stack *)malloc(sizeof(Stack)); + if (newNode == NULL) + return -1; + else { + newNode->data = data; + newNode->next = *head; + *head = newNode; + return 0; + } +} + +char popFromStack(Stack **head) { + if (*head == NULL) + return '\0'; + + Stack *lastNode = *head; + char lastNodeData = lastNode->data; + *head = (*head)->next; + free(lastNode); + return lastNodeData; +} + +void freeStack(Stack *head) { + Stack *current = head; + while (current != NULL) { + Stack *next = current->next; + free(current); + current = next; + } +} + diff --git a/HW4/modules/stack/stack.h b/HW4/modules/stack/stack.h new file mode 100644 index 0000000..516ce3c --- /dev/null +++ b/HW4/modules/stack/stack.h @@ -0,0 +1,28 @@ +#pragma once + +typedef struct Stack { + char data; + struct Stack *next; +} Stack; + +/** + * @brief Push element to stack + * @param data Character to push + * @param head Pointer to pointer of stack head + * @return -1 if couldn't allocate memory, 0 otherwise + */ +int pushToStack(char data, Stack **head); + +/** + * @brief Pop element from stack + * @param head Pointer to pointer of stack head + * @return Popped character or '\0' if stack is empty + */ +char popFromStack(Stack **head); + +/** + * @brief Free all stack memory + * @param head Pointer to stack head + */ +void freeStack(Stack *head); + From 97bbe1af023f4964b4c910d48619d2ce68528d7b Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 20 Oct 2025 19:46:21 +0300 Subject: [PATCH 2/5] Add queue struct --- HW4/modules/queue/queue.c | 39 +++++++++++++++++++++++++++++++++++++++ HW4/modules/queue/queue.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 HW4/modules/queue/queue.c create mode 100644 HW4/modules/queue/queue.h diff --git a/HW4/modules/queue/queue.c b/HW4/modules/queue/queue.c new file mode 100644 index 0000000..f1603aa --- /dev/null +++ b/HW4/modules/queue/queue.c @@ -0,0 +1,39 @@ +#include "queue.h" +#include +#include + +int pushToQueue(char data, Queue **head, Queue **tail) { + Queue *newQueueNode = (Queue *)malloc(sizeof(Queue)); + if (newQueueNode == NULL) + return -1; + + newQueueNode->data = data; + newQueueNode->next = NULL; + + if (*head == NULL) { + *head = newQueueNode; + *tail = newQueueNode; + } else { + (*tail)->next = newQueueNode; + *tail = newQueueNode; + } + return 0; +} + +void printQueue(Queue *head) { + while (head != NULL) { + printf("%c ", head->data); + head = head->next; + } + printf("\n"); +} + +void freeQueue(Queue *head) { + Queue *current = head; + while (current != NULL) { + Queue *next = current->next; + free(current); + current = next; + } +} + diff --git a/HW4/modules/queue/queue.h b/HW4/modules/queue/queue.h new file mode 100644 index 0000000..b63f5e2 --- /dev/null +++ b/HW4/modules/queue/queue.h @@ -0,0 +1,28 @@ +#pragma once + +typedef struct Queue { + char data; + struct Queue *next; +} Queue; + +/** + * @brief Push element to queue + * @param data Character to push + * @param head Pointer to pointer of queue head + * @param tail Pointer to pointer of queue tail + * @return -1 if couldn't allocate memory, 0 otherwise + */ +int pushToQueue(char data, Queue **head, Queue **tail); + +/** + * @brief Print all elements in queue + * @param head Pointer to queue head + */ +void printQueue(Queue *head); + +/** + * @brief Free all queue memory + * @param head Pointer to queue head + */ +void freeQueue(Queue *head); + From a055e3d2251c3f11f5ec764c66219e71bcd4c48a Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 19 Oct 2025 21:17:08 +0300 Subject: [PATCH 3/5] Add shunting yard algorithm --- HW4/ShuntingYard/src/main.c | 220 ++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 HW4/ShuntingYard/src/main.c diff --git a/HW4/ShuntingYard/src/main.c b/HW4/ShuntingYard/src/main.c new file mode 100644 index 0000000..571fffd --- /dev/null +++ b/HW4/ShuntingYard/src/main.c @@ -0,0 +1,220 @@ +#include +#include +#include + +typedef struct OperationStack { + char operation; + struct OperationStack *next; +} OperationStack; + +int pushToStack(char operation, OperationStack **head); +char popFromStack(OperationStack **head); +void freeStack(OperationStack *head); + +typedef struct OutputQueue { + char token; + struct OutputQueue *next; +} OutputQueue; + +int pushToQueue(char token, OutputQueue **head, OutputQueue **tail); +void printQueue(OutputQueue *head); +void freeQueue(OutputQueue *head); + +int getPrecedence(char operation); +void shuntingYard(const char *expression); + +int main() { + shuntingYard("1 + 1"); + shuntingYard("(1 + 1) * 2"); + shuntingYard("1 + 1 * 2"); + shuntingYard("3 + 4 * 2 / (1 - 5)"); + shuntingYard("1 + 2 + (3 + 4)"); + return 0; +} + +int pushToStack(char operation, OperationStack **head) { + OperationStack *newOperation = + (OperationStack *)malloc(sizeof(OperationStack)); + if (newOperation == NULL) + return -1; + else { + newOperation->operation = operation; + newOperation->next = *head; + *head = newOperation; + return 0; + } +} + +char popFromStack(OperationStack **head) { + if (*head == NULL) + return '\0'; + + OperationStack *lastEl = *head; + char lastElOperation = lastEl->operation; + *head = (*head)->next; + free(lastEl); + return lastElOperation; +} + +void freeStack(OperationStack *head) { + OperationStack *current = head; + while (current != NULL) { + OperationStack *next = current->next; + free(current); + current = next; + } +} + +int pushToQueue(char token, OutputQueue **head, OutputQueue **tail) { + OutputQueue *newQueueToken = (OutputQueue *)malloc(sizeof(OutputQueue)); + if (newQueueToken == NULL) + return -1; + + newQueueToken->token = token; + newQueueToken->next = NULL; + + if (*head == NULL) { + *head = newQueueToken; + *tail = newQueueToken; + } else { + (*tail)->next = newQueueToken; + *tail = newQueueToken; + } + return 0; +} + +void printQueue(OutputQueue *head) { + while (head != NULL) { + printf("%c ", head->token); + head = head->next; + } + printf("\n"); +} + +void freeQueue(OutputQueue *head) { + OutputQueue *current = head; + while (current != NULL) { + OutputQueue *next = current->next; + free(current); + current = next; + } +} + +int getPrecedence(char operation) { + if (operation == '/' operation == '*') + return 1; + else if (operation == '-' operation == '+') + return 0; + else + return -1; +} + +void shuntingYard(const char *expression) { + OperationStack *stackHead = NULL; + OutputQueue *queueHead = NULL; + OutputQueue *queueTail = NULL; + int errorCode = 0; + + for (int i = 0; expression[i] != '\0'; ++i) { + char currChar = expression[i]; + + Данил, [19.10.2025 20:57] if (isdigit(currChar)) { + errorCode = pushToQueue(currChar, &queueHead, &queueTail); + if (errorCode == -1) { + printf("Error: couldn't allocate memory\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + else if (currChar == '+' currChar == '-' currChar == '*' || + currChar == '/') { + while (stackHead != NULL && + getPrecedence(currChar) <= + getPrecedence(stackHead->operation)) { + char lastStackOp = popFromStack(&stackHead); + if (lastStackOp == '\0') { + printf("Error: trying to put empty operation into queue\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + errorCode = pushToQueue(lastStackOp, &queueHead, &queueTail); + if (errorCode == -1) { + printf("Error: couldn't allocate memory\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + errorCode = pushToStack(currChar, &stackHead); + if (errorCode == -1) { + printf("Error: couldn't allocate memory\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + else if (currChar == '(') { + errorCode = pushToStack(currChar, &stackHead); + if (errorCode == -1) { + printf("Error: couldn't allocate memory\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + else if (currChar == ')') { + while (stackHead != NULL && stackHead->operation != '(') { + char lastStackOp = popFromStack(&stackHead); + if (lastStackOp == '\0') { + printf("Error: trying to put empty operation into queue\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + errorCode = pushToQueue(lastStackOp, &queueHead, &queueTail); + if (errorCode == -1) { + printf("Error: couldn't allocate memory\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + if (popFromStack(&stackHead) != '(') { + printf("Error: mismatched parentheses\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + else if (currChar != ' ') { + printf("Error: wrong math expression\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + while (stackHead != NULL) { + char lastStackOp = popFromStack(&stackHead); + if (lastStackOp == '\0') { + printf("Error: trying to put empty operation into queue\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + errorCode = pushToQueue(lastStackOp, &queueHead, &queueTail); + if (errorCode == -1) { + printf("Error: couldn't allocate memory\n"); + freeQueue(queueHead); + freeStack(stackHead); + return; + } + } + + printQueue(queueHead); + freeQueue(queueHead); + freeStack(stackHead); + return; +} + From 3419ae746ef4ca85b6594fc02305545309b4f5c8 Mon Sep 17 00:00:00 2001 From: Dan Date: Sun, 19 Oct 2025 21:40:55 +0300 Subject: [PATCH 4/5] Format main.c --- HW4/ShuntingYard/src/main.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/HW4/ShuntingYard/src/main.c b/HW4/ShuntingYard/src/main.c index 571fffd..15a1acc 100644 --- a/HW4/ShuntingYard/src/main.c +++ b/HW4/ShuntingYard/src/main.c @@ -101,9 +101,9 @@ void freeQueue(OutputQueue *head) { } int getPrecedence(char operation) { - if (operation == '/' operation == '*') + if (operation == '/' || operation == '*') return 1; - else if (operation == '-' operation == '+') + else if (operation == '-' || operation == '+') return 0; else return -1; @@ -118,7 +118,7 @@ void shuntingYard(const char *expression) { for (int i = 0; expression[i] != '\0'; ++i) { char currChar = expression[i]; - Данил, [19.10.2025 20:57] if (isdigit(currChar)) { + if (isdigit(currChar)) { errorCode = pushToQueue(currChar, &queueHead, &queueTail); if (errorCode == -1) { printf("Error: couldn't allocate memory\n"); @@ -126,9 +126,8 @@ void shuntingYard(const char *expression) { freeStack(stackHead); return; } - } - else if (currChar == '+' currChar == '-' currChar == '*' || - currChar == '/') { + } else if (currChar == '+' || currChar == '-' || currChar == '*' || + currChar == '/') { while (stackHead != NULL && getPrecedence(currChar) <= getPrecedence(stackHead->operation)) { @@ -154,8 +153,7 @@ void shuntingYard(const char *expression) { freeStack(stackHead); return; } - } - else if (currChar == '(') { + } else if (currChar == '(') { errorCode = pushToStack(currChar, &stackHead); if (errorCode == -1) { printf("Error: couldn't allocate memory\n"); @@ -163,8 +161,7 @@ void shuntingYard(const char *expression) { freeStack(stackHead); return; } - } - else if (currChar == ')') { + } else if (currChar == ')') { while (stackHead != NULL && stackHead->operation != '(') { char lastStackOp = popFromStack(&stackHead); if (lastStackOp == '\0') { @@ -187,8 +184,7 @@ void shuntingYard(const char *expression) { freeStack(stackHead); return; } - } - else if (currChar != ' ') { + } else if (currChar != ' ') { printf("Error: wrong math expression\n"); freeQueue(queueHead); freeStack(stackHead); From 3a69f1a33594233606840c94c70fa9756349289c Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 20 Oct 2025 20:00:23 +0300 Subject: [PATCH 5/5] Add shunting yard algorithm --- HW4/ShuntingYard/src/main.c | 120 +++++------------------------------- 1 file changed, 17 insertions(+), 103 deletions(-) diff --git a/HW4/ShuntingYard/src/main.c b/HW4/ShuntingYard/src/main.c index 15a1acc..5b66dcd 100644 --- a/HW4/ShuntingYard/src/main.c +++ b/HW4/ShuntingYard/src/main.c @@ -1,27 +1,10 @@ +#include "../../modules/queue/queue.h" +#include "../../modules/stack/stack.h" #include #include -#include -typedef struct OperationStack { - char operation; - struct OperationStack *next; -} OperationStack; - -int pushToStack(char operation, OperationStack **head); -char popFromStack(OperationStack **head); -void freeStack(OperationStack *head); - -typedef struct OutputQueue { - char token; - struct OutputQueue *next; -} OutputQueue; - -int pushToQueue(char token, OutputQueue **head, OutputQueue **tail); -void printQueue(OutputQueue *head); -void freeQueue(OutputQueue *head); - -int getPrecedence(char operation); void shuntingYard(const char *expression); +int getPrecedence(char operation); int main() { shuntingYard("1 + 1"); @@ -32,87 +15,10 @@ int main() { return 0; } -int pushToStack(char operation, OperationStack **head) { - OperationStack *newOperation = - (OperationStack *)malloc(sizeof(OperationStack)); - if (newOperation == NULL) - return -1; - else { - newOperation->operation = operation; - newOperation->next = *head; - *head = newOperation; - return 0; - } -} - -char popFromStack(OperationStack **head) { - if (*head == NULL) - return '\0'; - - OperationStack *lastEl = *head; - char lastElOperation = lastEl->operation; - *head = (*head)->next; - free(lastEl); - return lastElOperation; -} - -void freeStack(OperationStack *head) { - OperationStack *current = head; - while (current != NULL) { - OperationStack *next = current->next; - free(current); - current = next; - } -} - -int pushToQueue(char token, OutputQueue **head, OutputQueue **tail) { - OutputQueue *newQueueToken = (OutputQueue *)malloc(sizeof(OutputQueue)); - if (newQueueToken == NULL) - return -1; - - newQueueToken->token = token; - newQueueToken->next = NULL; - - if (*head == NULL) { - *head = newQueueToken; - *tail = newQueueToken; - } else { - (*tail)->next = newQueueToken; - *tail = newQueueToken; - } - return 0; -} - -void printQueue(OutputQueue *head) { - while (head != NULL) { - printf("%c ", head->token); - head = head->next; - } - printf("\n"); -} - -void freeQueue(OutputQueue *head) { - OutputQueue *current = head; - while (current != NULL) { - OutputQueue *next = current->next; - free(current); - current = next; - } -} - -int getPrecedence(char operation) { - if (operation == '/' || operation == '*') - return 1; - else if (operation == '-' || operation == '+') - return 0; - else - return -1; -} - void shuntingYard(const char *expression) { - OperationStack *stackHead = NULL; - OutputQueue *queueHead = NULL; - OutputQueue *queueTail = NULL; + Stack *stackHead = NULL; + Queue *queueHead = NULL; + Queue *queueTail = NULL; int errorCode = 0; for (int i = 0; expression[i] != '\0'; ++i) { @@ -129,8 +35,7 @@ void shuntingYard(const char *expression) { } else if (currChar == '+' || currChar == '-' || currChar == '*' || currChar == '/') { while (stackHead != NULL && - getPrecedence(currChar) <= - getPrecedence(stackHead->operation)) { + getPrecedence(currChar) <= getPrecedence(stackHead->data)) { char lastStackOp = popFromStack(&stackHead); if (lastStackOp == '\0') { printf("Error: trying to put empty operation into queue\n"); @@ -162,7 +67,7 @@ void shuntingYard(const char *expression) { return; } } else if (currChar == ')') { - while (stackHead != NULL && stackHead->operation != '(') { + while (stackHead != NULL && stackHead->data != '(') { char lastStackOp = popFromStack(&stackHead); if (lastStackOp == '\0') { printf("Error: trying to put empty operation into queue\n"); @@ -214,3 +119,12 @@ void shuntingYard(const char *expression) { return; } +int getPrecedence(char operation) { + if (operation == '/' || operation == '*') + return 1; + else if (operation == '-' || operation == '+') + return 0; + else + return -1; +} +