+ /* If next token is an identifier, see if a colon follows it.
+ If one does, exit this rule now. */
+ if (t == tok_identifier)
+ {
+ bucket *ssave;
+ token_t t1;
+
+ ssave = symval;
+ t1 = lex ();
+ unlex (t1);
+ symval = ssave;
+ if (t1 == tok_colon)
+ break;
+
+ if (!first_rhs) /* JF */
+ first_rhs = symval;
+ /* Not followed by colon =>
+ process as part of this rule's rhs. */
+ }
+
+ /* If we just passed an action, that action was in the middle
+ of a rule, so make a dummy rule to reduce it to a
+ 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. */
+ bucket *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++;
+ nitems++;
+ p = symbol_list_new (sdummy);
+ /* Attach its lineno to that of the host rule. */
+ p->line = crule->line;
+ 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. */
+ nitems++;
+ p = symbol_list_new (sdummy);
+ p1->next = p;
+ p1 = p;
+
+ action_flag = 0;
+ }
+
+ if (t == tok_identifier)
+ {
+ nitems++;
+ p = symbol_list_new (symval);
+ p1->next = p;
+ p1 = p;
+ }
+ else /* handle an action. */
+ {
+ copy_action (crule, rulelength);
+ action_flag = 1;
+ xactions++; /* JF */
+ }
+ rulelength++;
+ } /* 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;
+
+ if (t == tok_prec)
+ {
+ complain (_("two @prec's in a row"));
+ t = lex ();
+ crule->ruleprec = symval;
+ t = lex ();
+ }
+ if (t == tok_guard)
+ {
+ if (!semantic_parser)
+ complain (_("%%guard present but %%semantic_parser not specified"));