157 lines
3.8 KiB
Plaintext
157 lines
3.8 KiB
Plaintext
%{
|
||
#include "C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\flex_bison_test\analyzers\polynomials\poly_calc\poly_calc.h"
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
void yyerror(const char *s);
|
||
int yylex();
|
||
|
||
extern FILE *yyin;
|
||
extern char allowed_variable;
|
||
|
||
typedef struct {
|
||
char name;
|
||
Polynomial poly;
|
||
} Variable;
|
||
|
||
Variable variables[26];
|
||
int variables_count = 0;
|
||
|
||
Polynomial* find_variable(char name) {
|
||
for (int i = 0; i < variables_count; i++) {
|
||
if (variables[i].name == name) {
|
||
return &variables[i].poly;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
void add_variable(char name, Polynomial poly) {
|
||
Polynomial* existing = find_variable(name);
|
||
if (existing) {
|
||
free_polynomial(existing);
|
||
*existing = poly;
|
||
} else {
|
||
variables[variables_count].name = name;
|
||
variables[variables_count].poly = poly;
|
||
variables_count++;
|
||
}
|
||
}
|
||
%}
|
||
|
||
%union {
|
||
Polynomial poly;
|
||
char var_name;
|
||
}
|
||
|
||
%token SEMICOLON PRINT EQUAL
|
||
%token <var_name> VAR_POLY
|
||
%token <poly> NUMBER VARIABLE
|
||
%type <poly> expr
|
||
|
||
%left '+' '-'
|
||
%left '*' '/'
|
||
%left UMINUS
|
||
%right '^'
|
||
|
||
%%
|
||
input:
|
||
| input line
|
||
;
|
||
|
||
line: expr SEMICOLON {
|
||
sort_polynomial(&$1);
|
||
free_polynomial(&$1);
|
||
}
|
||
| PRINT expr SEMICOLON {
|
||
printf("Result: ");
|
||
sort_polynomial(&$2);
|
||
print_polynomial(&$2, allowed_variable);
|
||
free_polynomial(&$2);
|
||
}
|
||
| VAR_POLY EQUAL expr SEMICOLON {
|
||
//printf("Variable '%c' assigned: ", $1);
|
||
sort_polynomial(&$3);
|
||
//print_polynomial(&$3, allowed_variable);
|
||
add_variable($1, $3);
|
||
}
|
||
;
|
||
|
||
expr: NUMBER { $$ = $1; }
|
||
| VARIABLE { $$ = $1; }
|
||
| VAR_POLY {
|
||
Polynomial* var_poly = find_variable($1);
|
||
if (var_poly) {
|
||
$$ = copy_poly(var_poly);
|
||
} else {
|
||
yyerror("Undefined variable");
|
||
YYERROR;
|
||
}
|
||
}
|
||
| '-' expr %prec UMINUS {
|
||
$$ = copy_poly(&$2);
|
||
for (int i = 0; i < $$.size; i++) {
|
||
$$.terms[i].coefficient *= -1;
|
||
}
|
||
free_polynomial(&$2);
|
||
}
|
||
| expr '+' expr {
|
||
$$ = add_polynomials(&$1, &$3);
|
||
free_polynomial(&$1);
|
||
free_polynomial(&$3);
|
||
}
|
||
| expr '-' expr {
|
||
$$ = sub_polynomials(&$1, &$3);
|
||
free_polynomial(&$1);
|
||
free_polynomial(&$3);
|
||
}
|
||
| expr '*' expr {
|
||
$$ = mul_polynomials(&$1, &$3);
|
||
free_polynomial(&$1);
|
||
free_polynomial(&$3);
|
||
}
|
||
| expr '^' expr {
|
||
if ($3.size != 1 || $3.terms[0].exponent != 0) {
|
||
yyerror("Exponent must be constant");
|
||
YYERROR;
|
||
}
|
||
int degree = $3.terms[0].coefficient;
|
||
if (degree < 0) {
|
||
yyerror("Negative exponents not supported");
|
||
YYERROR;
|
||
}
|
||
$$ = deg_poly(&$1, degree);
|
||
free_polynomial(&$1);
|
||
free_polynomial(&$3);
|
||
}
|
||
| '(' expr ')' { $$ = $2; }
|
||
;
|
||
%%
|
||
|
||
void yyerror(const char *s) {
|
||
fprintf(stderr, "ERROR: %s\n", s);
|
||
}
|
||
|
||
int main(int argc, char *argv[]) {
|
||
if (argc < 2) {
|
||
fprintf(stderr, "Usage: %s input_file\n", argv[0]);
|
||
return 1;
|
||
}
|
||
|
||
FILE *input_file = fopen(argv[1], "r");
|
||
if (!input_file) {
|
||
perror("Error opening file");
|
||
return 1;
|
||
}
|
||
|
||
yyin = input_file;
|
||
yyparse();
|
||
fclose(input_file);
|
||
|
||
// Освобождаем память переменных
|
||
for (int i = 0; i < variables_count; i++) {
|
||
free_polynomial(&variables[i].poly);
|
||
}
|
||
return 0;
|
||
} |