This commit is contained in:
2025-04-15 15:46:24 +03:00
commit 19159eb98d
17 changed files with 908 additions and 0 deletions

98
lab1/programm/main.py Normal file
View File

@@ -0,0 +1,98 @@
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()