commit db113a15d9a9e5f4769820d4550047749cc21acf Author: serr Date: Tue Apr 22 12:08:37 2025 +0300 new diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adb36c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.exe \ No newline at end of file diff --git a/analyzers/test/test.l b/analyzers/test/test.l new file mode 100644 index 0000000..41876a5 --- /dev/null +++ b/analyzers/test/test.l @@ -0,0 +1,22 @@ +%{ +#include "test.tab.h" +#include +#include + +int yylineno; + +%} + +%% +"{" { return LBRACE; } +"}" { return RBRACE; } +\n { yylineno++; } +[^{}]+ { + yylval.str = strdup(yytext); + return TEXT; + } +%% + +int yywrap() { + return 1; +} \ No newline at end of file diff --git a/analyzers/test/test.y b/analyzers/test/test.y new file mode 100644 index 0000000..7252c08 --- /dev/null +++ b/analyzers/test/test.y @@ -0,0 +1,49 @@ +%{ +#include +#include +#include + +extern int yylineno; +extern char *yytext; + +void yyerror(const char *s) { + fprintf(stderr, "\033[91mError at line %i\033[0m", yylineno); + exit(1); +} +extern int yylex(); +extern FILE *yyin; +%} + +%union { + char *str; +} + +%token TEXT +%token LBRACE RBRACE + +%% + +block: + LBRACE content RBRACE + ; + +content: + | content TEXT { printf("TOKEN ('%s')\n", $2); free($2); } + | content block {} + ; +%% + +int main(int argc, char **argv) { + yylineno = 1; + + if (argc > 1) { + FILE *f = fopen(argv[1], "r"); + if (!f) { + perror("\033[91mFail open file\033[0m"); + return 1; + } + yyin = f; + } + yyparse(); + return 0; +} \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..08aba1c --- /dev/null +++ b/main.py @@ -0,0 +1,48 @@ +import os +import subprocess + +# ЭТИ ПУТИ НАДО ЗАДАТЬ ВРУЧНУЮ +# *.l и *.y файлы из директории ANALYZERS_DIR ДОЛЖНЫ НАЗЫВАТЬСЯ как basename этой директории!!! +ANALYZERS_DIR = r'C:\Users\user\Desktop\УЧЕБА\6_СЕМ\КОМПИЛЯТОРЫ\go-analyzer\analyzers\test' +FLEX_EXE_PATH = r"C:\tools\win_flex_bison\win_flex.exe" +BISON_EXE_PATH = r"C:\tools\win_flex_bison\win_bison.exe" + +def main(): + # Подготовка путей + analyzer_name = os.path.basename(ANALYZERS_DIR) + lexical_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.l" + syntaxic_analyzer_path = fr"{ANALYZERS_DIR}\{analyzer_name}.y" + + # Подготовка списка команд + cmds = [ + f'{FLEX_EXE_PATH} {lexical_analyzer_path}', + f'{BISON_EXE_PATH} -d {syntaxic_analyzer_path}', + f'gcc lex.yy.c {analyzer_name}.tab.c -o {analyzer_name}.exe' + ] + + # Исполнение команд с выводом + for cmd in cmds: + print(f"\n\033[1mExecuting:\033[0m {cmd}") + try: + subprocess.run( + cmd, + shell=True, + check=True, + text=True, + stderr=subprocess.PIPE + ) + print(f'\033[92mSuccessfully executed!\033[0m') + except subprocess.CalledProcessError as e: + print("\033[91mErrors:\033[0m") + print(e.stderr) + + # Очистка промежуточных файлов (только если все команды успешны) + for path in ['lex.yy.c', f'{analyzer_name}.tab.c', f'{analyzer_name}.tab.h']: + try: + os.remove(path) + print(f"\033[1mRemoved:\033[0m {path}") + except FileNotFoundError: + pass + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tests/test_blocks.txt b/tests/test_blocks.txt new file mode 100644 index 0000000..57acaa9 --- /dev/null +++ b/tests/test_blocks.txt @@ -0,0 +1,13 @@ +{ + { 1 231233 + {1}{} + block1 { + block2 { block3 } + block4 asjdb asd bajds ba + } 126316 + block5 + } + { + 123 + } +} \ No newline at end of file