flex-bison-in-action/analyzers/polynomials/polynomials.y

154 lines
3.7 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

%{
#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>
extern void yyerror(const char *s);
int yylex();
extern FILE *yyin;
extern char allowed_variable;
extern int current_line_number;
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");
exit(1);
}
}
| '-' 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");
exit(1);
}
int degree = $3.terms[0].coefficient;
if (degree < 0) {
yyerror("Negative exponents not supported");
exit(1);
}
$$ = deg_poly(&$1, degree);
free_polynomial(&$1);
free_polynomial(&$3);
}
| '(' expr ')' { $$ = $2; }
;
%%
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;
}