]> ocean-lang.org Git - ocean/commitdiff
parsergen: don't report expected shift/reduce conflicts.
authorNeilBrown <neil@brown.name>
Thu, 9 May 2019 11:59:07 +0000 (21:59 +1000)
committerNeilBrown <neil@brown.name>
Thu, 9 May 2019 11:59:07 +0000 (21:59 +1000)
If a NEWLINE is being treated as a grammar symbol which will sometimes
force a reduction, then an apparent SHIFT/REDUCE conflict that could be
resolved to REDUCE by a newline and would default to shift, is expected
and not really a conflict.  So don't report those.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/parsergen.mdc

index bc1a604d3a8d696bb666d4262c735740b3648d92..3c816fa009a23b080597800272f1600123470702 100644 (file)
@@ -1796,6 +1796,15 @@ terminals to items where that terminal could be shifted and another
 which maps terminals to items that could be reduced when the terminal
 is in look-ahead.  We report when we get conflicts between the two.
 
+As a special case, if we find a SHIFT/REDUCE conflict, where a
+terminal that could be shifted is in the lookahead set of some
+reducable item, then set check if the reducable item also have
+`TK_newline` in its lookahead set.  If it does, then a newline will
+force and reduction, but anything else can reasonably be shifts, so
+that isn't really a conflict.  Such apparent conflicts do not get
+reported.  This will not affect a "tradtional" grammar that does not
+include newlines as token.
+
        static int conflicts_slr(struct grammar *g, enum grammar_type type)
        {
                int i;
@@ -1823,7 +1832,7 @@ is in look-ahead.  We report when we get conflicts between the two.
                                                symset_add(&shifts, sym, itm);
                                }
                        }
-                       /* Now look for reduction and conflicts */
+                       /* Now look for reductions and conflicts */
                        for (j = 0; j < is->items.cnt; j++) {
                                unsigned short itm = is->items.syms[j];
                                int p = item_prod(itm);
@@ -1841,7 +1850,7 @@ is in look-ahead.  We report when we get conflicts between the two.
                                int k;
                                for (k = 0; k < la.cnt; k++) {
                                        int pos = symset_find(&shifts, la.syms[k]);
-                                       if (pos >= 0) {
+                                       if (pos >= 0 && symset_find(&la, TK_newline) < 0) {
                                                printf("  State %d has SHIFT/REDUCE conflict on ", i);
                                                prtxt(g->symtab[la.syms[k]]->name);
                                                printf(":\n");