diff --git a/analyzers/echo/echo.l b/analyzers/echo/echo.l new file mode 100644 index 0000000..6468f7f --- /dev/null +++ b/analyzers/echo/echo.l @@ -0,0 +1,17 @@ +%{ +#include "echo.tab.h" +#include + +void yyerror(const char *s); + +%} + +%% +[ \t\n]+ { } +[a-zA-Z]+ { yylval.str = strdup(yytext); return TEXT; } +. { yyerror("Unexpected character"); } +%% + +int yywrap() { + return 1; +} diff --git a/analyzers/echo/echo.y b/analyzers/echo/echo.y new file mode 100644 index 0000000..68c1210 --- /dev/null +++ b/analyzers/echo/echo.y @@ -0,0 +1,41 @@ +%{ +#include +#include +#include +#include + +void yyerror(const char *s); +int yylex(void); + +%} + +%union { + char *str; +} + +%token TEXT + +%% + +input: + | poly +; + +poly: + TEXT { + printf($1); + free($1); + exit(1); + } +; + +%% + +void yyerror(const char *s) { + fprintf(stderr, "Error: %s\n", s); +} + +int main() { + yyparse(); + return 0; +} \ No newline at end of file diff --git a/analyzers/polynomials/polynomials.l b/analyzers/polynomials/polynomials.l new file mode 100644 index 0000000..92850c6 --- /dev/null +++ b/analyzers/polynomials/polynomials.l @@ -0,0 +1,21 @@ +%{ +#include "polynomials.tab.h" +#include + +void yyerror(const char *s); +%} + +%option noyywrap + +%% +[ \t]+ { /* skip whitespace */ } +\n { return 0; /* EOF */ } +[0-9]+ { yylval.num = atoi(yytext); return NUMBER; } +[a-zA-Z] { yylval.var = yytext[0]; return VARIABLE; } +"+" { return PLUS; } +"-" { return MINUS; } +"*" { return MULTIPLY; } +"(" { return LPAREN; } +")" { return RPAREN; } +. { yyerror("Unexpected character"); } +%% \ No newline at end of file diff --git a/analyzers/polynomials/polynomials.y b/analyzers/polynomials/polynomials.y new file mode 100644 index 0000000..975d74d --- /dev/null +++ b/analyzers/polynomials/polynomials.y @@ -0,0 +1,48 @@ +%{ +#include +#include + +void yyerror(const char *s); +int yylex(void); +%} + +%union { int num; char var; } + +%token NUMBER +%token VARIABLE +%token LPAREN RPAREN PLUS MINUS MULTIPLY + +%% + +input: + expr { printf("\033[92mParsing complete\033[0m\n"); } +; + +expr: + term + | expr PLUS term { printf("Found operator: +\n"); } + | expr MINUS term { printf("Found operator: -\n"); } +; + +term: + factor + | term MULTIPLY factor { printf("Found operator: *\n"); } +; + +factor: + NUMBER { printf("Found number: %d\n", $1); } + | VARIABLE { printf("Found variable: %c\n", $1); } + | LPAREN expr RPAREN +; + +%% + +void yyerror(const char *s) { + fprintf(stderr, "Error: %s\n", s); +} + +int main() { + printf("Enter a polynomial expression:\n"); + yyparse(); + return 0; +} \ No newline at end of file diff --git a/analyzers/polynomials/test/poly.c b/analyzers/polynomials/test/poly.c new file mode 100644 index 0000000..24c9c22 --- /dev/null +++ b/analyzers/polynomials/test/poly.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include + +// Структура для представления узла выражения +typedef struct Node { + char type; + union { + int num; + char var; + struct { + struct Node *left; + struct Node *right; + } expr; + }; +} Node; + +Node* new_num_node(int num); +Node* new_var_node(char var); +Node* new_expr_node(char type, Node *left, Node *right); +void free_node(Node *node); +void print_node(Node *node); +Node* simplify(Node *node); +Node* parse_expression(char **expr); +Node* parse_term(char **expr); +Node* parse_factor(char **expr); +Node* parse_primary(char **expr); + +// Функция для создания нового узла числа +Node* new_num_node(int num) { + Node *node = (Node*)malloc(sizeof(Node)); + node->type = 'N'; + node->num = num; + return node; +} + +// Функция для создания нового узла переменной +Node* new_var_node(char var) { + Node *node = (Node*)malloc(sizeof(Node)); + node->type = 'V'; + node->var = var; + return node; +} + +// Функция для создания нового узла выражения +Node* new_expr_node(char type, Node *left, Node *right) { + Node *node = (Node*)malloc(sizeof(Node)); + node->type = type; + node->expr.left = left; + node->expr.right = right; + return node; +} + +// Функция для освобождения памяти узла +void free_node(Node *node) { + if (!node) return; + if (node->type == '+' || node->type == '-' || node->type == '*' || node->type == '/' || node->type == '^') { + free_node(node->expr.left); + free_node(node->expr.right); + } + free(node); +} + +// Функция для печати узла (отладочная) +void print_node(Node *node) { + if (!node) return; + switch (node->type) { + case 'N': + printf("%d", node->num); + break; + case 'V': + printf("%c", node->var); + break; + case '+': + case '-': + case '*': + case '/': + case '^': + printf("("); + print_node(node->expr.left); + printf(" %c ", node->type); + print_node(node->expr.right); + printf(")"); + break; + } +} + +// Функция для упрощения выражения +Node* simplify(Node *node) { + if (!node) return NULL; + + if (node->type == '*') { + Node *left = simplify(node->expr.left); + Node *right = simplify(node->expr.right); + + if (left->type == 'N' && right->type == 'N') { + return new_num_node(left->num * right->num); + } else if (left->type == 'N' && left->num == 0) { + return new_num_node(0); + } else if (right->type == 'N' && right->num == 0) { + return new_num_node(0); + } else if (left->type == 'N' && left->num == 1) { + return right; + } else if (right->type == 'N' && right->num == 1) { + return left; + } else if (left->type == 'V' && right->type == 'V' && left->var == right->var) { + return new_expr_node('^', left, new_num_node(2)); + } + + return new_expr_node('*', left, right); + } else if (node->type == '+') { + Node *left = simplify(node->expr.left); + Node *right = simplify(node->expr.right); + + if (left->type == 'N' && right->type == 'N') { + return new_num_node(left->num + right->num); + } else if (left->type == 'N' && left->num == 0) { + return right; + } else if (right->type == 'N' && right->num == 0) { + return left; + } + + return new_expr_node('+', left, right); + } else if (node->type == '-') { + Node *left = simplify(node->expr.left); + Node *right = simplify(node->expr.right); + + if (left->type == 'N' && right->type == 'N') { + return new_num_node(left->num - right->num); + } else if (right->type == 'N' && right->num == 0) { + return left; + } + + return new_expr_node('-', left, right); + } + + return node; +} + +// Функция для парсинга выражения +Node* parse_expression(char **expr) { + Node *left = parse_term(expr); + while (**expr == '+' || **expr == '-') { + char op = *((*expr)++); + Node *right = parse_term(expr); + left = new_expr_node(op, left, right); + } + return left; +} + +// Функция для парсинга терма +Node* parse_term(char **expr) { + Node *left = parse_factor(expr); + while (**expr == '*' || **expr == '/') { + char op = *((*expr)++); + Node *right = parse_factor(expr); + left = new_expr_node(op, left, right); + } + return left; +} + +// Функция для парсинга фактора +Node* parse_factor(char **expr) { + Node *left = parse_primary(expr); + if (**expr == '^') { + *expr += 1; + Node *right = parse_factor(expr); + left = new_expr_node('^', left, right); + } + return left; +} + +// Функция для парсинга первичного выражения +Node* parse_primary(char **expr) { + if (isdigit(**expr)) { + int num = 0; + while (isdigit(**expr)) { + num = num * 10 + *((*expr)++) - '0'; + } + return new_num_node(num); + } else if (isalpha(**expr)) { + char var = *((*expr)++); + return new_var_node(var); + } else if (**expr == '(') { + *expr += 1; + Node *node = parse_expression(expr); + if (**expr == ')') { + *expr += 1; + } + return node; + } + return NULL; +} + +int main() { + char expr[256]; + printf("Enter an expression: "); + fgets(expr, sizeof(expr), stdin); + + char *ptr = expr; + Node *root = parse_expression(&ptr); + + printf("Original expression: "); + print_node(root); + printf("\n"); + + Node *simplified = simplify(root); + + printf("Simplified expression: "); + print_node(simplified); + printf("\n"); + + free_node(root); + free_node(simplified); + return 0; +} diff --git a/main.py b/main.py index 9ad27ae..eb02092 100644 --- a/main.py +++ b/main.py @@ -3,7 +3,7 @@ import subprocess # ЭТИ ПУТИ НАДО ЗАДАТЬ ВРУЧНУЮ # *.l и *.y файлы из директории ANALYZERS_DIR ДОЛЖНЫ НАЗЫВАТЬСЯ как basename этой директории!!! -ANALYZERS_DIR = r'C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\c_analyzer' +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"