разбро обратной польской встроил в polynomials.y

master
serr 2025-04-29 23:58:45 +03:00
parent d59a177dc2
commit 1e6de33b27
7 changed files with 198 additions and 125 deletions

View File

@ -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"
}
}

View File

@ -1,6 +1,11 @@
%{
#include "C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\polynomials\stack\stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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 <num> NUMBER
%token <var> 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;

View File

@ -1,27 +1,61 @@
// калькулятор на основе обратной польской записи
// gcc stack_test.c stack.c -o stack_test.exe
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Тестирование сценария:
// Токен: 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
@ -92,42 +126,3 @@ 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;
}

View File

@ -40,4 +40,7 @@ bool peek(Stack *s, Element *out);
// Очистка стека (освобождение памяти)
void clearStack(Stack *s);
// Вычисление выражения
char* calulate(Element* tokens, int tokens_count);
#endif // STACK_H

View File

@ -0,0 +1,63 @@
// калькулятор на основе обратной польской записи
// gcc stack_test.c stack.c -o stack_test.exe
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Тестирование сценария:
// Токен: 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;
}

View File

@ -1,58 +0,0 @@
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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--;
}
}

View File

@ -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'
]
# Исполнение команд с выводом