Yacc now understands %expect keyword. This should help prevent yacc from
authoretheisen <etheisen@openbsd.org>
Sun, 4 Feb 1996 08:37:00 +0000 (08:37 +0000)
committeretheisen <etheisen@openbsd.org>
Sun, 4 Feb 1996 08:37:00 +0000 (08:37 +0000)
gagging on GNU bison grammer.

usr.bin/yacc/defs.h
usr.bin/yacc/mkpar.c
usr.bin/yacc/reader.c

index f3d9b1d..4772d37 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: defs.h,v 1.1.1.1 1995/10/18 08:47:05 deraadt Exp $ */
+/*     $Id: defs.h,v 1.2 1996/02/04 08:37:00 etheisen Exp $ */
 
 #include <assert.h>
 #include <ctype.h>
@@ -66,6 +66,7 @@
 #define START 7
 #define UNION 8
 #define IDENT 9
+#define EXPECT 10
 
 
 /*  symbol classes  */
@@ -263,6 +264,7 @@ extern short *to_state;
 
 extern action **parser;
 extern int SRtotal;
+extern int SRexpect;
 extern int RRtotal;
 extern short *SRconflicts;
 extern short *RRconflicts;
index b1d5f57..b66784b 100644 (file)
@@ -1,11 +1,12 @@
 #ifndef lint
-static char rcsid[] = "$Id: mkpar.c,v 1.1.1.1 1995/10/18 08:47:05 deraadt Exp $";
+static char rcsid[] = "$Id: mkpar.c,v 1.2 1996/02/04 08:37:01 etheisen Exp $";
 #endif /* not lint */
 
 #include "defs.h"
 
 action **parser;
 int SRtotal;
+int SRexpect = 0;
 int RRtotal;
 short *SRconflicts;
 short *RRconflicts;
@@ -279,21 +280,21 @@ remove_conflicts()
 
 total_conflicts()
 {
-    fprintf(stderr, "%s: ", myname);
-    if (SRtotal == 1)
-       fprintf(stderr, "1 shift/reduce conflict");
-    else if (SRtotal > 1)
-       fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
-
-    if (SRtotal && RRtotal)
-       fprintf(stderr, ", ");
+    /* Warn if s/r != expect or if any r/r */
+    if ((SRtotal != SRexpect) || RRtotal)
+    {
+        if (SRtotal == 1)
+            fprintf(stderr, "%s: 1 shift/reduce conflict\n", myname);
+        else if (SRtotal > 1)
+            fprintf(stderr, "%s: %d shift/reduce conflicts\n", myname,
+                    SRtotal);
+    }
 
     if (RRtotal == 1)
-       fprintf(stderr, "1 reduce/reduce conflict");
+        fprintf(stderr, "%s: 1 reduce/reduce conflict\n", myname);
     else if (RRtotal > 1)
-       fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
-
-    fprintf(stderr, ".\n");
+       fprintf(stderr, "%s: %d reduce/reduce conflicts\n", myname,
+                RRtotal);
 }
 
 
index 8943753..f4c0de4 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
-static char rcsid[] = "$Id: reader.c,v 1.1.1.1 1995/10/18 08:47:06 deraadt Exp $";
+static char rcsid[] = "$Id: reader.c,v 1.2 1996/02/04 08:37:02 etheisen Exp $";
 #endif /* not lint */
 
 #include "defs.h"
@@ -250,6 +250,8 @@ keyword()
            return (UNION);
        if (strcmp(cache, "ident") == 0)
            return (IDENT);
+       if (strcmp(cache, "expect") == 0)
+           return (EXPECT);
     }
     else
     {
@@ -890,6 +892,50 @@ int assoc;
 }
 
 
+/*
+ * %expect requires special handling
+ * as it really isn't part of the yacc
+ * grammar only a flag for yacc proper.
+ */
+declare_expect(assoc)
+int assoc;
+{
+    register int c;
+
+    if (assoc != EXPECT) ++prec;
+
+    /*
+     * Stay away from nextc - doesn't
+     * detect EOL and will read to EOF.
+     */
+    c = *++cptr;
+    if (c == EOF) unexpected_EOF();
+
+    for(;;)
+    {
+        if (isdigit(c))
+        {
+           SRexpect = get_number();
+            break;
+        }
+        /*
+         * Looking for number before EOL.
+         * Spaces, tabs, and numbers are ok,
+         * words, punc., etc. are syntax errors.
+         */
+        else if (c == '\n' || isalpha(c) || !isspace(c))
+        {
+            syntax_error(lineno, line, cptr);
+        }
+        else
+        {
+            c = *++cptr;
+            if (c == EOF) unexpected_EOF();
+        }
+    }
+}
+
+
 declare_types()
 {
     register int c;
@@ -973,6 +1019,10 @@ read_declarations()
            declare_tokens(k);
            break;
 
+       case EXPECT:
+           declare_expect(k);
+            break;
+
        case TYPE:
            declare_types();
            break;