нормальный интерфейс в lab3
This commit is contained in:
1
lab3/programm/.gitignore
vendored
1
lab3/programm/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
grammar_*
|
||||
analysis_*
|
||||
generation_*
|
||||
@@ -255,6 +255,37 @@ class Grammar:
|
||||
table.add_row(row)
|
||||
return str(table)
|
||||
|
||||
def format_first_sets(self) -> str:
|
||||
"""Форматирует множества FIRST в читаемый вид."""
|
||||
result = []
|
||||
result.append("Множества FIRST:")
|
||||
result.append("=" * 40)
|
||||
|
||||
# Сортируем для гарантии порядка вывода
|
||||
for symbol in sorted(self.first_sets.keys()):
|
||||
# Заменяем пустую строку на эпсилон для лучшей читаемости
|
||||
first_set = {
|
||||
self.EPSILON if item == "" else item for item in self.first_sets[symbol]
|
||||
}
|
||||
result.append(f"FIRST({symbol}) = {{{', '.join(sorted(first_set))}}}")
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
def format_follow_sets(self) -> str:
|
||||
"""Форматирует множества FOLLOW в читаемый вид."""
|
||||
result = []
|
||||
result.append("Множества FOLLOW:")
|
||||
result.append("=" * 40)
|
||||
|
||||
# Обрабатываем только нетерминалы
|
||||
for non_terminal in sorted(self.productions.keys()):
|
||||
follow_set = self.follow_sets.get(non_terminal, set())
|
||||
result.append(
|
||||
f"FOLLOW({non_terminal}) = {{{', '.join(sorted(follow_set))}}}"
|
||||
)
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
def analyze(self, string: str) -> list[int]:
|
||||
input_tokens = string.split() + ["$"]
|
||||
input_pos = 0
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
ПрямойПорядок -> Подлежащее ДополнениеКПодлежащему Глагол ВторостепенныеЧлены Отрицание
|
||||
Инверсия -> Обстоятельство Глагол Подлежащее ВторостепенныеЧлены Отрицание
|
||||
Подлежащее -> ИменнаяГруппа ПридаточноеПредложение | Местоимение
|
||||
ПридаточноеПредложение -> ", " Союз Подлежащее Глагол ВторостепенныеЧлены Отрицание ", " | epsilon
|
||||
ПридаточноеПредложение -> "," Союз Подлежащее Глагол Отрицание "," | epsilon
|
||||
ВторостепенныеЧлены -> ВторостепенныйЧлен ВторостепенныеЧлены | epsilon
|
||||
ВторостепенныйЧлен -> Обстоятельство | Дополнение
|
||||
Обстоятельство -> ОбстоятельствоВремени | ОбстоятельствоМеста | ОбстоятельствоОбразаДействия
|
||||
|
||||
@@ -1,39 +1,56 @@
|
||||
import json
|
||||
|
||||
from grammar import Grammar
|
||||
|
||||
with open("grammar.txt", "r", encoding="utf-8") as file:
|
||||
|
||||
def load_grammar(filename: str = "grammar.txt") -> Grammar | None:
|
||||
try:
|
||||
with open(filename, "r", encoding="utf-8") as file:
|
||||
text = file.read()
|
||||
# text = """
|
||||
# S -> A b B | d
|
||||
# A -> C A b | B
|
||||
# B -> c S d | epsilon
|
||||
# C -> a | e d
|
||||
# """
|
||||
# text = """
|
||||
# S -> F | ( S + F )
|
||||
# F -> 1
|
||||
# """
|
||||
grammar = Grammar(text)
|
||||
|
||||
print("FIRST sets:", grammar.first_sets)
|
||||
print("FOLLOW sets:", grammar.follow_sets)
|
||||
|
||||
# Сохраняем информацию о грамматике в файлы
|
||||
with open("grammar_rules.txt", "w", encoding="utf-8") as output_file:
|
||||
output_file.write(grammar.format_rules())
|
||||
print("Правила грамматики с номерами сохранены в grammar_rules.txt")
|
||||
|
||||
with open("grammar_lookup_table.txt", "w", encoding="utf-8") as output_file:
|
||||
output_file.write(grammar.format_lookup_table())
|
||||
print("Таблица синтаксического анализа сохранена в grammar_lookup_table.txt")
|
||||
print(
|
||||
"Таблица синтаксического анализа сохранена в grammar_lookup_table.txt"
|
||||
)
|
||||
|
||||
input_string = "ich las gestern ein alt Buch"
|
||||
input_string = "der alt Mann las ein Buch"
|
||||
input_string = "gestern las der alt Mann ein Buch"
|
||||
print(f"Analyzing input '{input_string}':")
|
||||
with open("grammar_first.txt", "w", encoding="utf-8") as output_file:
|
||||
output_file.write(grammar.format_first_sets())
|
||||
print("Множества FIRST сохранены в grammar_first.txt")
|
||||
|
||||
with open("grammar_follow.txt", "w", encoding="utf-8") as output_file:
|
||||
output_file.write(grammar.format_follow_sets())
|
||||
print("Множества FOLLOW сохранены в grammar_follow.txt")
|
||||
|
||||
print(f"Грамматика успешно загружена из файла {filename}")
|
||||
return grammar
|
||||
except FileNotFoundError:
|
||||
print(f"Ошибка: Файл {filename} не найден")
|
||||
return None
|
||||
except ValueError as e:
|
||||
print(f"Ошибка при загрузке грамматики: {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Неизвестная ошибка: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def check_string(grammar: Grammar | None, input_string: str) -> None:
|
||||
if not grammar:
|
||||
print("Ошибка: Грамматика не загружена")
|
||||
return
|
||||
|
||||
print(f"Проверка строки: '{input_string}'")
|
||||
try:
|
||||
parse_result = grammar.analyze(input_string)
|
||||
print(f"Applied rules: {parse_result}")
|
||||
print(f"Результат: Строка соответствует грамматике")
|
||||
print(f"Применённые правила: {parse_result}")
|
||||
|
||||
# Сохраняем результат анализа в файл
|
||||
with open("analysis_result.txt", "w", encoding="utf-8") as f:
|
||||
f.write(f"Input: {input_string}\n")
|
||||
f.write("Applied rules: ")
|
||||
@@ -45,21 +62,27 @@ with open("analysis_result.txt", "w", encoding="utf-8") as f:
|
||||
for step in derivation_steps:
|
||||
f.write(f"{step}\n")
|
||||
|
||||
print("Результат анализа сохранен в analysis_result.txt")
|
||||
print("Подробный результат анализа сохранен в analysis_result.txt")
|
||||
except ValueError as e:
|
||||
print(f"Результат: Строка не соответствует грамматике")
|
||||
print(f"Ошибка: {e}")
|
||||
except Exception as e:
|
||||
print(f"Произошла ошибка при анализе: {e}")
|
||||
|
||||
# Тестирование функции генерации строк
|
||||
print("\nГенерация строк по грамматике:")
|
||||
for i in range(5):
|
||||
|
||||
def generate_string(grammar: Grammar | None) -> None:
|
||||
if not grammar:
|
||||
print("Ошибка: Грамматика не загружена")
|
||||
return
|
||||
|
||||
try:
|
||||
terminals, rules = grammar.generate()
|
||||
generated_string = " ".join(terminals)
|
||||
print(f"Сгенерированная строка {i+1}: {generated_string}")
|
||||
print(f"Сгенерированная строка: {generated_string}")
|
||||
print(f"Применённые правила: {rules}")
|
||||
|
||||
# Запись одной сгенерированной строки в файл
|
||||
# Сохраняем результат генерации в файл
|
||||
with open("generation_result.txt", "w", encoding="utf-8") as f:
|
||||
terminals, rules = grammar.generate()
|
||||
generated_string = " ".join(terminals)
|
||||
|
||||
f.write(f"Generated string: {generated_string}\n")
|
||||
f.write("Applied rules: ")
|
||||
f.write(str(rules))
|
||||
@@ -70,4 +93,56 @@ with open("generation_result.txt", "w", encoding="utf-8") as f:
|
||||
for step in derivation_steps:
|
||||
f.write(f"{step}\n")
|
||||
|
||||
print("Результат генерации сохранен в generation_result.txt")
|
||||
print("Подробный результат генерации сохранен в generation_result.txt")
|
||||
except Exception as e:
|
||||
print(f"Произошла ошибка при генерации: {e}")
|
||||
|
||||
|
||||
def main():
|
||||
print("Программа для работы с LL(1)-грамматиками")
|
||||
print("=" * 60)
|
||||
print("Варианты команд:")
|
||||
print(" - load <файл> - загрузить грамматику из файла (по умолчанию grammar.txt)")
|
||||
print(" - check <строка> - проверить, соответствует ли строка грамматике")
|
||||
print(" - generate - сгенерировать случайную строку по грамматике")
|
||||
print(" - exit - выход из программы")
|
||||
print("=" * 60)
|
||||
|
||||
# Загружаем грамматику по умолчанию при старте
|
||||
grammar = load_grammar()
|
||||
|
||||
while True:
|
||||
command = input("\nВведите команду: ").strip()
|
||||
|
||||
if not command:
|
||||
continue
|
||||
|
||||
parts = command.split(maxsplit=1)
|
||||
cmd = parts[0].lower()
|
||||
|
||||
if cmd == "exit":
|
||||
print("Выход из программы.")
|
||||
break
|
||||
|
||||
elif cmd == "load":
|
||||
filename = "grammar.txt"
|
||||
if len(parts) > 1:
|
||||
filename = parts[1].strip()
|
||||
grammar = load_grammar(filename)
|
||||
|
||||
elif cmd == "check":
|
||||
input_string = ""
|
||||
if len(parts) > 1:
|
||||
input_string = parts[1].strip()
|
||||
check_string(grammar, input_string)
|
||||
|
||||
elif cmd == "generate":
|
||||
generate_string(grammar)
|
||||
|
||||
else:
|
||||
print(f"Неизвестная команда: {cmd}")
|
||||
print("Доступные команды: load, check, generate, exit")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user