Преамбула
Я написал GLR-парсер с восстановлением после ошибок. Когда он сталкивается с ошибкой, он разбивается на следующие альтернативы:
- Вставьте ожидаемый элемент во ввод (может быть, пользователь его просто пропустил) и продолжайте как обычно.
- Замените ошибочный элемент на ожидаемый (может быть, пользователь только что сделал опечатку) и действуйте как обычно.
- Пропустить ошибочный элемент и, если следующий элемент тоже ошибочен, перейти к #2.
Но если на входе много ошибок (например, пользователь по ошибке передал парсеру JPEG-файл), количество альтернатив возрастает в геометрической прогрессии.
Пример
Такой парсер соответствует следующей грамматике:
Program -> Identifier WS Identifier WS '=' WS Identifier
Identifier -> ('a'..'z' | 'A'..'Z' | '0'..'9')*
WS -> ' '*
применяется к следующему тексту:
x = "abc\"def"; y = "ghi\"jkl";
не работает с «недостаточно памяти» на умеренно современном настольном компьютере.
Вопрос
Как уменьшить количество вариантов в случае ошибок ввода?