]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
(check_and_convert_grammar): New function.
[bison.git] / src / reader.c
index c0547e08c8c4bd09dc5108630e57b00ca05d5d69..0fa162d9ce786c650fad8db949ea0bba2ea3298c 100644 (file)
@@ -36,6 +36,8 @@
 #include "symlist.h"
 #include "symtab.h"
 
+static void check_and_convert_grammar (void);
+
 static symbol_list *grammar = NULL;
 static bool start_flag = false;
 merger_list *merge_functions;
@@ -210,6 +212,20 @@ grammar_current_rule_begin (symbol *lhs, location loc)
 }
 
 
+/*-----------------------------------------------------------------.
+| A symbol is typed if it has a declared %type, or if it is a      |
+| mid-rule symbol (i.e., the generated LHS replacing a mid-rule    |
+| action) that was assigned to, as in `exp: { $$ = 1; } { $$ = $1; |
+| }'.                                                              |
+`-----------------------------------------------------------------*/
+
+static bool
+symbol_typed_p (const symbol_list *s)
+{
+  return (s->sym->type_name
+         || (s->midrule && s->midrule->used));
+}
+
 /*----------------------------------------------------------------.
 | Check that the rule R is properly defined.  For instance, there |
 | should be no type clash on the default action.                  |
@@ -251,7 +267,7 @@ grammar_rule_check (const symbol_list *r)
     int n = 0;
     for (; l && l->sym; l = l->next, ++n)
       if (! (l->used
-            || !l->sym->type_name
+            || !symbol_typed_p (l)
             /* The default action, $$ = $1, `uses' both.  */
             || (!r->action && (n == 0 || n == 1))))
        {
@@ -318,14 +334,16 @@ grammar_midrule_action (void)
     grammar = midrule;
 
   /* End the dummy's rule.  */
-  previous_rule_end = symbol_list_new (NULL, dummy_location);
-  previous_rule_end->next = current_rule;
+  midrule->next = symbol_list_new (NULL, dummy_location);
+  grammar_rule_check (midrule);
+  midrule->next->next = current_rule;
 
-  midrule->next = previous_rule_end;
+  previous_rule_end = midrule->next;
 
   /* Insert the dummy nonterminal replacing the midrule action into
-     the current rule.  */
+     the current rule.  Bind it to its dedicated rule.  */
   grammar_current_rule_symbol_append (dummy, dummy_location);
+  grammar_end->midrule = midrule;
 }
 
 /* Set the precedence symbol of the current rule to PRECSYM. */
@@ -402,7 +420,11 @@ packgram (void)
   rule_number ruleno = 0;
   symbol_list *p = grammar;
 
-  ritem = xnmalloc (nritems, sizeof *ritem);
+  ritem = xnmalloc (nritems + 1, sizeof *ritem);
+
+  /* This sentinel is used by build_relations in gram.c.  */
+  *ritem++ = 0;
+
   rules = xnmalloc (nrules, sizeof *rules);
 
   while (p)
@@ -449,8 +471,7 @@ packgram (void)
        p = p->next;
     }
 
-  if (itemno != nritems)
-    abort ();
+  assert (itemno == nritems);
 
   if (trace_flag & trace_sets)
     ritem_print (stderr);
@@ -496,12 +517,22 @@ reader (void)
   scanner_initialize ();
   gram_parse ();
 
-  /* If something went wrong during the parsing, don't try to
-     continue.  */
-  if (complaint_issued)
-    return;
+  if (! complaint_issued)
+    check_and_convert_grammar ();
+
+  xfclose (gram_in);
+}
+
+
+/*-------------------------------------------------------------.
+| Check the grammar that has just been read, and convert it to |
+| internal form.                                              |
+`-------------------------------------------------------------*/
 
-  /* Grammar has been read.  Do some checking */
+static void
+check_and_convert_grammar (void)
+{
+  /* Grammar has been read.  Do some checking.  */
   if (nrules == 0)
     fatal (_("no rules in the input grammar"));
 
@@ -518,7 +549,7 @@ reader (void)
       endtoken->user_token_number = 0;
     }
 
-  /* Insert the initial rule, which line is that of the first rule
+  /* Insert the initial rule, whose line is that of the first rule
      (not that of the start symbol):
 
      accept: %start EOF.  */
@@ -534,10 +565,7 @@ reader (void)
     grammar = p;
   }
 
-  if (! (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars))
-    abort ();
-
-  xfclose (gram_in);
+  assert (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
 
   /* Assign the symbols their symbol numbers.  Write #defines for the
      token symbols into FDEFINES if requested.  */