]> git.saurik.com Git - bison.git/blobdiff - tests/conflicts.at
Thank the developer of the initial push parser implementation.
[bison.git] / tests / conflicts.at
index f2f7861c4196ab9d5b4983aa992f921797a1364d..705419b95b8c296c685a6664540f3463470f1335 100644 (file)
@@ -1,7 +1,6 @@
 # Exercising Bison on conflicts.                         -*- Autotest -*-
 
-# Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software
-# Foundation, Inc.
+# Copyright (C) 2002-2005, 2007-2010 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -112,6 +111,153 @@ AT_PARSER_CHECK([./input '0<0>0'], [1], [],
          [syntax error, unexpected '>'
 ])
 
+# We must disable default reductions in inconsistent states in order to
+# have an explicit list of all expected tokens.  (However, unless we use
+# canonical LR, lookahead sets are merged for different left contexts,
+# so it is still possible to have extra incorrect tokens in the expected
+# list.  That just doesn't happen to be a problem for this test case.)
+
+AT_BISON_CHECK([-Dlr.default-reductions=consistent -o input.c input.y])
+AT_COMPILE([input])
+
+AT_PARSER_CHECK([./input '0<0'])
+AT_PARSER_CHECK([./input '0<0<0'], [1], [],
+         [syntax error, unexpected '<', expecting $end
+])
+
+AT_PARSER_CHECK([./input '0>0'])
+AT_PARSER_CHECK([./input '0>0>0'], [1], [],
+         [syntax error, unexpected '>', expecting $end
+])
+
+AT_PARSER_CHECK([./input '0<0>0'], [1], [],
+         [syntax error, unexpected '>', expecting $end
+])
+
+AT_CLEANUP
+
+
+
+## ------------------------------------------- ##
+## parse.error=verbose and consistent errors.  ##
+## ------------------------------------------- ##
+
+AT_SETUP([[parse.error=verbose and consistent errors]])
+
+m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [
+
+AT_BISON_CHECK([$1[ -o input.c input.y]])
+AT_COMPILE([[input]])
+
+m4_pushdef([AT_EXPECTING], [m4_if($3, [ab], [[, expecting 'a' or 'b']],
+                                  $3, [a],  [[, expecting 'a']],
+                                  $3, [b],  [[, expecting 'b']])])
+
+AT_PARSER_CHECK([[./input]], [[1]], [],
+[[syntax error, unexpected ]$2[]AT_EXPECTING[
+]])
+
+m4_popdef([AT_EXPECTING])
+
+])
+
+AT_DATA_GRAMMAR([input.y],
+[[%code {
+  #include <assert.h>
+  #include <stdio.h>
+  int yylex (void);
+  void yyerror (char const *);
+  #define USE(Var)
+}
+
+%define parse.error verbose
+
+// The point isn't to test IELR here, but state merging happens to
+// complicate the example.
+%define lr.type ielr
+
+%nonassoc 'a'
+
+// If yylval=0 here, then we know that the 'a' destructor is being
+// invoked incorrectly for the 'b' set in the semantic action below.
+// All 'a' tokens are returned by yylex, which sets yylval=1.
+%destructor {
+  if (!$$)
+    fprintf (stderr, "Wrong destructor.\n");
+} 'a'
+
+%%
+
+// The lookahead assigned by the semantic action isn't needed before
+// either error action is encountered.  In a previous version of Bison,
+// this was a problem as it meant yychar was not translated into yytoken
+// before either error action.  The second error action thus invoked a
+// destructor that it selected according to the incorrect yytoken.  The
+// first error action would have reported an incorrect unexpected token
+// except that, due to another bug, the unexpected token is not reported
+// at all because the error action is the default action in a consistent
+// state.  That bug still needs to be fixed.
+start: error-reduce consistent-error 'a' { USE ($3); } ;
+
+error-reduce:
+  'a' 'a' consistent-reduction consistent-error 'a'
+  { USE (($1, $2, $5)); }
+| 'a' error
+  { USE ($1); }
+;
+
+consistent-reduction: /*empty*/ {
+  assert (yychar == YYEMPTY);
+  yylval = 0;
+  yychar = 'b';
+} ;
+
+consistent-error:
+  'a' { USE ($1); }
+| /*empty*/ %prec 'a'
+;
+
+// Provide another context in which all rules are useful so that this
+// test case looks a little more realistic.
+start: 'b' consistent-error 'b' ;
+
+%%
+
+int
+yylex (void)
+{
+  static char const *input = "aa";
+  yylval = 1;
+  return *input++;
+}
+
+void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+int
+main (void)
+{
+  return yyparse ();
+}
+]])
+
+# See comments in grammar for why this test doesn't succeed.
+AT_XFAIL_IF([[:]])
+
+AT_CONSISTENT_ERRORS_CHECK([], [['b']], [[none]])
+AT_CONSISTENT_ERRORS_CHECK([[-Dlr.default-reductions=consistent]],
+                           [['b']], [[none]])
+
+# Canonical LR doesn't foresee the error for 'a'!
+AT_CONSISTENT_ERRORS_CHECK([[-Dlr.default-reductions=accepting]],
+                           [[$end]], [[a]])
+AT_CONSISTENT_ERRORS_CHECK([[-Flr.type=canonical-lr]], [[$end]], [[a]])
+
+m4_popdef([AT_CONSISTENT_ERRORS_CHECK])
+
 AT_CLEANUP