Генерация случайной строки
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import random
|
||||||
import re
|
import re
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
@@ -316,3 +317,61 @@ class Grammar:
|
|||||||
)
|
)
|
||||||
|
|
||||||
return rules_applied
|
return rules_applied
|
||||||
|
|
||||||
|
def generate(self, symbol: str | None = None) -> tuple[list[str], list[int]]:
|
||||||
|
"""Генерирует предложение по заданной грамматике. Возвращает список терминалов
|
||||||
|
и список номеров применённых правил."""
|
||||||
|
|
||||||
|
if symbol is None:
|
||||||
|
return self.generate(self.start_symbol)
|
||||||
|
|
||||||
|
# Если символ - терминал, возвращаем его
|
||||||
|
if symbol not in self.productions:
|
||||||
|
return [symbol], []
|
||||||
|
|
||||||
|
# Выбираем случайное правило для нетерминала
|
||||||
|
rules = self.productions[symbol]
|
||||||
|
chosen_rule = random.choice(rules)
|
||||||
|
|
||||||
|
# Получаем номер выбранного правила
|
||||||
|
rule_number = self.rule_numbers[(symbol, tuple(chosen_rule))]
|
||||||
|
|
||||||
|
# Инициализируем результаты
|
||||||
|
terminals = []
|
||||||
|
rule_numbers = [rule_number]
|
||||||
|
|
||||||
|
# Разворачиваем каждый символ в правой части правила
|
||||||
|
for s in chosen_rule:
|
||||||
|
sub_terminals, sub_rules = self.generate(s)
|
||||||
|
terminals.extend(sub_terminals)
|
||||||
|
rule_numbers.extend(sub_rules)
|
||||||
|
|
||||||
|
return terminals, rule_numbers
|
||||||
|
|
||||||
|
def generate_derivation_steps(self, rule_numbers: list[int]) -> list[str]:
|
||||||
|
"""Преобразует список номеров правил в последовательность шагов вывода.
|
||||||
|
Возвращает список строк, представляющих каждый шаг вывода."""
|
||||||
|
|
||||||
|
# Получаем соответствие между номерами правил и самими правилами
|
||||||
|
rule_details = {num: rule for rule, num in self.rule_numbers.items()}
|
||||||
|
|
||||||
|
# Начинаем с начального символа
|
||||||
|
current = self.start_symbol
|
||||||
|
steps = [current]
|
||||||
|
|
||||||
|
# Применяем каждое правило по порядку
|
||||||
|
for rule_num in rule_numbers:
|
||||||
|
if rule_num in rule_details:
|
||||||
|
non_terminal, replacement = rule_details[rule_num]
|
||||||
|
|
||||||
|
# Находим первое вхождение нетерминала и заменяем его
|
||||||
|
words = current.split()
|
||||||
|
for i, word in enumerate(words):
|
||||||
|
if word == non_terminal:
|
||||||
|
words[i : i + 1] = replacement
|
||||||
|
break
|
||||||
|
|
||||||
|
current = " ".join(words)
|
||||||
|
steps.append(current)
|
||||||
|
|
||||||
|
return steps
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ print(f"Analyzing input '{input_string}':")
|
|||||||
parse_result = grammar.analyze(input_string)
|
parse_result = grammar.analyze(input_string)
|
||||||
print(f"Applied rules: {parse_result}")
|
print(f"Applied rules: {parse_result}")
|
||||||
|
|
||||||
rule_details = {num: rule for rule, num in grammar.rule_numbers.items()}
|
|
||||||
|
|
||||||
with open("analysis_result.txt", "w", encoding="utf-8") as f:
|
with open("analysis_result.txt", "w", encoding="utf-8") as f:
|
||||||
f.write(f"Input: {input_string}\n")
|
f.write(f"Input: {input_string}\n")
|
||||||
f.write("Applied rules: ")
|
f.write("Applied rules: ")
|
||||||
@@ -43,19 +41,33 @@ with open("analysis_result.txt", "w", encoding="utf-8") as f:
|
|||||||
f.write("\n\n")
|
f.write("\n\n")
|
||||||
f.write("Derivation steps:\n")
|
f.write("Derivation steps:\n")
|
||||||
|
|
||||||
current = grammar.start_symbol
|
derivation_steps = grammar.generate_derivation_steps(parse_result)
|
||||||
f.write(f"{current}\n")
|
for step in derivation_steps:
|
||||||
|
f.write(f"{step}\n")
|
||||||
for rule_num in parse_result:
|
|
||||||
non_terminal, replacement = rule_details[rule_num]
|
|
||||||
|
|
||||||
words = current.split()
|
|
||||||
for i, word in enumerate(words):
|
|
||||||
if word == non_terminal:
|
|
||||||
words[i : i + 1] = replacement
|
|
||||||
break
|
|
||||||
|
|
||||||
current = " ".join(words)
|
|
||||||
f.write(f"{current}\n")
|
|
||||||
|
|
||||||
print("Результат анализа сохранен в analysis_result.txt")
|
print("Результат анализа сохранен в analysis_result.txt")
|
||||||
|
|
||||||
|
# Тестирование функции генерации строк
|
||||||
|
print("\nГенерация строк по грамматике:")
|
||||||
|
for i in range(5):
|
||||||
|
terminals, rules = grammar.generate()
|
||||||
|
generated_string = " ".join(terminals)
|
||||||
|
print(f"Сгенерированная строка {i+1}: {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))
|
||||||
|
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")
|
||||||
|
|||||||
Reference in New Issue
Block a user