add LR(0) output

This should not be used to generate parsers.  My point is actually to
facilitate debugging (when tweaking the generation of the LR(0)
automaton for instance, not carying -yet- about lookaheads).

* src/reader.c (prepare_percent_define_front_end_variables): Add lr(0).
* src/conflicts.c (set_conflicts): Be robust to reds not having
lookaheads at all.
* src/ielr.c (LrType, lr_type_get): Adjust.
(ielr): Implement support for LR(0).
* src/lalr.c (lalr_free): Don't free LA when it's not computed.
This commit is contained in:
Akim Demaille
2019-01-27 18:29:17 +01:00
parent 0d44f83fcc
commit e346210c03
3 changed files with 68 additions and 42 deletions

View File

@@ -369,13 +369,16 @@ set_conflicts (state *s, symbol **errors)
s->solved_conflicts_xml = obstack_finish0 (&solved_conflicts_xml_obstack); s->solved_conflicts_xml = obstack_finish0 (&solved_conflicts_xml_obstack);
/* Loop over all rules which require lookahead in this state. Check /* Loop over all rules which require lookahead in this state. Check
for conflicts not resolved above. */ for conflicts not resolved above.
for (int i = 0; i < reds->num; ++i)
{ reds->lookahead_tokens can be NULL if the LR type is LR(0). */
if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) if (reds->lookahead_tokens)
conflicts[s->number] = 1; for (int i = 0; i < reds->num; ++i)
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); {
} if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set))
conflicts[s->number] = 1;
bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]);
}
} }

View File

@@ -36,7 +36,36 @@
#include "symtab.h" #include "symtab.h"
/** Records the value of the \%define variable lr.type. */ /** Records the value of the \%define variable lr.type. */
typedef enum { LR_TYPE__LALR, LR_TYPE__IELR, LR_TYPE__CANONICAL_LR } LrType; typedef enum
{
LR_TYPE__LR0,
LR_TYPE__LALR,
LR_TYPE__IELR,
LR_TYPE__CANONICAL_LR
} LrType;
/* The user's requested LR type. */
static LrType
lr_type_get (void)
{
char *type = muscle_percent_define_get ("lr.type");
LrType res;
if (STREQ (type, "lr(0)"))
res = LR_TYPE__LR0;
else if (STREQ (type, "lalr"))
res = LR_TYPE__LALR;
else if (STREQ (type, "ielr"))
res = LR_TYPE__IELR;
else if (STREQ (type, "canonical-lr"))
res = LR_TYPE__CANONICAL_LR;
else
{
aver (false);
abort ();
}
free (type);
return res;
}
/** /**
* \post: * \post:
@@ -1052,46 +1081,39 @@ ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows,
} }
/* The user's requested LR type. */
static LrType
lr_type_get (void)
{
char *type = muscle_percent_define_get ("lr.type");
LrType res;
if (STREQ (type, "lalr"))
res = LR_TYPE__LALR;
else if (STREQ (type, "ielr"))
res = LR_TYPE__IELR;
else if (STREQ (type, "canonical-lr"))
res = LR_TYPE__CANONICAL_LR;
else
{
aver (false);
abort ();
}
free (type);
return res;
}
void void
ielr (void) ielr (void)
{ {
LrType lr_type = lr_type_get (); LrType lr_type = lr_type_get ();
/* Phase 0: LALR(1). */ /* Phase 0: LALR(1). */
timevar_push (tv_lalr); switch (lr_type)
if (lr_type == LR_TYPE__CANONICAL_LR)
set_goto_map ();
else
lalr ();
if (lr_type == LR_TYPE__LALR)
{ {
case LR_TYPE__LR0:
timevar_push (tv_lalr);
set_goto_map ();
timevar_pop (tv_lalr);
return;
case LR_TYPE__CANONICAL_LR:
timevar_push (tv_lalr);
set_goto_map ();
timevar_pop (tv_lalr);
break;
case LR_TYPE__LALR:
timevar_push (tv_lalr);
lalr ();
bitsetv_free (goto_follows); bitsetv_free (goto_follows);
timevar_pop (tv_lalr); timevar_pop (tv_lalr);
return; return;
case LR_TYPE__IELR:
timevar_push (tv_lalr);
lalr ();
timevar_pop (tv_lalr);
break;
} }
timevar_pop (tv_lalr);
{ {
bitsetv follow_kernel_items; bitsetv follow_kernel_items;

View File

@@ -754,11 +754,12 @@ prepare_percent_define_front_end_variables (void)
/* Check %define front-end variables. */ /* Check %define front-end variables. */
{ {
static char const * const values[] = { static char const * const values[] =
"lr.type", "lalr", "ielr", "canonical-lr", NULL, {
"lr.default-reduction", "most", "consistent", "accepting", NULL, "lr.type", "lr(0)", "lalr", "ielr", "canonical-lr", NULL,
NULL "lr.default-reduction", "most", "consistent", "accepting", NULL,
}; NULL
};
muscle_percent_define_check_values (values); muscle_percent_define_check_values (values);
} }
} }