Я делаю компилятор в BNFC, и он дошел до стадии, когда он уже компилирует некоторые вещи, и код работает на моем устройстве. Но перед отправкой я хочу, чтобы мой компилятор возвращал правильные сообщения об ошибках, когда пользователь пытается скомпилировать недопустимую программу.
Я обнаружил, как bison может записывать ошибки в поток stderr, и я могу их перехватить. Теперь предположим, что в коде пользователя нет синтаксической ошибки, он просто ссылается на неопределенную переменную, я могу уловить это в моем посетителе, но я не могу знать, какой был номер строки, как я могу найти номер строки?
В bison вы можете получить доступ к начальной и конечной позиции текущего выражения, используя переменную @$
, который содержит структуру с членами first_column
, first_line
, last_column
а также last_line
, так же @1
и т. д. содержат одинаковую информацию для подвыражений $ 1 и т. д. соответственно.
Чтобы получить доступ к той же информации позже, вам нужно записать ее в свой ast. Поэтому добавьте поле к вашим типам узлов AST, чтобы сохранить местоположение, а затем установите это поле при создании узла в вашем файле зубров.
(предыдущий ответ более богат), но в некоторых простых парсерах, если мы объявим
%option yylineno
в flex, и распечатать его в yyerror,
yyerror(char *s) {
fprintf(stderr,"ERROR (line %d):before '%s'\n-%s",yylineno, yytext,s);
}
иногда это помогает …