lab1
This commit is contained in:
98
lab1/programm/main.py
Normal file
98
lab1/programm/main.py
Normal 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()
|
||||
Reference in New Issue
Block a user