From e346210c038bc5c6ab2aca99e04f8452181406e1 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 27 Jan 2019 18:29:17 +0100 Subject: [PATCH] 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. --- src/conflicts.c | 17 +++++----- src/ielr.c | 82 +++++++++++++++++++++++++++++++------------------ src/reader.c | 11 ++++--- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/conflicts.c b/src/conflicts.c index c849e898..734b8c15 100644 --- a/src/conflicts.c +++ b/src/conflicts.c @@ -369,13 +369,16 @@ set_conflicts (state *s, symbol **errors) s->solved_conflicts_xml = obstack_finish0 (&solved_conflicts_xml_obstack); /* Loop over all rules which require lookahead in this state. Check - for conflicts not resolved above. */ - for (int i = 0; i < reds->num; ++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]); - } + for conflicts not resolved above. + + reds->lookahead_tokens can be NULL if the LR type is LR(0). */ + if (reds->lookahead_tokens) + for (int i = 0; i < reds->num; ++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]); + } } diff --git a/src/ielr.c b/src/ielr.c index fe1217b1..47ce38c3 100644 --- a/src/ielr.c +++ b/src/ielr.c @@ -36,7 +36,36 @@ #include "symtab.h" /** 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: @@ -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 ielr (void) { LrType lr_type = lr_type_get (); /* Phase 0: LALR(1). */ - timevar_push (tv_lalr); - if (lr_type == LR_TYPE__CANONICAL_LR) - set_goto_map (); - else - lalr (); - if (lr_type == LR_TYPE__LALR) + switch (lr_type) { + 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); timevar_pop (tv_lalr); return; + + case LR_TYPE__IELR: + timevar_push (tv_lalr); + lalr (); + timevar_pop (tv_lalr); + break; } - timevar_pop (tv_lalr); { bitsetv follow_kernel_items; diff --git a/src/reader.c b/src/reader.c index 075d6c7a..dbc834a4 100644 --- a/src/reader.c +++ b/src/reader.c @@ -754,11 +754,12 @@ prepare_percent_define_front_end_variables (void) /* Check %define front-end variables. */ { - static char const * const values[] = { - "lr.type", "lalr", "ielr", "canonical-lr", NULL, - "lr.default-reduction", "most", "consistent", "accepting", NULL, - NULL - }; + static char const * const values[] = + { + "lr.type", "lr(0)", "lalr", "ielr", "canonical-lr", NULL, + "lr.default-reduction", "most", "consistent", "accepting", NULL, + NULL + }; muscle_percent_define_check_values (values); } }