bison-patches
[Top][All Lists]
Advanced

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

FTR:


From: Akim Demaille
Subject: FTR:
Date: Wed, 29 Apr 2020 07:58:51 +0200

For the records, I decided not to do anything about this.  I think
the cure is worse than the disease, as some "great" leader loves to
put it...

If the user wants 5 tokens at most, and would like to know if there
are actually more than 5, or really 0, then let her ask for 6, and
not use the 6th one.  That's simpler, clearer.

commit a99799bd6de1baafe159dc41ad455dc5bae0b488
Author: Akim Demaille <address@hidden>
Date:   Wed Apr 29 07:34:42 2020 +0200

    all: fix the interface of yyexpected_tokens
    
    The user gives yyexpected_tokens a limit: the max number of tokens she
    wants to hear about.  That's because an error message that reports a
    bazillion of possible tokens is useless.
    
    In that case yyexpected_tokens returned 0, so the user would not know
    if there are really no possible expected tokens (yes, that's
    possible), or just too many.
    
    There are several ways to tell the user in which situation she's in:
    
    - return some E2MANY, a negative value.  Then it makes the pattern
    
        int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
        if (argsize < 0)
          return argsize;
    
      no longer valid, as for E2MANY (i) the user must generate the error
      message anyway, and (ii) she should not return E2MANY
    
    - return ARGS_MAX + 1.  Then it makes it dangerous for the user, as
      she has to iterate update `min (ARGS_MAX, argsize)`.
    
    Returning 0 is definitely for the user, as it tells her "this is not
    an error, just generate your message without a list of expecting
    tokens".  So let's still return 0, but set arg[0] to the empty token
    when the list is really empty.
    
    * data/skeletons/glr.c, data/skeletons/lalr1.cc, data/skeletons/lalr1.java
    * data/skeletons/yacc.c (yyexpected_tokens): Put the empty symbol
    first if there are no possible tokens at all.
    * examples/c/bistromathic/parse.y: Demonstrate how to use that.

diff --git a/data/skeletons/glr.c b/data/skeletons/glr.c
index 1cb99662..3d5d2c42 100644
--- a/data/skeletons/glr.c
+++ b/data/skeletons/glr.c
@@ -2121,6 +2121,8 @@ yypcontext_expected_tokens (const yyGLRStack* yystackp,
               yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
           }
     }
+  if (yyarg && yycount == 0 && 0 < yyargn)
+    yyarg[0] = ]b4_symbol(-2, kind)[;
   return yycount;
 }]])[
 
diff --git a/data/skeletons/lalr1.cc b/data/skeletons/lalr1.cc
index 81aff234..244db851 100644
--- a/data/skeletons/lalr1.cc
+++ b/data/skeletons/lalr1.cc
@@ -1316,6 +1316,8 @@ b4_dollar_popdef])[]dnl
             }
       }
 ]])[
+    if (yyarg && yycount == 0 && 0 < yyargn)
+      yyarg[0] = symbol_kind::]b4_symbol(-2, kind)[;
     return yycount;
   }
 
diff --git a/data/skeletons/lalr1.java b/data/skeletons/lalr1.java
index e2d4bcad..f708ada0 100644
--- a/data/skeletons/lalr1.java
+++ b/data/skeletons/lalr1.java
@@ -950,6 +950,8 @@ b4_dollar_popdef[]dnl
                   yyarg[yycount++] = SymbolKind.get (yyx);
               }
         }
+      if (yyarg != null && yycount == yyoffset && yyoffset < yyargn)
+        yyarg[yycount] = null;
       return yycount - yyoffset;
     }
   }
diff --git a/data/skeletons/yacc.c b/data/skeletons/yacc.c
index 6fed7de5..0ba11979 100644
--- a/data/skeletons/yacc.c
+++ b/data/skeletons/yacc.c
@@ -1197,6 +1197,8 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
               yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx);
           }
     }]])[
+  if (yyarg && yycount == 0 && 0 < yyargn)
+    yyarg[0] = ]b4_symbol(-2, kind)[;
   return yycount;
 }
 
diff --git a/examples/c/bistromathic/bistromathic.test 
b/examples/c/bistromathic/bistromathic.test
index 1e5bd0e1..fbbcf9c3 100755
--- a/examples/c/bistromathic/bistromathic.test
+++ b/examples/c/bistromathic/bistromathic.test
@@ -66,7 +66,7 @@ cat >input <<EOF
 EOF
 run 0 '> *
 > ''
-err: 1.1: syntax error: expected end of file or - or ( or exit or number or 
function or variable before *'
+err: 1.1: syntax error: expected end of file or - or ( or exit or number or 
function etc., before *'
 
 cat >input <<EOF
 1 + 2 * * 3
diff --git a/examples/c/bistromathic/parse.y b/examples/c/bistromathic/parse.y
index 925e06f5..87f9726d 100644
--- a/examples/c/bistromathic/parse.y
+++ b/examples/c/bistromathic/parse.y
@@ -331,7 +331,7 @@ error_format_string (int argc)
     case 5: return _("%@: syntax error: expected %0e or %1e or %2e or %3e 
before %u");
     case 6: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or 
%4e before %u");
     case 7: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or 
%4e or %5e before %u");
-    case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or 
%4e or %5e or %6e before %u");
+    case 8: return _("%@: syntax error: expected %0e or %1e or %2e or %3e or 
%4e or %5e etc., before %u");
     }
 }
 
@@ -339,12 +339,15 @@ error_format_string (int argc)
 int
 yyreport_syntax_error (const yypcontext_t *ctx)
 {
-  enum { ARGS_MAX = 7 };
+  enum { ARGS_MAX = 6 };
   yysymbol_kind_t arg[ARGS_MAX];
   int argsize = yypcontext_expected_tokens (ctx, arg, ARGS_MAX);
   if (argsize < 0)
     return argsize;
-  const char *format = error_format_string (1 + argsize);
+  const int too_many_expected_tokens = argsize == 0 && arg[0] != 
YYSYMBOL_YYEMPTY;
+  if (too_many_expected_tokens)
+    argsize = ARGS_MAX;
+  const char *format = error_format_string (1 + argsize + 
too_many_expected_tokens);
 
   while (*format)
     // %@: location.




reply via email to

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