[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Complain about hidden left recursion in GLR parsing
From: |
Sylvain Schmitz |
Subject: |
Re: Complain about hidden left recursion in GLR parsing |
Date: |
Mon, 13 Mar 2006 22:26:53 +0100 |
User-agent: |
Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7) Gecko/20040616 |
There is a bug in the patch I sent earlier; here is the same patch,
corrected.
--
Sorry,
Sylvain
--- bison/src/closure.c 2005-12-10 00:51:25.000000000 +0100
+++ bison-cvs20060222/src/closure.c 2006-03-13 19:45:24.000000000 +0100
@@ -29,9 +29,11 @@
#include <quotearg.h>
#include "closure.h"
+#include "complain.h"
#include "derives.h"
#include "getargs.h"
#include "gram.h"
+#include "nullable.h"
#include "reader.h"
#include "symtab.h"
@@ -44,6 +46,7 @@
/* internal data. See comments before set_fderives and set_firsts. */
static bitsetv fderives = NULL;
static bitsetv firsts = NULL;
+static bitsetv next_vars = NULL;
/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
#define FDERIVES(Var) fderives[(Var) - ntokens]
@@ -120,6 +123,10 @@
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
| (5)) is set. |
+| |
+| NEXT_VARS is similar but also takes nullable symbols into |
+| account. It is used for the detection of hidden left recursion |
+| in GLR parsing. |
`------------------------------------------------------------------*/
static void
@@ -128,13 +135,29 @@
symbol_number i, j;
firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
+ next_vars = bitsetv_create (nvars, nvars, BITSET_FIXED);
for (i = ntokens; i < nsyms; i++)
for (j = 0; derives[i - ntokens][j]; ++j)
{
item_number sym = derives[i - ntokens][j]->rhs[0];
if (ISVAR (sym))
- bitset_set (FIRSTS (i), sym - ntokens);
+ {
+ int k = 1;
+ bitset_set (FIRSTS (i), sym - ntokens);
+ bitset_set (next_vars [i - ntokens], sym - ntokens);
+ /* Keep going in the rule right hand side if the current
+ symbol is nullable. */
+ while (nullable[sym - ntokens]
+ && (sym = derives[i - ntokens][j]->rhs[k]) >= 0
+ && ISVAR (sym))
+ {
+ bitset_set (next_vars [i - ntokens], sym - ntokens);
+ k++;
+ }
+ if (ISVAR (sym))
+ bitset_set (next_vars [i - ntokens], sym - ntokens);
+ }
}
if (trace_flag & trace_sets)
@@ -145,6 +168,43 @@
if (trace_flag & trace_sets)
print_firsts ();
+
+
+ if (glr_parser)
+ {
+ bitsetv_transitive_closure (next_vars);
+ for (i = ntokens; i < nsyms; i++)
+ if (bitset_test (next_vars[i - ntokens], i - ntokens))
+ for (j = 0; derives[i - ntokens][j]; ++j)
+ {
+ item_number sym = derives[i - ntokens][j]->rhs[0];
+ if (ISVAR(sym) && nullable[sym - ntokens])
+ {
+ int k = 1;
+ while ((sym = derives[i - ntokens][j]->rhs[k++]) >= 0
+ && ISVAR (sym)
+ && nullable[sym - ntokens]
+ && !bitset_test (next_vars[sym-ntokens],i-ntokens));
+
+ if (sym >= 0
+ &&
+ ((ISVAR (sym)
+ && bitset_test (next_vars[sym-ntokens],i-ntokens))
+ ||
+ ((sym = derives[i - ntokens][j]->rhs[k++]) >= 0
+ && ISVAR (sym)
+ && bitset_test (next_vars[sym-ntokens],i-ntokens))))
+ {
+ complain_at (derives[i - ntokens][j]->location,
+ "%s: %s: ",
+ _("error"),
+ _("hidden left recursion in rule"));
+ rule_print (derives[i - ntokens][j], stderr);
+ }
+ }
+ }
+ }
+ bitsetv_free (next_vars);
}
/*-------------------------------------------------------------------.