Использование генератора синтаксического анализатора, такого как BISON, и в то же время корректно обрабатывать некорректный ввод - PullRequest
3 голосов
/ 06 мая 2009

Мне нужен парсер для языка, который не так уж и сложен. Единственная загвоздка в том, что я никогда не хочу, чтобы синтаксический анализатор выдавал ошибку, когда он получает некорректный ввод. Скорее, я хочу, чтобы он просто продолжал, придавая как можно больше смысла вводу, подобно тому, как это делают парсеры HTML в веб-браузере.

Я, естественно, думал использовать генератор синтаксических анализаторов, но у меня не так много опыта с ними, и все примеры, которые я видел в Bison и Antlr, содержат хрупкие парсеры, которые сдаются, как только встречают синтаксис ошибка. Это выполнимо с ними, или я должен рассмотреть ручное катание это? Это, вероятно, (я думаю) не было бы так сложно, учитывая язык.

Ответы [ 2 ]

1 голос
/ 06 мая 2009

Вы должны разработать свою грамматику с учетом контрольных точек. Под контрольными точками я подразумеваю точку с запятой для C, разрыв строки для Python или точку для COBOL (в качестве примеров). Эта контрольная точка определяет, сколько компиляторов восстанавливается, чтобы они могли сообщать больше, чем просто о первой найденной ошибке.

Я не использовал Bison, но YACC позволяет вам переопределить обработку ошибок, и я надеюсь, что эквивалентный инструмент GNU был бы по крайней мере таким же мощным, как наши старые UNIX-кланкеры.

Я делал это раньше с помощью файла конфигурации грамматики YACC. Допустим, у вас есть следующий правильно сформированный сегмент:

item = "bread" {
    quantity = 7
    price = 1.50
    taxrate = 10
}

и по какой-то странной причине пользователь неверно произносит «количество», делая его неверным. В этот момент в ваших обратных вызовах вы можете просто поднять флаг ошибки, который будет препятствовать дальнейшей обработке, пока контрольная точка не будет достигнута. Вы позволяете анализатору продолжать работу (перехватывать и игнорировать дальнейшие ошибки) и следить за тем, чтобы ваши обратные вызовы ничего не делали в ответ на любые ложные успехи в поврежденном синтаксисе.

Это может быть простым игнорированием всех последующих строф вплоть до закрывающей скобки или даже установкой значения по умолчанию для цены и игнорированием только до разрыва строки (так что вы по крайней мере получите частично сформированный объект).

Как бы вы ни делали, просто сбросьте флаг ошибки, когда доберетесь до контрольной точки, чтобы продолжить обработку.

Я бы по-прежнему следил за тем, чтобы пользователь был уведомлен, иногда считается плохой формой продолжать работу с данными, которые клиент не хотел: -).

1 голос
/ 06 мая 2009

Я не уверен, что вы сможете сделать это с генератором парсера в общем случае. По крайней мере, не полностью автоматически. Рассмотрим следующее неправильное выражение:

a - b + c ) * d

Что должен делать парсер с этим? Когда он встречает первый недопустимый токен, закрывающую круглую скобку, он может каким-то образом догадаться, что пользователь намеревался где-нибудь открыть открытую скобку, но где? В любом месте, где он мог бы быть, это привело бы к другому значению.

Вместо этого можно было просто притвориться, что все, что было раньше, никогда не было. Тогда бы получилось

* d

Который все еще деформирован.

...