Восстановление ошибок зубров (режим паники) не работает?

Я читал о том, как сделать синтаксический анализ 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 функция, которая заставляла программу выходить.

Другие вопросы по тегам