更新 (2021 年 9 月)
バージョン 3.7 以降、Bison はユーザー定義のエラー メッセージをサポートしてい%define parse.error custom
ますyyreport_syntax_error
。
int
yyreport_syntax_error (const yypcontext_t *ctx)
{
int res = 0;
YYLOCATION_PRINT (stderr, *yypcontext_location (ctx));
fprintf (stderr, ": syntax error");
// Report the tokens expected at this point.
{
enum { TOKENMAX = 10 };
yysymbol_kind_t expected[TOKENMAX];
int n = yypcontext_expected_tokens (ctx, expected, TOKENMAX);
if (n < 0)
// Forward errors to yyparse.
res = n;
else
for (int i = 0; i < n; ++i)
fprintf (stderr, "%s %s",
i == 0 ? ": expected" : " or", yysymbol_name (expected[i]));
}
// Report the unexpected token.
{
yysymbol_kind_t lookahead = yypcontext_token (ctx);
if (lookahead != YYSYMBOL_YYEMPTY)
fprintf (stderr, " before %s", yysymbol_name (lookahead));
}
fprintf (stderr, "\n");
return res;
}
詳細については、ドキュメントの構文エラー報告関数 yyreport_syntax_errorセクションを参照してください。
元の回答 (2013 年 3 月)
Bison は、カスタム エラー メッセージを生成するための適切なツールではありませんが、有効にしていれば、標準のエラー メッセージも悪くありません%error-verbose
。ドキュメントを見てください: http://www.gnu.org/software/bison/manual/bison.html#Error-Reporting .
本当にカスタム エラー メッセージを提供したい場合は、YYERROR に関するドキュメントを読んで、キャッチしたいパターンのルールを生成し、自分でエラーを発生させてください。たとえば、ここでは 0 による除算は構文エラーとして扱われます (疑わしいですが、カスタム構文エラー メッセージの例を提供します)。
exp:
NUM { $$ = $1; }
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp
{
if ($3)
$$ = $1 / $3;
else
{
$$ = 1;
fprintf (stderr, "%d.%d-%d.%d: division by zero",
@3.first_line, @3.first_column,
@3.last_line, @3.last_column);
}
}
トークンに文字列を指定すると、より適切なエラー メッセージが生成されることにも注意してください。
%token NUM
を生成しますunexpected NUM
が、
%token NUM "number"
生成しunexpected number
ます。