]> git.saurik.com Git - bison.git/blobdiff - tests/glr-regression.at
Add bison.html.
[bison.git] / tests / glr-regression.at
index ae15e4cfef2037a692baedceee5f8191dc5a3424..966730b88041ef6424d12e7d48922f41aa26a982 100644 (file)
@@ -34,7 +34,7 @@ AT_DATA_GRAMMAR([glr-regr1.y],
 #define YYSTYPE int
 static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1);
 int yylex (void);
-int yyerror (char const *msg);
+void yyerror (char const *msg);
 %}
 
 
@@ -70,11 +70,10 @@ main (void)
   return yyparse ();
 }
 
-int
+void
 yyerror (char const *msg)
 {
   fprintf (stderr, "%s\n", msg);
-  exit (4);
 }
 
 
@@ -121,7 +120,7 @@ AT_DATA_GRAMMAR([glr-regr2a.y],
 /* Reported by S. Eken */
 
 %{
-  #define YYSTYPE char *
+  #define YYSTYPE char const *
   #define yyfalse 0
   #define yytrue 1
 
@@ -156,10 +155,11 @@ var_list:
     { $$ = $1; }
   | var ',' var_list
     {
-      $$ = malloc (strlen ($1) + 1 + strlen ($3) + 1);
-      strcpy ($$, $1);
-      strcat ($$, ",");
-      strcat ($$, $3);
+      char *s = (char *) malloc (strlen ($1) + 1 + strlen ($3) + 1);
+      strcpy (s, $1);
+      strcat (s, ",");
+      strcat (s, $3);
+      $$ = s;
     }
   ;
 
@@ -174,6 +174,7 @@ int
 yylex (void)
 {
   char buf[50];
+  char *s;
   switch (fscanf (yyin, " %1[a-z,]", buf)) {
   case 1:
     return buf[0];
@@ -183,11 +184,12 @@ yylex (void)
     break;
   }
   if (fscanf (yyin, "%49s", buf) != 1)
-    abort ();
+    return 0;
   if (sizeof buf - 1 <= strlen (buf))
     abort ();
-  yylval = malloc (strlen (buf) + 1);
-  strcpy (yylval, buf);
+  s = (char *) malloc (strlen (buf) + 1);
+  strcpy (s, buf);
+  yylval = s;
   return 'V';
 }
 
@@ -200,7 +202,7 @@ int
 main (int argc, char **argv)
 {
   yyin = stdin;
-  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 1;
+  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 3;
   return yyparse ();
 }
 ]])
@@ -310,7 +312,7 @@ int yylex (void)
 
 int main(int argc, char* argv[]) {
   yyin = stdin;
-  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 1;
+  if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 3;
   return yyparse ();
 }
 ]])
@@ -325,3 +327,312 @@ AT_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]], 0,
 ]], [])
 
 AT_CLEANUP
