+static inline void
+copy_dollar (FILE *fin, struct obstack *oout,
+ symbol_list *rule, int stack_offset)
+{
+ int c = getc (fin);
+ const char *type_name = NULL;
+
+ /* Get the type name if explicit. */
+ if (c == '<')
+ {
+ read_type_name (fin);
+ type_name = token_buffer;
+ value_components_used = 1;
+ c = getc (fin);
+ }
+
+ if (c == '$')
+ {
+ obstack_sgrow (oout, "yyval");
+
+ if (!type_name)
+ type_name = get_type_name (0, rule);
+ if (type_name)
+ obstack_fgrow1 (oout, ".%s", type_name);
+ if (!type_name && typed)
+ complain (_("$$ of `%s' has no declared type"),
+ rule->sym->tag);
+ }
+ else if (isdigit (c) || c == '-')
+ {
+ int n;
+ ungetc (c, fin);
+ n = read_signed_integer (fin);
+
+ if (n > stack_offset)
+ complain (_("invalid value: %s%d"), "$", n);
+ else
+ {
+ if (!type_name && n > 0)
+ type_name = get_type_name (n, rule);
+
+ /* Offset is always 0 if parser has already popped the stack
+ pointer. */
+ obstack_fgrow1 (oout, "yyvsp[%d]",
+ n - (semantic_parser ? 0 : stack_offset));
+
+ if (type_name)
+ obstack_fgrow1 (oout, ".%s", type_name);
+ if (!type_name && typed)
+ complain (_("$%d of `%s' has no declared type"),
+ n, rule->sym->tag);
+ }
+ }
+ else
+ {
+ char buf[] = "$c";
+ buf[1] = c;
+ complain (_("%s is invalid"), quote (buf));
+ }
+}
+\f
+/*-------------------------------------------------------------------.
+| Copy the contents of a `%{ ... %}' into the definitions file. The |
+| `%{' has already been read. Return after reading the `%}'. |
+`-------------------------------------------------------------------*/
+
+static void
+copy_definition (void)
+{
+ int c;
+ /* -1 while reading a character if prev char was %. */
+ int after_percent;
+
+ if (!no_lines_flag)
+ {
+ obstack_fgrow2 (&attrs_obstack, muscle_find ("linef"),
+ lineno, quotearg_style (c_quoting_style,
+ muscle_find ("filename")));
+ }