разбро обратной польской встроил в polynomials.y
parent
d59a177dc2
commit
1e6de33b27
|
@ -4,6 +4,8 @@
|
||||||
"*.gohtml": "html",
|
"*.gohtml": "html",
|
||||||
"stdlib.h": "c",
|
"stdlib.h": "c",
|
||||||
"opd_stack.h": "c",
|
"opd_stack.h": "c",
|
||||||
"stdio.h": "c"
|
"stdio.h": "c",
|
||||||
|
"stack.h": "c",
|
||||||
|
"stddef.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,11 @@
|
||||||
%{
|
%{
|
||||||
|
#include "C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\polynomials\stack\stack.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
Element tokens[100];
|
||||||
|
int token_count = 0;
|
||||||
|
|
||||||
void yyerror(const char *s);
|
void yyerror(const char *s);
|
||||||
int yylex(void);
|
int yylex(void);
|
||||||
|
@ -8,7 +13,10 @@ int yylex(void);
|
||||||
extern FILE* yyin;
|
extern FILE* yyin;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union { int num; char var; }
|
%union {
|
||||||
|
int num;
|
||||||
|
char var;
|
||||||
|
}
|
||||||
|
|
||||||
%token <num> NUMBER
|
%token <num> NUMBER
|
||||||
%token <var> VARIABLE
|
%token <var> VARIABLE
|
||||||
|
@ -22,25 +30,72 @@ input:
|
||||||
|
|
||||||
expr:
|
expr:
|
||||||
term
|
term
|
||||||
| expr PLUS term { printf("Found operator: +\n"); }
|
| expr PLUS term {
|
||||||
| expr MINUS term { printf("Found operator: -\n"); }
|
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:
|
term:
|
||||||
factor
|
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:
|
factor:
|
||||||
NUMBER { printf("Found number: %d\n", $1); }
|
NUMBER {
|
||||||
| VARIABLE { printf("Found variable: %c\n", $1); }
|
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
|
| LPAREN expr RPAREN
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
void yyerror(const char *s) {
|
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) {
|
int main(int argc, char** argv) {
|
||||||
|
@ -50,7 +105,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
FILE* input_file = fopen(argv[1], "r");
|
FILE* input_file = fopen(argv[1], "r");
|
||||||
if (!input_file) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +113,13 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
printf("\033[34mParsing expression from file: %s\033[0m\n", argv[1]);
|
printf("\033[34mParsing expression from file: %s\033[0m\n", argv[1]);
|
||||||
yyparse();
|
yyparse();
|
||||||
|
|
||||||
|
print_tokens();
|
||||||
|
char* res = calulate(tokens, token_count);
|
||||||
|
printf("Result: %s\n", res);
|
||||||
|
free(res);
|
||||||
|
free_tokens();
|
||||||
|
|
||||||
fclose(input_file);
|
fclose(input_file);
|
||||||
printf("\033[92mParsing complete\033[0m\n");
|
printf("\033[92mParsing complete\033[0m\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,27 +1,61 @@
|
||||||
// калькулятор на основе обратной польской записи
|
|
||||||
|
|
||||||
// gcc stack_test.c stack.c -o stack_test.exe
|
|
||||||
|
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// Тестирование сценария:
|
void initStack(Stack *s) {
|
||||||
// Токен: 2 -> Стек: [2]
|
s->top = -1;
|
||||||
// Токен: 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. и еще нескольких
|
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) {
|
char* calulate(Element* tokens, int tokens_count) {
|
||||||
#define MAX_ELEMENT_STRING_SIZE 100
|
#define MAX_ELEMENT_STRING_SIZE 100
|
||||||
|
@ -91,43 +125,4 @@ char* calulate(Element* tokens, int tokens_count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
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;
|
|
||||||
}
|
}
|
|
@ -40,4 +40,7 @@ bool peek(Stack *s, Element *out);
|
||||||
// Очистка стека (освобождение памяти)
|
// Очистка стека (освобождение памяти)
|
||||||
void clearStack(Stack *s);
|
void clearStack(Stack *s);
|
||||||
|
|
||||||
|
// Вычисление выражения
|
||||||
|
char* calulate(Element* tokens, int tokens_count);
|
||||||
|
|
||||||
#endif // STACK_H
|
#endif // STACK_H
|
|
@ -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;
|
||||||
|
}
|
|
@ -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--;
|
|
||||||
}
|
|
||||||
}
|
|
8
main.py
8
main.py
|
@ -6,6 +6,9 @@ import subprocess
|
||||||
ANALYZERS_DIR = r'C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\polynomials'
|
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"
|
FLEX_EXE_PATH = r"C:\tools\win_flex_bison\win_flex.exe"
|
||||||
BISON_EXE_PATH = r"C:\tools\win_flex_bison\win_bison.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():
|
def main():
|
||||||
# Подготовка путей
|
# Подготовка путей
|
||||||
|
@ -13,11 +16,14 @@ def main():
|
||||||
lexical_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.l"
|
lexical_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.l"
|
||||||
syntaxic_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.y"
|
syntaxic_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.y"
|
||||||
|
|
||||||
|
# Преобразование списка зависимостей в строку для gcc
|
||||||
|
dependencies_str = ' '.join(DEPENDENCY_LIST)
|
||||||
|
|
||||||
# Подготовка списка команд
|
# Подготовка списка команд
|
||||||
cmds = [
|
cmds = [
|
||||||
f'{FLEX_EXE_PATH} {lexical_analyzer_path}',
|
f'{FLEX_EXE_PATH} {lexical_analyzer_path}',
|
||||||
f'{BISON_EXE_PATH} -d {syntaxic_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'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Исполнение команд с выводом
|
# Исполнение команд с выводом
|
||||||
|
|
Loading…
Reference in New Issue