Я нашел ответ в способе восстановления после панического режима, но в нем тоже есть некоторые ошибки.Что я сделал, так это отредактировал свою грамматику так, чтобы, как только я встретил пропущенный символ в строке входного файла (в вышеупомянутом случае - точку с запятой), парсер продолжал работать, пока не обнаружил похожий символ.Эти похожие символы называются синхронизирующими токенами.
См. Пример ниже.Сначала я заменил все токены SEMICOLON в моей грамматике следующим образом.
Semicolon()
Затем добавьте это новое правило производства.
void Semicolon() :
{}
{
try
{
<SEMICOLON>
} catch (ParseException e) {
Token t;
System.out.println(e.toString());
do {
t = getNextToken();
} while (t.kind != SEMICOLON && t!=null && t.kind != EOF );
}
}
Как только я столкнусь с парсером пропавших символов, найдите похожего символа. Когда он находит такой символ, он возвращается к правилу, которое его вызвало.
Пример: - Предполагается, что точка с запятой отсутствует в объявлении переменной.
int a=10 <--- no semicolon
Итак, синтаксический анализатор ищет точку с запятой.в какой-то момент он находит точку с запятой.
___(some code)__; method(param1);
Так что после нахождения первой точки с запятой в приведенном выше примере он возвращается к правилу объявления переменной (потому что это тот, который вызвал метод точки с запятой ().) Но чтомы находим после того, как вновь найденная точка с запятой является вызовом функции, а не объявлением переменной.
Может кто-нибудь предложить, пожалуйста, способ решения этой проблемы.