polynomials: обычный калькулятор как основа

master
serr 2025-05-12 20:21:36 +03:00
parent ca856f121c
commit 93df059f44
3 changed files with 29 additions and 125 deletions

View File

@ -1,21 +1,13 @@
%{
#include "polynomials.tab.h"
#include <string.h>
void yyerror(const char *s);
%}
%option noyywrap
%%
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
[-+*^()] { return yytext[0]; }
[ \t] ;
\n { return 0; }
. { printf("unknown: %s\n", yytext); exit(0); }
%%
%%
[ \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"); }
%%
int yywrap() { return 1; }

View File

@ -1,126 +1,38 @@
%{
#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;
#include <math.h>
void yyerror(const char *s);
int yylex(void);
extern FILE* yyin;
int yylex();
%}
%union {
int num;
char var;
}
%token <num> NUMBER
%token <var> VARIABLE
%token LPAREN RPAREN PLUS MINUS MULTIPLY
%token NUMBER
%left '+' '-'
%left '*' '/'
%left UMINUS
%right '^'
%%
input:
| expr
| input expr { printf("= %d\n", $2); }
;
expr:
term
| 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");
}
expr: NUMBER { $$ = $1; }
| '-' expr %prec UMINUS { $$ = -$2; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| expr '^' expr { $$ = pow($1, $3); }
| '(' expr ')' { $$ = $2; }
;
term:
factor
| term MULTIPLY factor {
tokens[token_count].str_ptr = "*";
tokens[token_count].type = 'o';
token_count++;
//printf("Found operator: *\n");
}
;
factor:
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, "ERROR: %s\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) {
if (argc != 2) {
fprintf(stderr, "\033[91mUsage: %s <input_file>\033[0m\n", argv[0]);
return 1;
}
FILE* input_file = fopen(argv[1], "r");
if (!input_file) {
perror("\033[91mFailed to open input file\033[0m\n");
return 1;
}
yyin = input_file;
printf("\033[34mParsing expression from file: %s\033[0m\n", argv[1]);
int main() {
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

@ -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"
DEPENDENCY_LIST = [