+
+
+## ---------------------------------------------------------------------- ##
+## Duplicate representation of merged trees                               ##
+## Thanks to Joel E. Denny for this test; see                             ##
+## <http://lists.gnu.org/archive/html/help-bison/2005-07/msg00013.html>.  ##
+## ---------------------------------------------------------------------- ##
+
+AT_SETUP([Duplicate representation of merged trees])
+
+AT_DATA_GRAMMAR([glr-regr4.y],
+[[
+%union { char *ptr; }
+%type <ptr> S A A1 A2 B
+%glr-parser
+
+%{
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <string.h>
+  static char *merge (YYSTYPE, YYSTYPE);
+  static char *make_value (char const *, char const *);
+  static void yyerror (char const *);
+  static int yylex (void);
+%}
+
+%%
+
+tree: S { printf ("%s\n", $1); } ;
+
+S:
+  A   %merge<merge> { $$ = make_value ("S", $1); }
+  | B %merge<merge> { $$ = make_value ("S", $1); }
+  ;
+
+A:
+  A1   %merge<merge> { $$ = make_value ("A", $1); }
+  | A2 %merge<merge> { $$ = make_value ("A", $1); }
+  ;
+
+A1: 'a' { $$ = make_value ("A1", "'a'"); } ;
+A2: 'a' { $$ = make_value ("A2", "'a'"); } ;
+B:  'a' { $$ = make_value ("B", "'a'");  } ;
+
+%%
+
+static int
+yylex (void)
+{
+  static char const *input = "a";
+  return *input++;
+}
+
+int
+main (void)
+{
+  return yyparse ();
+}
+
+static char *
+make_value (char const *parent, char const *child)
+{
+  char const format[] = "%s <- %s";
+  char *value =
+    (char *) malloc (strlen (parent) + strlen (child) + sizeof format);
+  sprintf (value, format, parent, child);
+  return value;
+}
+
+static char *
+merge (YYSTYPE s1, YYSTYPE s2)
+{
+  char const format[] = "merge{ %s and %s }";
+  char *value =
+    (char *) malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format);
+  sprintf (value, format, s1.ptr, s2.ptr);
+  return value;
+}
+
+static void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+]])
+
+AT_CHECK([[bison -o glr-regr4.c glr-regr4.y]], 0, [],
+[glr-regr4.y: conflicts: 1 reduce/reduce
+])
+AT_COMPILE([glr-regr4])
+
+AT_CHECK([[./glr-regr4]], 0,
+[[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' }
+]], [])
+
+AT_CLEANUP
+
+
+## ------------------------------------------------------------------------- ##
+## User destructor for unresolved GLR semantic value                         ##
+## Thanks to Joel E. Denny for this test; see                                ##
+## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00016.html>.  ##
+## ------------------------------------------------------------------------- ##
+
+AT_SETUP([User destructor for unresolved GLR semantic value])
+
+AT_DATA_GRAMMAR([glr-regr5.y],
+[[
+%{
+  #include <stdio.h>
+  #include <stdlib.h>
+  static void yyerror (char const *);
+  static int yylex (void);
+  enum { MAGIC_VALUE = -1057808125 }; /* originally chosen at random */
+%}
+
+%glr-parser
+%union { int value; }
+%type <value> start
+
+%destructor {
+  if ($$ != MAGIC_VALUE)
+    {
+      fprintf (stderr, "Bad destructor call.\n");
+      exit (EXIT_FAILURE);
+    }
+} start
+
+%%
+
+start:
+   'a' { $$ = MAGIC_VALUE; }
+   | 'a' { $$ = MAGIC_VALUE; }
+   ;
+
+%%
+
+static int
+yylex (void)
+{
+  static char const *input = "a";
+  return *input++;
+}
+
+static void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+int
+main (void)
+{
+  return yyparse () != 1;
+}
+]])
+
+AT_CHECK([[bison -o glr-regr5.c glr-regr5.y]], 0, [],
+[glr-regr5.y: conflicts: 1 reduce/reduce
+])
+AT_COMPILE([glr-regr5])
+
+AT_CHECK([[./glr-regr5]], 0, [],
+[syntax is ambiguous
+])
+
+AT_CLEANUP
+
+
+## ------------------------------------------------------------------------- ##
+## User destructor after an error during a split parse                       ##
+## Thanks to Joel E. Denny for this test; see                                ##
+## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00029.html>.  ##
+## ------------------------------------------------------------------------- ##
+
+AT_SETUP([User destructor after an error during a split parse])
+
+AT_DATA_GRAMMAR([glr-regr6.y],
+[[
+%{
+  #include <stdio.h>
+  #include <stdlib.h>
+  static void yyerror (char const *);
+  static int yylex (void);
+%}
+
+%glr-parser
+%union { int value; }
+%type <value> 'a'
+
+%destructor {
+  printf ("Destructor called.\n");
+} 'a'
+
+%%
+
+start: 'a' | 'a' ;
+
+%%
+
+static int
+yylex (void)
+{
+  static char const *input = "a";
+  return *input++;
+}
+
+static void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+int
+main (void)
+{
+  return yyparse () != 1;
+}
+]])
+
+AT_CHECK([[bison -o glr-regr6.c glr-regr6.y]], 0, [],
+[glr-regr6.y: conflicts: 1 reduce/reduce
+])
+AT_COMPILE([glr-regr6])
+
+AT_CHECK([[./glr-regr6]], 0,
+[Destructor called.
+],
+[syntax is ambiguous
+])
+
+AT_CLEANUP
+
+
+## ------------------------------------------------------------------------- ##
+## Duplicated user destructor for lookahead                                  ##
+## Thanks to Joel E. Denny for this test; see                                ##
+## <http://lists.gnu.org/archive/html/bison-patches/2005-08/msg00035.html>.  ##
+## ------------------------------------------------------------------------- ##
+
+AT_SETUP([Duplicated user destructor for lookahead])
+
+AT_DATA_GRAMMAR([glr-regr7.y],
+[[
+%{
+  #include <stdio.h>
+  #include <stdlib.h>
+  static void yyerror (char const *);
+  static int yylex (void);
+  #define YYSTACKEXPANDABLE 0
+%}
+
+%glr-parser
+%union { int *count; }
+%type <count> 'a'
+
+%destructor {
+  if ((*$$)++)
+    fprintf (stderr, "Destructor called on same value twice.\n");
+} 'a'
+
+%%
+
+start:
+    stack1 start
+  | stack2 start
+  | /* empty */
+  ;
+stack1: 'a' ;
+stack2: 'a' ;
+
+%%
+
+static int
+yylex (void)
+{
+  yylval.count = malloc (sizeof (int));
+  if (!yylval.count)
+    {
+      fprintf (stderr, "Test inconclusive.\n");
+      exit (EXIT_FAILURE);
+    }
+  *yylval.count = 0;
+  return 'a';
+}
+
+static void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+int
+main (void)
+{
+  return yyparse ();
+}
+]])
+
+AT_CHECK([[bison -o glr-regr7.c glr-regr7.y]], 0, [],
+[glr-regr7.y: conflicts: 2 reduce/reduce
+])
+AT_COMPILE([glr-regr7])
+
+AT_CHECK([[exit 77; ./glr-regr7]], 2, [],
+[memory exhausted
+])
+
+AT_CLEANUP