Я новичок как в Nemerle так и в Nemerle.Peg, но все же решился написать парсер для очередной задачи на Nemerle.Peg. Первую свою грамматику удалось заставить работать довольно быстро (спасибо интеграции с VS 2010), но нигде не могу найти информацию об обработке ошибок парсинга. В статье
Макрос PegGrammarАвтор(ы): Чистяков Владислав Юрьевич
Дата: 07.06.2011
Макрос PegGrammar – это макрос Nemerle, позволяющий добавлять в приложения парсеры, описываемые в нотации PEG.
есть что-то про атрибут FailureRecovery и SkipRule/StopRule, но мне не очень понятно как их применить.
Хотелось бы получить ссылки на примеры c обработкой ошибок в парсере и выводом сообщений об ошибках пользователю. Был бы очень благодарен, если бы смогли доступно объяснить, как работают вышеуказанные атрибуты и правила Skip/Stop.
Здравствуйте, Raimon, Вы писали:
R>Хотелось бы получить ссылки на примеры c обработкой ошибок в парсере и выводом сообщений об ошибках пользователю. Был бы очень благодарен, если бы смогли доступно объяснить, как работают вышеуказанные атрибуты и правила Skip/Stop.
PegGrammar автоматически выявляет одну ошибку после чего останавливает парсинг. То как получить и отобразить эту информацию можно поглядеть в коде тестовой утилиты к C#-парсеру (
здесь).
Если нужно выявлять ошибки которые парсер отловить не способен, то нужно писать дополнительные правила в которых обрабатывать ошибочные ситуации.
Сами сообщения при этом нужно помещать в AST (создавая для этого специальные ветки) или кидая исключения (в последнем случае будет невозможно обработать более одной ошибки).
Для вынимания сообщений из AST-а можно воспользоваться макросом CollectParseErrors (из пространства имен Nemerle.Peg.AstUtils, макробиблиотеки Nemerle.Peg.Macros.dll). Метод GetParseErrors в AST C#-а
сгенерирован именно этим макросом. При этом ветки содержащие ошибки должны иметь определенные имена (если не ошибаюсь, иметь в названии Error).
Для восстановления после обнаружения ошибки можно воспользоваться атрибутом FailureRecovery. Она позволяет пропустить часть некорректного кода и продолжить паринг с корректной позиции.
Пример использования FailureRecovery есть в
парсере C#:
[FailureRecovery(statementRecovery, ("}" / statement / switchSection), (space+ / stringLiteral+ / block / [Any]))]
statement : Statement = labeledStatement
/ declarationStatement
/ embeddedStatement;
Обработчик statementRecovery находится
здесь.
Он так же должен создавать ветки AST содержащие сообщения об ошибках.