Создание настраиваемого сообщения об ошибке в инструменте yacc - PullRequest
0 голосов
/ 29 октября 2018

Привет, я только начал работать над инструментами lex и yacc.

Я понял, что yyerror получает только строку "синтаксическая ошибка" из yacc. Мне было интересно, могу ли я настроить эту строку.

О, а также я могу различать различные типы ошибок? (Привязка к отсутствующему токену и дополнительному токену как к ошибкам.) Если так, как я должен ..?

Большое спасибо.

1 Ответ

0 голосов
/ 29 октября 2018

Вы можете свободно печатать любое сообщение в yyerror (или вообще без сообщения), поэтому вы можете настроить сообщения по своему усмотрению. Обычной настройкой является добавление номера строки (и, возможно, номера столбца) токена, который вызвал ошибку. Вы можете, конечно, изменить текст, если хотите, но если вы просто хотите изменить его на другой язык, вам, вероятно, следует использовать механизм gettext . Вы найдете файлы .po в подкаталоге runtime-po исходного дистрибутива. Если эта возможность включена, bison организует перевод строки перед ее передачей в yyerror, но, конечно, вы можете выполнить перевод самостоятельно в yyerror, если это более удобно для вас.

Я подозреваю, что вы действительно хотите, чтобы зубр выдал более информативное сообщение об ошибке. Bison имеет только один альтернативный формат сообщения об ошибке, который включает в себя список «ожидаемых» токенов. Вы можете попросить Bison выдать такое сообщение об ошибке, включив

%define parse.error verbose

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

%define parse.lac full

Это незначительное снижение производительности. См. Связанный раздел руководства для деталей.

В списке токенов, созданных этой функцией, используется имя токена, указанное в файле зубров. Эти имена обычно не очень удобны для пользователя, поэтому вы можете генерировать сообщения об ошибках, такие как печально известная ошибка PHP

syntax error, unexpected T_CONSTANT_ENCAPSED_STRING

(Примечание: более поздние версии PHP создают другое, но не менее загадочное сообщение.)

Чтобы избежать этого, определите псевдонимы в двойных кавычках для ваших токенов. Это также может сделать вашу грамматику более читабельной:

%type <string> TOK_ID "identifier"
%token TOK_IF "if" TOK_ELSE "else" TOK_WHILE "while"
%token TOK_LSH "<<"
/* Etc. */

%%

stmt: expr ';' 
    | while 
    | if
    | /* ... */
while: "while" '(' expr ')' stmt
expr: "identifier"
    | expr "<<" expr
/* ... */

Указанные имена не будут переданы через gettext. Это подходит для имен, которые являются ключевыми словами, но может быть желательно перевести описательные псевдонимы токенов. Для этого необходимо набросать этот ответ .

...