Это не так уж отличается от решения bison/flex, предложенного в вопросе, на который вы ссылаетесь. По крайней мере, принцип тот же. Отличаются только детали.
Ключевым фактом является то, что именно сканер, а не синтаксический анализатор, должен считать строки, потому что именно сканер преобразует входной текст в токены. Парсер ничего не знает об исходном тексте; он просто получает последовательность правильно обработанных токенов.
Итак, нам нужно просмотреть документацию по JFlex, чтобы выяснить, как заставить его отслеживать номера строк, а затем мы находим следующее в разделе, посвященном параметрам и объявлениям:
В руководстве 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