Я хочу разобрать определенные пользователем доменные языки. Эти языки обычно близки к математическим обозначениям (я не разбираю естественный язык). Пользователи определяют свои DSL в нотации BNF, например так:
expr ::= LiteralInteger
| ( expr )
| expr + expr
| expr * expr
Подобные входные данные 1 + ( 2 * 3 )
должны быть приняты, в то время как подобные входные данные 1 +
должны быть отклонены как неправильные, а подобные входные данные 1 + 2 * 3
должны быть отклонены как неоднозначные.
Главная трудность здесь заключается в том, чтобы справиться с неоднозначными грамматиками в удобной для пользователя форме. Ограничить грамматику, чтобы она была однозначной, не вариант: таков язык - идея состоит в том, что авторы предпочитают опускать круглые скобки, когда они не нужны, чтобы избежать двусмысленности. Пока выражение не является двусмысленным, мне нужно его проанализировать, а если нет, мне нужно отклонить его.
Мой синтаксический анализатор должен работать с любой не зависящей от контекста грамматикой, даже неоднозначной, и должен принимать все однозначные входные данные. Мне нужно дерево разбора для всех принятых входных данных. Для некорректного или неоднозначного ввода я в идеале хочу хорошие сообщения об ошибках, но для начала я возьму то, что смогу получить.
Как правило, я буду вызывать анализатор на относительно короткие входные данные, со случайным более длинным вводом. Таким образом, асимптотически более быстрый алгоритм может быть не лучшим выбором. Я хотел бы оптимизировать распределение около 80% входов длиной менее 20 символов, 19% между 20 и 50 символами и 1% редко более длинных входов. Скорость для неверных вводов не является главной проблемой. Кроме того, я ожидаю модификацию DSL примерно через каждые 1000-100000 входов; Я могу потратить пару секунд на предварительную обработку грамматики, а не пару минут.
Какой алгоритм (ы) разбора я должен исследовать, учитывая мои типичные размеры ввода? Должны ли сообщения об ошибках быть фактором моего выбора, или я должен сосредоточиться на разборе однозначных входных данных и, возможно, запустить совершенно отдельный, более медленный синтаксический анализатор для обеспечения обратной связи об ошибках?
(В проекте, где я нуждался в этом (некоторое время назад), я использовал CYK , который не был слишком сложным для реализации и работал адекватно для моих входных размеров, но не вызывал очень хороших ошибок.)
x+y+z
.
+
, так что x+y+z
это действительно неоднозначно, поэтому ошибочно.