diff --git a/.vscode/settings.json b/.vscode/settings.json index 9315955..cb9a69c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,8 @@ "*.gohtml": "html", "stdlib.h": "c", "opd_stack.h": "c", - "stdio.h": "c" + "stdio.h": "c", + "stack.h": "c", + "stddef.h": "c" } } \ No newline at end of file diff --git a/analyzers/polynomials/polynomials.y b/analyzers/polynomials/polynomials.y index beb5b9a..ba8f8c8 100644 --- a/analyzers/polynomials/polynomials.y +++ b/analyzers/polynomials/polynomials.y @@ -1,6 +1,11 @@ %{ +#include "C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\polynomials\stack\stack.h" #include #include +#include + +Element tokens[100]; +int token_count = 0; void yyerror(const char *s); int yylex(void); @@ -8,7 +13,10 @@ int yylex(void); extern FILE* yyin; %} -%union { int num; char var; } +%union { + int num; + char var; +} %token NUMBER %token VARIABLE @@ -22,25 +30,72 @@ input: expr: term - | expr PLUS term { printf("Found operator: +\n"); } - | expr MINUS term { printf("Found operator: -\n"); } + | expr PLUS term { + tokens[token_count].str_ptr = "+"; + tokens[token_count].type = 'o'; + token_count++; + //printf("Found operator: +\n"); + } + | expr MINUS term { + tokens[token_count].str_ptr = "-"; + tokens[token_count].type = 'o'; + token_count++; + //printf("Found operator: -\n"); + } ; term: factor - | term MULTIPLY factor { printf("Found operator: *\n"); } + | term MULTIPLY factor { + tokens[token_count].str_ptr = "*"; + tokens[token_count].type = 'o'; + token_count++; + //printf("Found operator: *\n"); + } ; factor: - NUMBER { printf("Found number: %d\n", $1); } - | VARIABLE { printf("Found variable: %c\n", $1); } + NUMBER { + char* num_str = malloc(20); + sprintf(num_str, "%d", $1); + tokens[token_count].str_ptr = num_str; + tokens[token_count].type = 'n'; + token_count++; + //printf("Found number: %d\n", $1); + } + | VARIABLE { + char* var_str = malloc(2); + var_str[0] = $1; + var_str[1] = '\0'; + tokens[token_count].str_ptr = var_str; + tokens[token_count].type = 'v'; + token_count++; + //printf("Found variable: %c\n", $1); + } | LPAREN expr RPAREN ; %% void yyerror(const char *s) { - fprintf(stderr, "033[91mError: %s\033[0m\n", s); + fprintf(stderr, "\033[91mError: %s\033[0m\n", s); +} + +void print_tokens() { + printf("\nToken sequence:\n"); + printf("Index | Token | Type\n"); + printf("------|-------|-----\n"); + for (int i = 0; i < token_count; i++) { + printf("%5d | %5s | %c\n", i, tokens[i].str_ptr, tokens[i].type); + } +} + +void free_tokens() { + for (int i = 0; i < token_count; i++) { + if (tokens[i].type == 'n' || tokens[i].type == 'v') { + free(tokens[i].str_ptr); + } + } } int main(int argc, char** argv) { @@ -50,7 +105,7 @@ int main(int argc, char** argv) { } FILE* input_file = fopen(argv[1], "r"); if (!input_file) { - perror("033[91mFailed to open input file\033[0m\n"); + perror("\033[91mFailed to open input file\033[0m\n"); return 1; } @@ -58,6 +113,13 @@ int main(int argc, char** argv) { printf("\033[34mParsing expression from file: %s\033[0m\n", argv[1]); yyparse(); + + print_tokens(); + char* res = calulate(tokens, token_count); + printf("Result: %s\n", res); + free(res); + free_tokens(); + fclose(input_file); printf("\033[92mParsing complete\033[0m\n"); return 0; diff --git a/analyzers/polynomials/stacks/stack/stack_test.c b/analyzers/polynomials/stack/stack.c similarity index 57% rename from analyzers/polynomials/stacks/stack/stack_test.c rename to analyzers/polynomials/stack/stack.c index fbb70e2..f27c22a 100644 --- a/analyzers/polynomials/stacks/stack/stack_test.c +++ b/analyzers/polynomials/stack/stack.c @@ -1,27 +1,61 @@ -// калькулятор на основе обратной польской записи - -// gcc stack_test.c stack.c -o stack_test.exe - #include "stack.h" #include #include #include -// Тестирование сценария: -// Токен: 2 -> Стек: [2] -// Токен: 2 -> Стек: [2, 2] -// Токен: 10 -> Стек: [2, 2, 10] -// Токен: 3 -> Стек: [2, 2, 10, 3] -// Токен: - -> Берем 3 и 10: 10-3=7 -> Стек: [2, 2, 7] -// Токен: * -> Берем 7 и 2: 2*7=14 -> Стек: [2, 14] -// Токен: x -> Стек: [2, 14, x] -// Токен: 8 -> Стек: [2, 14, x, 8] -// Токен: - -> Берем 8 и x: x-8 -> Стек: [2, 14, (x-8)] -// Токен: * -> Берем (x-8) и 14: 14*(x-8) -> Стек: [2, (14*(x-8))] -// Токен: + -> Берем (14*(x-8)) и 2: 2+(14*(x-8)) -> Стек: [(2+(14*(x-8)))] -// Ответ: (2+(14*(x-8))) +void initStack(Stack *s) { + s->top = -1; +} -// P.S. и еще нескольких +bool isEmpty(Stack *s) { + return s->top == -1; +} + +bool isFull(Stack *s) { + return s->top == MAX_STACK_SIZE - 1; +} + +bool push(Stack *s, const char *value, char type) { + if (isFull(s)) { + fprintf(stderr, "Stack overflow!\n"); + return false; + } + char *new_str = malloc(strlen(value) + 1); + if (new_str == NULL) { + fprintf(stderr, "Memory allocation failed!\n"); + return false; + } + strcpy(new_str, value); + s->top++; + s->data[s->top].str_ptr = new_str; + s->data[s->top].type = type; + return true; +} + +bool pop(Stack *s, Element *out) { + if (isEmpty(s)) { + fprintf(stderr, "Stack is empty!\n"); + return false; + } + *out = s->data[s->top--]; + return true; +} + +bool peek(Stack *s, Element *out) { + if (isEmpty(s)) { + fprintf(stderr, "Stack is empty!\n"); + return false; + } + *out = s->data[s->top]; + return true; +} + +void clearStack(Stack *s) { + while (s->top >= 0) { + free(s->data[s->top].str_ptr); + s->top--; + } +} char* calulate(Element* tokens, int tokens_count) { #define MAX_ELEMENT_STRING_SIZE 100 @@ -91,43 +125,4 @@ char* calulate(Element* tokens, int tokens_count) { } return NULL; -} - -int main() { - - char* res; - Element tokens[100]; - - tokens[0].str_ptr = "2"; tokens[0].type = 'n'; // number - tokens[1].str_ptr = "2"; tokens[1].type = 'n'; // number - tokens[2].str_ptr = "10"; tokens[2].type = 'n'; // number - tokens[3].str_ptr = "3"; tokens[3].type = 'n'; // number - tokens[4].str_ptr = "-"; tokens[4].type = 'o'; // operator - tokens[5].str_ptr = "*"; tokens[5].type = 'o'; // operator - tokens[6].str_ptr = "x"; tokens[6].type = 'v'; // variable - tokens[7].str_ptr = "8"; tokens[7].type = 'n'; // number - tokens[8].str_ptr = "-"; tokens[8].type = 'o'; // operator - tokens[9].str_ptr = "*"; tokens[9].type = 'o'; // operator - tokens[10].str_ptr = "+"; tokens[10].type = 'o'; // operator - res = calulate(tokens, 11); - printf("Result: %s\n", res); - free(res); - - tokens[0].str_ptr = "2"; tokens[0].type = 'n'; - tokens[1].str_ptr = "2"; tokens[1].type = 'n'; - tokens[2].str_ptr = "+"; tokens[2].type = 'o'; - res = calulate(tokens, 3); - printf("Result: %s\n", res); - free(res); - - tokens[0].str_ptr = "2"; tokens[0].type = 'n'; - tokens[1].str_ptr = "2"; tokens[1].type = 'n'; - tokens[2].str_ptr = "+"; tokens[2].type = 'o'; - tokens[3].str_ptr = "x"; tokens[3].type = 'v'; - tokens[4].str_ptr = "*"; tokens[4].type = 'o'; - res = calulate(tokens, 5); - printf("Result: %s\n", res); - free(res); - - return 0; } \ No newline at end of file diff --git a/analyzers/polynomials/stacks/stack/stack.h b/analyzers/polynomials/stack/stack.h similarity index 91% rename from analyzers/polynomials/stacks/stack/stack.h rename to analyzers/polynomials/stack/stack.h index a500e4c..561cd2d 100644 --- a/analyzers/polynomials/stacks/stack/stack.h +++ b/analyzers/polynomials/stack/stack.h @@ -40,4 +40,7 @@ bool peek(Stack *s, Element *out); // Очистка стека (освобождение памяти) void clearStack(Stack *s); +// Вычисление выражения +char* calulate(Element* tokens, int tokens_count); + #endif // STACK_H \ No newline at end of file diff --git a/analyzers/polynomials/stack/stack_test.c b/analyzers/polynomials/stack/stack_test.c new file mode 100644 index 0000000..5f2ffe0 --- /dev/null +++ b/analyzers/polynomials/stack/stack_test.c @@ -0,0 +1,63 @@ +// калькулятор на основе обратной польской записи + +// gcc stack_test.c stack.c -o stack_test.exe + +#include "stack.h" +#include +#include +#include + +// Тестирование сценария: +// Токен: 2 -> Стек: [2] +// Токен: 2 -> Стек: [2, 2] +// Токен: 10 -> Стек: [2, 2, 10] +// Токен: 3 -> Стек: [2, 2, 10, 3] +// Токен: - -> Берем 3 и 10: 10-3=7 -> Стек: [2, 2, 7] +// Токен: * -> Берем 7 и 2: 2*7=14 -> Стек: [2, 14] +// Токен: x -> Стек: [2, 14, x] +// Токен: 8 -> Стек: [2, 14, x, 8] +// Токен: - -> Берем 8 и x: x-8 -> Стек: [2, 14, (x-8)] +// Токен: * -> Берем (x-8) и 14: 14*(x-8) -> Стек: [2, (14*(x-8))] +// Токен: + -> Берем (14*(x-8)) и 2: 2+(14*(x-8)) -> Стек: [(2+(14*(x-8)))] +// Ответ: (2+(14*(x-8))) + +// P.S. и еще нескольких + +int main() { + + char* res; + Element tokens[100]; + + tokens[0].str_ptr = "2"; tokens[0].type = 'n'; // number + tokens[1].str_ptr = "2"; tokens[1].type = 'n'; // number + tokens[2].str_ptr = "10"; tokens[2].type = 'n'; // number + tokens[3].str_ptr = "3"; tokens[3].type = 'n'; // number + tokens[4].str_ptr = "-"; tokens[4].type = 'o'; // operator + tokens[5].str_ptr = "*"; tokens[5].type = 'o'; // operator + tokens[6].str_ptr = "x"; tokens[6].type = 'v'; // variable + tokens[7].str_ptr = "8"; tokens[7].type = 'n'; // number + tokens[8].str_ptr = "-"; tokens[8].type = 'o'; // operator + tokens[9].str_ptr = "*"; tokens[9].type = 'o'; // operator + tokens[10].str_ptr = "+"; tokens[10].type = 'o'; // operator + res = calulate(tokens, 11); + printf("Result: %s\n", res); + free(res); + + tokens[0].str_ptr = "2"; tokens[0].type = 'n'; + tokens[1].str_ptr = "2"; tokens[1].type = 'n'; + tokens[2].str_ptr = "+"; tokens[2].type = 'o'; + res = calulate(tokens, 3); + printf("Result: %s\n", res); + free(res); + + tokens[0].str_ptr = "2"; tokens[0].type = 'n'; + tokens[1].str_ptr = "2"; tokens[1].type = 'n'; + tokens[2].str_ptr = "+"; tokens[2].type = 'o'; + tokens[3].str_ptr = "x"; tokens[3].type = 'v'; + tokens[4].str_ptr = "*"; tokens[4].type = 'o'; + res = calulate(tokens, 5); + printf("Result: %s\n", res); + free(res); + + return 0; +} \ No newline at end of file diff --git a/analyzers/polynomials/stacks/stack/stack.c b/analyzers/polynomials/stacks/stack/stack.c deleted file mode 100644 index 2e370b4..0000000 --- a/analyzers/polynomials/stacks/stack/stack.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "stack.h" -#include -#include -#include - -void initStack(Stack *s) { - s->top = -1; -} - -bool isEmpty(Stack *s) { - return s->top == -1; -} - -bool isFull(Stack *s) { - return s->top == MAX_STACK_SIZE - 1; -} - -bool push(Stack *s, const char *value, char type) { - if (isFull(s)) { - fprintf(stderr, "Stack overflow!\n"); - return false; - } - char *new_str = malloc(strlen(value) + 1); - if (new_str == NULL) { - fprintf(stderr, "Memory allocation failed!\n"); - return false; - } - strcpy(new_str, value); - s->top++; - s->data[s->top].str_ptr = new_str; - s->data[s->top].type = type; - return true; -} - -bool pop(Stack *s, Element *out) { - if (isEmpty(s)) { - fprintf(stderr, "Stack is empty!\n"); - return false; - } - *out = s->data[s->top--]; - return true; -} - -bool peek(Stack *s, Element *out) { - if (isEmpty(s)) { - fprintf(stderr, "Stack is empty!\n"); - return false; - } - *out = s->data[s->top]; - return true; -} - -void clearStack(Stack *s) { - while (s->top >= 0) { - free(s->data[s->top].str_ptr); - s->top--; - } -} \ No newline at end of file diff --git a/main.py b/main.py index eb02092..15c96be 100644 --- a/main.py +++ b/main.py @@ -6,6 +6,9 @@ import subprocess ANALYZERS_DIR = r'C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\polynomials' FLEX_EXE_PATH = r"C:\tools\win_flex_bison\win_flex.exe" BISON_EXE_PATH = r"C:\tools\win_flex_bison\win_bison.exe" +DEPENDENCY_LIST = [ + r"C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\polynomials\stack\stack.c" +] def main(): # Подготовка путей @@ -13,11 +16,14 @@ def main(): lexical_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.l" syntaxic_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.y" + # Преобразование списка зависимостей в строку для gcc + dependencies_str = ' '.join(DEPENDENCY_LIST) + # Подготовка списка команд cmds = [ f'{FLEX_EXE_PATH} {lexical_analyzer_path}', f'{BISON_EXE_PATH} -d {syntaxic_analyzer_path}', - f'gcc lex.yy.c {analyzer_name}.tab.c -o {analyzer_name}.exe' + fr'gcc lex.yy.c {analyzer_name}.tab.c {dependencies_str} -o {analyzer_name}.exe' ] # Исполнение команд с выводом