bug-bison
[Top][All Lists]
Advanced

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

Re: Possible bug simple grammar


From: Paul Eggert
Subject: Re: Possible bug simple grammar
Date: Sun, 14 May 2006 23:16:35 -0700
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Thanks for that bug report.  I installed the following patch to fix
the bug.

2006-05-14  Paul Eggert  <address@hidden>

        * data/glr.c (yyreportSyntaxError): Fix off-by-one error in
        checking against YYLAST that caused the parser to miss a potential
        alternative in its diagnostic.
        Problem reported by Maria Jose Moron Fernandez in
        <http://lists.gnu.org/archive/html/bug-bison/2006-05/msg00024.html>.
        * data/lalr1.cc (yysyntax_error_): Likewise.
        * data/yacc.c (yysyntax_error): Likewise.
        * tests/regression.at (_AT_DATA_DANCER_Y): Use static array for
        tokens, in case we run into an older C compiler.
        (_AT_DATA_EXPECT2_Y, AT_CHECK_EXPECT2): New macros.
        Use them to check for the off-by-one error fixed above.

Index: data/glr.c
===================================================================
RCS file: /cvsroot/bison/bison/data/glr.c,v
retrieving revision 1.173
diff -p -u -r1.173 glr.c
--- data/glr.c  14 May 2006 20:40:34 -0000      1.173
+++ data/glr.c  15 May 2006 06:03:11 -0000
@@ -2077,7 +2077,7 @@ yyreportSyntaxError (yyGLRStack* yystack
 #if YYERROR_VERBOSE
       int yyn;
       yyn = yypact[yystackp->yytops.yystates[0]->yylrState];
-      if (YYPACT_NINF < yyn && yyn < YYLAST)
+      if (YYPACT_NINF < yyn && yyn <= YYLAST)
        {
          yySymbol yytoken = YYTRANSLATE (yychar);
          size_t yysize0 = yytnamerr (NULL, yytokenName (yytoken));
@@ -2104,7 +2104,7 @@ yyreportSyntaxError (yyGLRStack* yystack
          int yyxbegin = yyn < 0 ? -yyn : 0;
 
          /* Stay within bounds of both yycheck and yytname.  */
-         int yychecklim = YYLAST - yyn;
+         int yychecklim = YYLAST - yyn + 1;
          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
          int yycount = 1;
 
Index: data/lalr1.cc
===================================================================
RCS file: /cvsroot/bison/bison/data/lalr1.cc,v
retrieving revision 1.130
diff -p -u -r1.130 lalr1.cc
--- data/lalr1.cc       14 May 2006 20:48:24 -0000      1.130
+++ data/lalr1.cc       15 May 2006 06:03:11 -0000
@@ -838,14 +838,14 @@ b4_error_verbose_if([, int tok])[)
     YYUSE (yystate);
 #if YYERROR_VERBOSE
     int yyn = yypact_[yystate];
-    if (yypact_ninf_ < yyn && yyn < yylast_)
+    if (yypact_ninf_ < yyn && yyn <= yylast_)
       {
        /* Start YYX at -YYN if negative to avoid negative indexes in
           YYCHECK.  */
        int yyxbegin = yyn < 0 ? -yyn : 0;
 
        /* Stay within bounds of both yycheck and yytname.  */
-       int yychecklim = yylast_ - yyn;
+       int yychecklim = yylast_ - yyn + 1;
        int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
        int count = 0;
        for (int x = yyxbegin; x < yyxend; ++x)
Index: data/yacc.c
===================================================================
RCS file: /cvsroot/bison/bison/data/yacc.c,v
retrieving revision 1.139
diff -p -u -r1.139 yacc.c
--- data/yacc.c 15 May 2006 05:10:06 -0000      1.139
+++ data/yacc.c 15 May 2006 06:03:11 -0000
@@ -847,7 +847,7 @@ yysyntax_error (char *yyresult, int yyst
 {
   int yyn = yypact[yystate];
 
-  if (! (YYPACT_NINF < yyn && yyn < YYLAST))
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
     return 0;
   else
     {
@@ -885,7 +885,7 @@ yysyntax_error (char *yyresult, int yyst
       int yyxbegin = yyn < 0 ? -yyn : 0;
 
       /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn;
+      int yychecklim = YYLAST - yyn + 1;
       int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
       int yycount = 1;
 
Index: tests/regression.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/regression.at,v
retrieving revision 1.96
diff -p -u -r1.96 regression.at
--- tests/regression.at 15 May 2006 05:10:06 -0000      1.96
+++ tests/regression.at 15 May 2006 06:03:11 -0000
@@ -824,7 +824,7 @@ static int
 yylex (AT_LALR1_CC_IF([int *lval], [void]))
 [{
   static int toknum = 0;
-  int tokens[] =
+  static int tokens[] =
     {
       ':', -1
     };
@@ -864,3 +864,100 @@ AT_CLEANUP
 AT_CHECK_DANCER()
 AT_CHECK_DANCER([%glr-parser])
 AT_CHECK_DANCER([%skeleton "lalr1.cc"])
+
+
+## ------------------------------------------ ##
+## Diagnostic that expects two alternatives.  ##
+## ------------------------------------------ ##
+
+
+# _AT_DATA_EXPECT2_Y(BISON-OPTIONS)
+# --------------------------------
+m4_define([_AT_DATA_EXPECT2_Y],
+[AT_DATA_GRAMMAR([expect2.y],
+[%{
+static int yylex (AT_LALR1_CC_IF([int *], [void]));
+AT_LALR1_CC_IF([],
+[#include <stdio.h>
+static void yyerror (const char *);])
+%}
+$1
+%defines
+%error-verbose
+%token A 1000
+%token B
+
+%%
+program: /* empty */
+ | program e ';'
+ | program error ';';
+
+e: e '+' t | t;
+t: A | B;
+
+%%
+AT_LALR1_CC_IF(
+[/* A C++ error reporting function. */
+void
+yy::parser::error (const location&, const std::string& m)
+{
+  std::cerr << m << std::endl;
+}
+
+int
+yyparse ()
+{
+  yy::parser parser;
+  return parser.parse ();
+}
+],
+[static void
+yyerror (const char *s)
+{
+  fprintf (stderr, "%s\n", s);
+}])
+
+static int
+yylex (AT_LALR1_CC_IF([int *lval], [void]))
+[{
+  static int toknum = 0;
+  static int tokens[] =
+    {
+      1000, '+', '+', -1
+    };
+  ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC.  */])[
+  return tokens[toknum++];
+}]
+
+int
+main (void)
+{
+  return yyparse ();
+}
+])
+])# _AT_DATA_EXPECT2_Y
+
+
+# AT_CHECK_EXPECT2(BISON-OPTIONS)
+# ------------------------------
+# Generate the grammar, compile it, run it.
+m4_define([AT_CHECK_EXPECT2],
+[AT_SETUP([Expecting two tokens $1])
+AT_BISON_OPTION_PUSHDEFS([$1])
+_AT_DATA_EXPECT2_Y([$1])
+AT_CHECK([bison -o expect2.c expect2.y])
+AT_LALR1_CC_IF(
+  [AT_CHECK([bison -o expect2.cc expect2.y])
+   AT_COMPILE_CXX([expect2])],
+  [AT_CHECK([bison -o expect2.c expect2.y])
+   AT_COMPILE([expect2])])
+AT_PARSER_CHECK([./expect2], 1, [],
+[syntax error, unexpected '+', expecting A or B
+])
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+])
+
+AT_CHECK_EXPECT2()
+AT_CHECK_EXPECT2([%glr-parser])
+AT_CHECK_EXPECT2([%skeleton "lalr1.cc"])




reply via email to

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