]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
* src/reader.c (grammar_midrule_action): New, Eved out from
[bison.git] / src / reader.c
index 5587c32acf5ab1dd60aa27603375cec07048af26..949d74bb26cc657d2b3ebe09e64631c8fff05232 100644 (file)
@@ -656,13 +656,7 @@ parse_assoc_decl (associativity assoc)
          break;
 
        case tok_identifier:
-         if (symval->class == nterm_sym)
-           complain (_("symbol %s redefined"), symval->tag);
-         if (symval->number == NUMBER_UNDEFINED)
-           {
-             symval->number = ntokens++;
-             symval->class = token_sym;
-           }
+         symbol_class_set (symval, token_sym);
          symbol_precedence_set (symval, lastprec, assoc);
          if (name)
            symbol_type_set (symval, name);
@@ -671,7 +665,7 @@ parse_assoc_decl (associativity assoc)
        case tok_number:
          if (prev == tok_identifier)
            {
-             symval->user_token_number = numval;
+             symbol_user_token_number_set (symval, numval);
            }
          else
            {
@@ -1078,19 +1072,109 @@ gensym (void)
 | in the rules section.                                              |
 `-------------------------------------------------------------------*/
 
+/* The (currently) last symbol of GRAMMAR. */
+symbol_list *grammar_end = NULL;
+
+/* Append S to the GRAMMAR. */
+static void
+grammar_symbol_append (symbol_t *s)
+{
+  symbol_list *p = symbol_list_new (s);
+
+  if (grammar_end)
+    grammar_end->next = p;
+  else
+    grammar = p;
+
+  grammar_end = p;
+}
+
+/* The rule currently being defined, and the previous rule.  Point to
+   the first symbol of each list: their lhs.  */
+symbol_list *current_rule = NULL;
+symbol_list *previous_rule = NULL;
+
+
+/* Create a new rule for LHS in to the GRAMMAR. */
+
+static void
+grammar_rule_begin (symbol_t *lhs)
+{
+  if (!start_flag)
+    {
+      startsymbol = lhs;
+      start_flag = 1;
+    }
+
+  /* Start a new rule and record its lhs.  */
+  ++nrules;
+  ++nritems;
+
+  previous_rule = grammar_end;
+  grammar_symbol_append (lhs);
+  current_rule = grammar_end;
+
+  /* Mark the rule's lhs as a nonterminal if not already so.  */
+
+  if (lhs->class == unknown_sym)
+    {
+      lhs->class = nterm_sym;
+      lhs->number = nvars;
+      ++nvars;
+    }
+  else if (lhs->class == token_sym)
+    complain (_("rule given for %s, which is a token"), lhs->tag);
+}
+
+/* The previous action turns out the be a mid-rule action.  Attach it
+   to the current rule, i.e., create a dummy symbol, attach it this
+   mid-rule action, and append this dummy nonterminal to the current
+   rule.  */
+
+static void
+grammar_midrule_action (void)
+{
+  /* Since the action was written out with this rule's number, we must
+     give the new rule this number by inserting the new rule before
+     it.  */
+
+  /* Make a dummy nonterminal, a gensym.  */
+  symbol_t *sdummy = gensym ();
+  symbol_list *midrule_action = symbol_list_new (sdummy);
+
+  /* Make a new rule, whose body is empty, before the current one, so
+     that the action just read can belong to it.  */
+  ++nrules;
+  ++nritems;
+  /* Attach its lineno to that of the host rule.  */
+  midrule_action->line = current_rule->line;
+  /* Move the action from the host rule to this one.  */
+  midrule_action->action = current_rule->action;
+  midrule_action->action_line = current_rule->action_line;
+  current_rule->action = NULL;
+
+  if (previous_rule)
+    previous_rule->next = midrule_action;
+  else
+    grammar = midrule_action;
+
+  /* End of the rule. */
+  previous_rule = symbol_list_new (NULL);
+  previous_rule->next = current_rule;
+
+  midrule_action->next = previous_rule;
+
+  /* Insert the dummy generated by that rule into this rule.  */
+  ++nritems;
+  grammar_symbol_append (sdummy);
+}
+
+
 static void
 readgram (void)
 {
   token_t t;
   symbol_t *lhs = NULL;
-  symbol_list *p = NULL;
-  symbol_list *p1 = NULL;
-
-  /* Points to first symbol_list of current rule. its symbol is the
-     lhs of the rule.  */
-  symbol_list *crule = NULL;
-  /* Points to the symbol_list preceding crule.  */
-  symbol_list *crule1 = NULL;
 
   t = lex ();
 
@@ -1107,12 +1191,6 @@ readgram (void)
          {
            lhs = symval;
 
-           if (!start_flag)
-             {
-               startsymbol = lhs;
-               start_flag = 1;
-             }
-
            t = lex ();
            if (t != tok_colon)
              {
@@ -1120,39 +1198,13 @@ readgram (void)
                unlex (t);
              }
          }
-
        if (nrules == 0 && t == tok_bar)
          {
            complain (_("grammar starts with vertical bar"));
            lhs = symval;       /* BOGUS: use a random symval */
          }
-       /* start a new rule and record its lhs.  */
-
-       ++nrules;
-       ++nritems;
-
-       p = symbol_list_new (lhs);
-
-       crule1 = p1;
-       if (p1)
-         p1->next = p;
-       else
-         grammar = p;
-
-       p1 = p;
-       crule = p;
-
-       /* mark the rule's lhs as a nonterminal if not already so.  */
-
-       if (lhs->class == unknown_sym)
-         {
-           lhs->class = nterm_sym;
-           lhs->number = nvars;
-           ++nvars;
-         }
-       else if (lhs->class == token_sym)
-         complain (_("rule given for %s, which is a token"), lhs->tag);
 
+       grammar_rule_begin (lhs);
        /* read the rhs of the rule.  */
 
        for (;;)
@@ -1161,7 +1213,7 @@ readgram (void)
            if (t == tok_prec)
              {
                t = lex ();
-               crule->ruleprec = symval;
+               current_rule->ruleprec = symval;
                t = lex ();
              }
 
@@ -1196,56 +1248,18 @@ readgram (void)
               non-terminal.  */
            if (action_flag)
              {
-               /* Since the action was written out with this rule's
-                  number, we must give the new rule this number by
-                  inserting the new rule before it.  */
-
-               /* Make a dummy nonterminal, a gensym.  */
-               symbol_t *sdummy = gensym ();
-
-               /* Make a new rule, whose body is empty, before the
-                  current one, so that the action just read can
-                  belong to it.  */
-               ++nrules;
-               ++nritems;
-               p = symbol_list_new (sdummy);
-               /* Attach its lineno to that of the host rule. */
-               p->line = crule->line;
-               /* Move the action from the host rule to this one. */
-               p->action = crule->action;
-               p->action_line = crule->action_line;
-               crule->action = NULL;
-
-               if (crule1)
-                 crule1->next = p;
-               else
-                 grammar = p;
-               /* End of the rule. */
-               crule1 = symbol_list_new (NULL);
-               crule1->next = crule;
-
-               p->next = crule1;
-
-               /* Insert the dummy generated by that rule into this
-                  rule.  */
-               ++nritems;
-               p = symbol_list_new (sdummy);
-               p1->next = p;
-               p1 = p;
-
+               grammar_midrule_action ();
                action_flag = 0;
              }
 
            if (t == tok_identifier)
              {
                ++nritems;
-               p = symbol_list_new (symval);
-               p1->next = p;
-               p1 = p;
+               grammar_symbol_append (symval);
              }
            else                /* handle an action.  */
              {
-               parse_action (crule, rulelength);
+               parse_action (current_rule, rulelength);
                action_flag = 1;
                ++xactions;     /* JF */
              }
@@ -1253,15 +1267,13 @@ readgram (void)
          }                     /* end of  read rhs of rule */
 
        /* Put an empty link in the list to mark the end of this rule  */
-       p = symbol_list_new (NULL);
-       p1->next = p;
-       p1 = p;
+       grammar_symbol_append (NULL);
 
        if (t == tok_prec)
          {
            complain (_("two @prec's in a row"));
            t = lex ();
-           crule->ruleprec = symval;
+           current_rule->ruleprec = symval;
            t = lex ();
          }
 
@@ -1270,7 +1282,7 @@ readgram (void)
            /* This case never occurs -wjh */
            if (action_flag)
              complain (_("two actions at end of one rule"));
-           parse_action (crule, rulelength);
+           parse_action (current_rule, rulelength);
            action_flag = 1;
            ++xactions; /* -wjh */
            t = lex ();
@@ -1313,15 +1325,17 @@ readgram (void)
      (not that of the start symbol):
 
      axiom: %start EOF.  */
-  p = symbol_list_new (axiom);
-  p->line = grammar->line;
-  p->next = symbol_list_new (startsymbol);
-  p->next->next = symbol_list_new (eoftoken);
-  p->next->next->next = symbol_list_new (NULL);
-  p->next->next->next->next = grammar;
-  nrules += 1;
-  nritems += 3;
-  grammar = p;
+  {
+    symbol_list *p = symbol_list_new (axiom);
+    p->line = grammar->line;
+    p->next = symbol_list_new (startsymbol);
+    p->next->next = symbol_list_new (eoftoken);
+    p->next->next->next = symbol_list_new (NULL);
+    p->next->next->next->next = grammar;
+    nrules += 1;
+    nritems += 3;
+    grammar = p;
+  }
 
   if (nsyms > SHRT_MAX)
     fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),