Проблема
Учитывая контекстно-свободную грамматику с произвольными правилами и потоком токенов, как можно эффективно идентифицировать фрагменты потока, соответствующие грамматике?
Пример:
Грамматика
S -> ASB | AB
A -> a
B -> b
(По сути, количество a
с последующим равным количеством b
с)
Ручей:
aabaaabbc...
Ожидаемый результат:
- Соответствие, начинающееся с позиции 1: ab
- Соответствие, начинающееся с позиции 4: aabb
Конечно, ключ "эффективно". без слишком долгого тестирования слишком многих безнадежных кандидатов. Единственное, что я знаю о своих данных, это то, что хотя грамматика произвольна, на практике совпадающие последовательности будут относительно короткими (‹20 терминалов), а сам поток будет довольно длинным (>10000 терминалов).
В идеале я также хотел бы синтаксическое дерево, но это не так важно, потому что, как только фрагмент идентифицирован, я могу запустить обычный синтаксический анализатор над ним, чтобы получить дерево.
С чего начать? Какой тип парсера можно приспособить для такого рода работы?
ababababab
должна пять раз совпадать с выводомS => AB -> ab
. Но добавление правил мусора даст вам такие производные, какS' => GS' => ababababS' => ababababAB => ababababab
. Таким образом, вывод мусора означает, что вам нужно будет перечислить все возможные выводы, а затем выбрать вывод с наибольшим числом выводов, не связанных с мусором, или упорядочить правила выводов так, чтобы выводы, не связанные с мусором, шли последними. Является ли это более оптимальным решением, чем просто сопоставление подпоследовательностей с использованием CYK или чего-то еще? 16.10.2011