- if (header_extension)
- complain (_("multiple %%header_extension declarations"));
- fscanf (finput, "%s", buff);
- header_extension = xstrdup (buff);
-}
-
-/*------------------------------------------.
-| Parse what comes after %source_extension. |
-`------------------------------------------*/
-
-static void
-parse_source_extension_decl (void)
-{
- char buff[32];
-
- if (src_extension)
- complain (_("multiple %%source_extension declarations"));
- fscanf (finput, "%s", buff);
- src_extension = xstrdup (buff);
-}
-
-/*----------------------------------------------------------------.
-| Read from finput until `%%' is seen. Discard the `%%'. Handle |
-| any `%' declarations, and copy the contents of any `%{ ... %}' |
-| groups to ATTRS_OBSTACK. |
-`----------------------------------------------------------------*/
-
-static void
-read_declarations (void)
-{
- int c;
- int tok;
-
- for (;;)
- {
- c = skip_white_space ();
-
- if (c == '%')
- {
- tok = parse_percent_token ();
-
- switch (tok)
- {
- case tok_two_percents:
- return;
-
- case tok_percent_left_curly:
- copy_definition ();
- break;
-
- case tok_token:
- parse_token_decl (token_sym, nterm_sym);
- break;
-
- case tok_nterm:
- parse_token_decl (nterm_sym, token_sym);
- break;
-
- case tok_type:
- parse_type_decl ();
- break;
-
- case tok_start:
- parse_start_decl ();
- break;
-
- case tok_union:
- parse_union_decl ();
- break;
-
- case tok_expect:
- parse_expect_decl ();
- break;
-
- case tok_thong:
- parse_thong_decl ();
- break;
-
- case tok_left:
- parse_assoc_decl (left_assoc);
- break;
-
- case tok_right:
- parse_assoc_decl (right_assoc);
- break;
-
- case tok_nonassoc:
- parse_assoc_decl (non_assoc);
- break;
-
- case tok_hdrext:
- parse_header_extension_decl ();
- break;
-
- case tok_srcext:
- parse_source_extension_decl ();
- break;
-
- case tok_define:
- parse_macro_decl ();
- break;
-
- case tok_skel:
- parse_skel_decl ();
- break;
-
- case tok_noop:
- break;
-
- default:
- complain (_("unrecognized: %s"), token_buffer);
- skip_to_char ('%');
- }
- }
- else if (c == EOF)
- fatal (_("no input grammar"));
- else
- {
- char buf[] = "c";
- buf[0] = c;
- complain (_("unknown character: %s"), quote (buf));
- skip_to_char ('%');
- }
- }
-}
-\f
-/*-------------------------------------------------------------------.
-| Assuming that a `{' has just been seen, copy everything up to the |
-| matching `}' 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. |
-`-------------------------------------------------------------------*/
-
-static void
-copy_action (symbol_list *rule, int stack_offset)
-{
- int c;
- int count;
- char buf[4096];
-
- /* offset is always 0 if parser has already popped the stack pointer */
- if (semantic_parser)
- stack_offset = 0;
-
- sprintf (buf, "\ncase %d:\n", nrules);
- obstack_grow (&action_obstack, buf, strlen (buf));
-
- if (!no_lines_flag)
- {
- sprintf (buf, "#line %d %s\n",
- lineno, quotearg_style (c_quoting_style,
- macro_find ("filename")));
- obstack_grow (&action_obstack, buf, strlen (buf));
- }
- obstack_1grow (&action_obstack, '{');
-
- count = 1;
- c = getc (finput);
-
- while (count > 0)
- {
- while (c != '}')
- {
- switch (c)
- {
- case '\n':
- obstack_1grow (&action_obstack, c);
- lineno++;
- break;
-
- 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,
- 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);
- }
- }
-
- 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;
-
- case '$':
- copy_dollar (finput, &guard_obstack, rule, stack_offset);
- break;
-
- case '@':
- copy_at (finput, &guard_obstack, stack_offset);
- break;
-
- case EOF:
- fatal ("%s", _("unterminated %guard clause"));
-
- default:
- obstack_1grow (&guard_obstack, c);
- }
-
- if (c != '}' || count != 0)
- c = getc (finput);
- }
-
- c = skip_white_space ();
-
- obstack_sgrow (&guard_obstack, ";\n break;}");
- if (c == '{')
- copy_action (rule, stack_offset);
- else if (c == '=')
- {
- c = getc (finput); /* why not skip_white_space -wjh */
- if (c == '{')
- copy_action (rule, stack_offset);
- }
- else
- ungetc (c, finput);
-}
-\f
-
-static void
-record_rule_line (void)