from grammar import ActionsListWithAppliedCount, Grammar def load_grammar(filename: str = "grammar.txt") -> Grammar | None: try: # #b - 2 * #a + 3 * #c actions = [ lambda rule_number, applied_count, _: print( f"Rule #{rule_number} (applied x{applied_count} times): iconst_1" ), lambda rule_number, applied_count, _: print( f"Rule #{rule_number} (applied x{applied_count} times): iconst_2 isub" ), lambda rule_number, applied_count, _: print( f"Rule #{rule_number} (applied x{applied_count} times): iconst_1 iadd" ), lambda rule_number, applied_count, _: print( f"Rule #{rule_number} (applied x{applied_count} times): iconst_1 iadd" ), lambda rule_number, applied_count, _: print( f"Rule #{rule_number} (applied x{applied_count} times): iconst_3 iadd" ), ] with open(filename, "r", encoding="utf-8") as file: text = file.read() grammar = Grammar(text, ActionsListWithAppliedCount(actions)) # Сохраняем информацию о грамматике в файлы 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" ) 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 tokenize_string(input_string: str) -> list[str]: return input_string.split() def check_string(grammar: Grammar | None, input_string: str) -> None: if not grammar: print("Ошибка: Грамматика не загружена") return print(f"Проверка строки: '{input_string}'") try: input_tokens = tokenize_string(input_string) parse_result = grammar.analyze(input_tokens) 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: ") f.write(str(parse_result)) f.write("\n\n") f.write("Derivation steps:\n") derivation_steps = grammar.generate_derivation_steps(parse_result) for step in derivation_steps: f.write(f"{step}\n") print("Подробный результат анализа сохранен в analysis_result.txt") except ValueError as e: print(f"Результат: Строка не соответствует грамматике") print(f"Ошибка: {e}") except Exception as e: print(f"Произошла ошибка при анализе: {e}") def generate_string(grammar: Grammar | None) -> None: if not grammar: print("Ошибка: Грамматика не загружена") return try: terminals, rules = grammar.generate() generated_string = " ".join(terminals) print(f"Сгенерированная строка: {generated_string}") print(f"Применённые правила: {rules}") # Сохраняем результат генерации в файл with open("generation_result.txt", "w", encoding="utf-8") as f: f.write(f"Generated string: {generated_string}\n") f.write("Applied rules: ") f.write(str(rules)) f.write("\n\n") f.write("Derivation steps:\n") derivation_steps = grammar.generate_derivation_steps(rules) for step in derivation_steps: f.write(f"{step}\n") 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()