import math import os from typing import Callable from prettytable import PrettyTable from lexer import LexemeType, Lexer class IdentifierMapper: def __init__(self): self.id_table = {} self.counter = 0 def __call__(self, lex_text: str) -> str: if lex_text not in self.id_table: self.id_table[lex_text] = f"{lex_text} : {self.counter}" self.counter += 1 return self.id_table[lex_text] def exp_form_to_complex(exp_str: str) -> str: # Разделяем строку по 'E' base, exponent = exp_str.split("E") r = float(base) phi = float(exponent) # Преобразуем в алгебраическую форму a = r * math.cos(phi) b = r * math.sin(phi) return f"{a:.2f} + i * {b:.2f}" LEXEME_TYPES: dict[str, LexemeType] = { # 1. Идентификаторы "IDENTIFIER": LexemeType( "IDENTIFIER", r"[A-Za-z_][A-Za-z_0-9]{0,15}(?![A-Za-z_0-9])", IdentifierMapper() ), # 2. Комплексные числа в показательной форме (на самом деле — числа в экспоненциальной форме) "COMPLEX": LexemeType( # "COMPLEX", r"[+-]?\d+(?:\.\d+)?E[+-]?\d+(?!E)", exp_form_to_complex "COMPLEX", r"[+-]?\d+(?:\.\d+)?E[+-]?\d+(?:\.\d+)?(?!E)", exp_form_to_complex, ), # 3. Оператор присваивания := "ASSIGN": LexemeType("ASSIGN", r"\:=(?![\:=])"), # 4. Арифметические операторы "ARITHMETIC_OP": LexemeType("ARITHMETIC_OP", r"[+\-*/^]"), # 5. Скобки "PAREN": LexemeType("PAREN", r"[()]"), # 6. Разделитель выражений | "SEPARATOR": LexemeType("SEPARATOR", r"\|"), # 7. Комментарии от # до конца строки "COMMENT": LexemeType("COMMENT", r"\#.*"), } def analyze_and_print_table(code: str): lexer = Lexer(LEXEME_TYPES.values()) lexemes = lexer.analyze(code) table = PrettyTable(["Лексема", "Тип лексемы", "Значение"]) for l in lexemes: table.add_row([l.text, l.type_name, l.value]) print(table) print() LEXEME_TYPES["IDENTIFIER"].value_func = IdentifierMapper() def main(): while True: # Запрашиваем название файла file_name = input( "Введите название файла для анализа (или 'exit' для выхода): " ) if file_name.lower() == "exit": print("Завершаю программу.") break if not os.path.isfile(file_name): print(f"Файл '{file_name}' не найден. Попробуйте снова.") continue # Читаем содержимое файла with open(file_name, "r", encoding="utf-8") as file: code = file.read() # Анализируем и выводим таблицу analyze_and_print_table(code) if __name__ == "__main__": main()