+ case '{':
+ obstack_1grow (&action_obstack, c);
+ count++;
+ break;
+
+ case '\'':
+ case '"':
+ copy_string (finput, &action_obstack, c);
+ break;
+
+ case '/':
+ copy_comment (finput, &action_obstack);
+ break;
+
+ case '$':
+ copy_dollar (finput, &action_obstack,
+ rule, stack_offset);
+ break;
+
+ case '@':
+ copy_at (finput, &action_obstack,
+ rule, stack_offset);
+ break;
+
+ case EOF:
+ fatal (_("unmatched %s"), "`{'");
+
+ default:
+ obstack_1grow (&action_obstack, c);
+ }
+
+ c = getc (finput);
+ }
+
+ /* above loop exits when c is '}' */
+
+ if (--count)
+ {
+ obstack_1grow (&action_obstack, c);
+ c = getc (finput);
+ }
+ }
+
+ /* As a Bison extension, add the ending semicolon. Since some Yacc
+ don't do that, help people using bison as a Yacc finding their
+ missing semicolons. */
+ if (yacc_flag)
+ obstack_sgrow (&action_obstack, "}\n break;");
+ else
+ obstack_sgrow (&action_obstack, ";\n break;}");
+}
+\f
+/*-------------------------------------------------------------------.
+| After `%guard' is seen in the input file, copy the actual guard |
+| into the guards file. If the guard is followed by an action, copy |
+| that into the actions file. STACK_OFFSET is the number of values |
+| in the current rule so far, which says where to find `$0' with |
+| respect to the top of the stack, for the simple parser in which |
+| the stack is not popped until after the guard is run. |
+`-------------------------------------------------------------------*/
+
+static void
+copy_guard (symbol_list *rule, int stack_offset)
+{
+ int c;
+ int count;
+ int brace_flag = 0;
+
+ /* offset is always 0 if parser has already popped the stack pointer */
+ if (semantic_parser)
+ stack_offset = 0;
+
+ obstack_fgrow1 (&guard_obstack, "\ncase %d:\n", nrules);
+ if (!no_lines_flag)
+ obstack_fgrow2 (&guard_obstack, "#line %d %s\n",
+ lineno, quotearg_style (c_quoting_style, infile));
+ obstack_1grow (&guard_obstack, '{');
+
+ count = 0;
+ c = getc (finput);
+
+ while (brace_flag ? (count > 0) : (c != ';'))
+ {
+ switch (c)
+ {
+ case '\n':
+ obstack_1grow (&guard_obstack, c);
+ lineno++;
+ break;
+
+ case '{':
+ obstack_1grow (&guard_obstack, c);
+ brace_flag = 1;
+ count++;
+ break;
+
+ case '}':
+ obstack_1grow (&guard_obstack, c);
+ if (count > 0)
+ count--;
+ else
+ {
+ complain (_("unmatched %s"), "`}'");
+ c = getc (finput); /* skip it */
+ }
+ break;
+
+ case '\'':
+ case '"':
+ copy_string (finput, &guard_obstack, c);
+ break;
+
+ case '/':
+ copy_comment (finput, &guard_obstack);
+ break;