mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
c: don't emit an error message when the scanner returns YYERRCODE
* data/skeletons/yacc.c (yyparse): When the scanner returns YYERRCODE, go directly to error recovery (yyerrlab1). However, don't keep the error token as lookahead, that token is too special. * data/skeletons/lalr1.cc: Likewise. * examples/c/bistromathic/parse.y (yylex): Use that feature to report nicely invalid characters. * examples/c/bistromathic/bistromathic.test: Check that. * examples/test: Neutralize gratuitous differences such as rule position. * tests/calc.at: Check that case in C only. The other case seem to be working, but that's an illusion that the next commit will address (in fact, they can enter endless loops, and report the error several times anyway).
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
%code top {
|
||||
#include <ctype.h> // isdigit
|
||||
#include <math.h> // cos, sin, etc.
|
||||
#include <stdarg.h> // va_start
|
||||
#include <stdio.h> // printf
|
||||
#include <stdlib.h> // calloc
|
||||
#include <string.h> // strcmp
|
||||
@@ -45,8 +46,14 @@
|
||||
}
|
||||
|
||||
%code provides {
|
||||
# ifndef __attribute__
|
||||
# ifndef __GNUC__
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
# endif
|
||||
int yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
|
||||
void yyerror (YYLTYPE *yylloc, char const *msg);
|
||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
}
|
||||
|
||||
%code {
|
||||
@@ -249,6 +256,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
case '(': return TOK_LPAREN;
|
||||
case ')': return TOK_RPAREN;
|
||||
|
||||
case '!': return TOK_YYUNDEF;
|
||||
|
||||
case '\0': return TOK_YYEOF;
|
||||
|
||||
// Numbers.
|
||||
@@ -290,8 +299,8 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
|
||||
|
||||
// Stray characters.
|
||||
default:
|
||||
yyerror (yylloc, "error: invalid character");
|
||||
return yylex (line, yylval, yylloc);
|
||||
yyerror (yylloc, "syntax error: invalid character: %c", c);
|
||||
return TOK_YYERRCODE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,10 +380,15 @@ yyreport_syntax_error (const yypcontext_t *ctx)
|
||||
|
||||
|
||||
// Called by yyparse on error.
|
||||
void yyerror (YYLTYPE *loc, char const *msg)
|
||||
void yyerror (YYLTYPE *loc, char const *format, ...)
|
||||
{
|
||||
YY_LOCATION_PRINT (stderr, *loc);
|
||||
fprintf (stderr, ": %s\n", msg);
|
||||
fputs (": ", stderr);
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
putc ('\n', stderr);
|
||||
}
|
||||
|
||||
|
||||
@@ -535,7 +549,7 @@ int main (int argc, char const* argv[])
|
||||
#endif
|
||||
|
||||
// Enable parse traces on option -p.
|
||||
if (argc == 2 && strcmp (argv[1], "-p") == 0)
|
||||
if (1 < argc && strcmp (argv[1], "-p") == 0)
|
||||
yydebug = 1;
|
||||
init_table ();
|
||||
init_readline ();
|
||||
|
||||
Reference in New Issue
Block a user