BYACCJ: Как включить номер строки в сообщение об ошибке?

Это моя текущая функция обработки ошибок:

public void yyerror(String error) {
    System.err.println("Error: "+ error);
}

Это функция ошибок по умолчанию, которую я нашел на домашней странице BYACC/J. Я не могу найти способ добавить номер строки. Мой вопрос похож на этот вопрос. Но решение здесь не работает.

Для моего лексера я использую файл JFlex.


person Hari    schedule 09.04.2020    source источник


Ответы (1)


Это не так уж отличается от решения bison/flex, предложенного в вопросе, на который вы ссылаетесь. По крайней мере, принцип тот же. Отличаются только детали.

Ключевым фактом является то, что именно сканер, а не синтаксический анализатор, должен считать строки, потому что именно сканер преобразует входной текст в токены. Парсер ничего не знает об исходном тексте; он просто получает последовательность правильно обработанных токенов.

Итак, нам нужно просмотреть документацию по JFlex, чтобы выяснить, как заставить его отслеживать номера строк, а затем мы находим следующее в разделе, посвященном параметрам и объявлениям:

  • %line

    Включает подсчет строк. Переменная-член int yyline содержит количество строк (начиная с 0) от начала ввода до начала текущего токена.

В руководстве JFlex не упоминается, что yyline является закрытой переменной-членом, поэтому, чтобы получить ее из синтаксического анализатора, вам нужно добавить в файл JFlex что-то вроде следующего:

%line
{
    public int GetLine() { return yyline + 1; }
    // ...

}

Затем вы можете добавить вызов GetLine в функцию ошибки:

public void yyerror (String error) {
  System.err.println ("Error at line " + lexer.GetLine() + ": " + error);
}

Иногда это приводит к запутанным сообщениям об ошибках, поскольку к моменту вызова yyerror синтаксический анализатор уже запросил упреждающий токен, который может находиться в строке, следующей за ошибкой, или даже быть отделен от ошибки несколькими строками комментариев. (Эта проблема часто возникает, когда ошибка заключается в отсутствующем терминаторе оператора.) Но это хорошее начало.

person rici    schedule 10.04.2020