Восстановление ошибок зубров (режим паники) не работает?
Я читал о том, как сделать синтаксический анализ Bison "устойчивым к ошибкам", и это кажется довольно простым. Независимо от того, где я посмотрел, все сводится к одному и тому же простому решению.
Тем не менее, я был не в состоянии заставить это работать, и я не вижу недостаток. Парсер продолжает останавливаться / выходить вместо продолжения / восстановления...
То, что у меня есть, - это правило лечить все keywords
(и их образцы), как:
keywords:
key1_rule
| key2_rule
| key3_rule
;
И над этим у меня есть мой file
правило итератора:
file:
%empty
| file keywords
;
У меня проблема в том, что иногда ключевые слова используются в шаблоне, который не обрабатывается, но это не проблема, потому что мы не хотим фиксировать эти случаи (а просто хотим их игнорировать). Например:
Мы фиксируем образец:
KEY1 NAME KEY2 VALUE
Мы хотим игнорировать:
KEY1 NAME KEY3 KEY2 VALUE
или же
KEY2 VALUE
(KEY2 не предшествует KEY1)
В этих случаях, которые мы хотим игнорировать, анализатор корректно запускает ошибку "неожиданный токен". В приведенном выше примере ошибка будет "Parse error: syntax error, unexpected KEY3"
(или же "Parse error: syntax error, unexpected KEY2"
).
Итак, из того, что я видел, я думал, что решение будет столь же простым, как использование error
жетон, вот так:
file:
%empty
| file keywords
| file error
;
Я также попробовал *:
keywords:
key1_rule
| key2_rule
| key3_rule
| keywords error
;
* а также попробовал: error '\n'
а также error '\n' { yyerrok; }
(что я видел в некоторых случаях)
К сожалению, ни одна из моих попыток не была успешной... и я продолжаю получать ту же самую "неожиданную" ошибку. Интересно, есть ли что-то, что мне нужно настроить, прежде чем я смогу правильно его использовать... Я заметил, что у меня было %option nodefault
в моем файле лексера и попытался удалить его, но тоже результат был тот же.
1 ответ
Этот пост дал мне немного понимания того, в чем может быть проблема. В некоторых случаях проблема возникает из-за того, что условие остановки в "правиле ошибки" не выполняется, что в его случае было потому, что анализатор игнорировал / пропускал новую строку ('\n'
). Итак, правило:
ошибка '\n' { yyerrok; yyclearin; }
никогда не будет работать...(так как '\n'
никогда не был пойман)
Таким образом, я исключил ошибку между двумя известными токенами, чтобы исключить эту возможность, но все же получил ошибку. Изучив немного больше, я обнаружил, что проблема была внутри yyerror
функция, которая заставляла программу выходить.