bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/4] bistromathic: do not display parse error on completion


From: Akim Demaille
Subject: [PATCH 3/4] bistromathic: do not display parse error on completion
Date: Sat, 11 Jul 2020 18:08:17 +0200

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 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.
---
 examples/c/bistromathic/bistromathic.test |  3 --
 examples/c/bistromathic/parse.y           | 49 +++++++++++++++++------
 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;
-- 
2.27.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]