summaryrefslogtreecommitdiff
path: root/examples/c
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2020-07-11 13:48:43 +0200
committerAkim Demaille <akim.demaille@gmail.com>2020-07-11 18:05:50 +0200
commitc47e1174d4418b544b340d82f031219318eb2f51 (patch)
tree3b26facf5f13e25b338a064a20a0ba07c421fd44 /examples/c
parent093eeb27e9d08f72809660411b928d3683371fc0 (diff)
downloadbison-c47e1174d4418b544b340d82f031219318eb2f51.tar.gz
bistromathic: do not display parse errors on completion
Currently autocompletion on a line with errors leaks the error messages. It can be useful to let the user know, but GNU Readline does not provide us with an nice way to display the error. So we actually break into the current line of the user. So instead, do not show these errors. * examples/c/bistromathic/parse.y (user_context): New. Use %param to pass it to the parser and scanner. Keep quiet when in computing autocompletion.
Diffstat (limited to 'examples/c')
-rwxr-xr-xexamples/c/bistromathic/bistromathic.test3
-rw-r--r--examples/c/bistromathic/parse.y49
2 files changed, 36 insertions, 16 deletions
diff --git a/examples/c/bistromathic/bistromathic.test b/examples/c/bistromathic/bistromathic.test
index 4f8e24ad..74e8db9c 100755
--- a/examples/c/bistromathic/bistromathic.test
+++ b/examples/c/bistromathic/bistromathic.test
@@ -314,7 +314,6 @@ EOF
run -n 0 '> 1++ ''
> ''
err: 1.3: syntax error: expected - or ( or number or function or variable before +
-err: 1.3: syntax error: expected - or ( or number or function or variable before +
'
# And even when the error was recovered from.
@@ -324,7 +323,5 @@ EOF
run -n 0 '> (1++2) + 3 + ''
> ''
err: 1.4: syntax error: expected - or ( or number or function or variable before +
-err: 1.4: syntax error: expected - or ( or number or function or variable before +
-err: 1.4: syntax error: expected - or ( or number or function or variable before +
err: 1.15: syntax error: expected - or ( or number or function or variable before end of file
'
diff --git a/examples/c/bistromathic/parse.y b/examples/c/bistromathic/parse.y
index 43b41e32..0dca4ae0 100644
--- a/examples/c/bistromathic/parse.y
+++ b/examples/c/bistromathic/parse.y
@@ -65,6 +65,13 @@
symrec *putsym (char const *name, int sym_type);
symrec *getsym (char const *name);
+
+ // Exchanging information with the parser.
+ typedef struct
+ {
+ // Whether to not emit error messages.
+ int silent;
+ } user_context;
}
// Emitted in the header file, after the definition of YYSTYPE.
@@ -74,9 +81,13 @@
# define __attribute__(Spec) /* empty */
# endif
# endif
- yytoken_kind_t yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc);
- void yyerror (YYLTYPE *loc, char const *format, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
+
+ yytoken_kind_t
+ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
+ const user_context *uctx);
+ void yyerror (YYLTYPE *loc, const user_context *uctx,
+ char const *format, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
}
// Emitted in the implementation file.
@@ -116,6 +127,9 @@
// Generate the parser description file (calc.output).
%verbose
+// User information exchanged with the parser and scanner.
+%param {const user_context *uctx}
+
// Generate YYSTYPE from the types assigned to symbols.
%define api.value.type union
%token
@@ -171,7 +185,7 @@ exp:
{
if ($r == 0)
{
- yyerror (&@$, "error: division by zero");
+ yyerror (&@$, uctx, "error: division by zero");
YYERROR;
}
else
@@ -258,7 +272,8 @@ symbol_count (void)
`----------*/
yytoken_kind_t
-yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
+yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc,
+ const user_context *uctx)
{
int c;
@@ -328,7 +343,7 @@ yylex (const char **line, YYSTYPE *yylval, YYLTYPE *yylloc)
// Stray characters.
default:
- yyerror (yylloc, "syntax error: invalid character: %c", c);
+ yyerror (yylloc, uctx, "syntax error: invalid character: %c", c);
return TOK_YYerror;
}
}
@@ -366,8 +381,11 @@ error_format_string (int argc)
int
-yyreport_syntax_error (const yypcontext_t *ctx)
+yyreport_syntax_error (const yypcontext_t *ctx, const user_context *uctx)
{
+ if (uctx->silent)
+ return 0;
+
enum { ARGS_MAX = 6 };
yysymbol_kind_t arg[ARGS_MAX];
int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
@@ -412,8 +430,11 @@ yyreport_syntax_error (const yypcontext_t *ctx)
// Called by yyparse on error.
-void yyerror (YYLTYPE *loc, char const *format, ...)
+void yyerror (YYLTYPE *loc, const user_context *uctx, char const *format, ...)
{
+ if (uctx->silent)
+ return;
+
YY_LOCATION_PRINT (stderr, *loc);
fputs (": ", stderr);
va_list args;
@@ -449,12 +470,13 @@ xstrndup (const char *string, size_t n)
static int
process_line (YYLTYPE *lloc, const char *line)
{
+ user_context uctx = {0};
yypstate *ps = yypstate_new ();
int status = 0;
do {
YYSTYPE lval;
- yytoken_kind_t token = yylex (&line, &lval, lloc);
- status = yypush_parse (ps, token, &lval, lloc);
+ yytoken_kind_t token = yylex (&line, &lval, lloc, &uctx);
+ status = yypush_parse (ps, token, &lval, lloc, &uctx);
} while (status == YYPUSH_MORE);
yypstate_delete (ps);
lloc->last_line++;
@@ -469,6 +491,7 @@ expected_tokens (const char *input,
int *tokens, int ntokens)
{
YYDPRINTF ((stderr, "expected_tokens (\"%s\")", input));
+ user_context uctx = {1};
// Parse the current state of the line.
yypstate *ps = yypstate_new ();
@@ -476,11 +499,11 @@ expected_tokens (const char *input,
YYLTYPE lloc = { 1, 1, 1, 1 };
do {
YYSTYPE lval;
- yytoken_kind_t token = yylex (&input, &lval, &lloc);
- // Don't let the parser know when we reach the end of input.
+ yytoken_kind_t token = yylex (&input, &lval, &lloc, &uctx);
+ // Don't let the parse know when we reach the end of input.
if (token == TOK_YYEOF)
break;
- status = yypush_parse (ps, token, &lval, &lloc);
+ status = yypush_parse (ps, token, &lval, &lloc, &uctx);
} while (status == YYPUSH_MORE);
int res = 0;