-static int typed = 0;
-
-/* Incremented for each %left, %right or %nonassoc seen */
-static int lastprec = 0;
-
-static symbol_list *
-symbol_list_new (symbol_t *sym)
-{
- symbol_list *res = XMALLOC (symbol_list, 1);
- res->next = NULL;
- res->sym = sym;
- res->line = lineno;
- res->action = NULL;
- res->action_line = 0;
- res->ruleprec = NULL;
- return res;
-}
-
-/*===================\
-| Low level lexing. |
-\===================*/
-
-static void
-skip_to_char (int target)
-{
- int c;
- if (target == '\n')
- complain (_(" Skipping to next \\n"));
- else
- complain (_(" Skipping to next %c"), target);
-
- do
- c = skip_white_space ();
- while (c != target && c != EOF);
- if (c != EOF)
- ungetc (c, finput);
-}
-
-
-/*---------------------------------------------------------.
-| Read a signed integer from STREAM and return its value. |
-`---------------------------------------------------------*/
-
-static inline int
-read_signed_integer (FILE *stream)
-{
- int c = getc (stream);
- int sign = 1;
- int n = 0;
-
- if (c == '-')
- {
- c = getc (stream);
- sign = -1;
- }
-
- while (isdigit (c))
- {
- n = 10 * n + (c - '0');
- c = getc (stream);
- }
-
- ungetc (c, stream);
-
- return sign * n;
-}
-\f
-/*--------------------------------------------------------------.
-| Get the data type (alternative in the union) of the value for |
-| symbol N in rule RULE. |
-`--------------------------------------------------------------*/
-
-static char *
-get_type_name (int n, symbol_list *rule)
-{
- int i;
- symbol_list *rp;
-
- if (n < 0)
- {
- complain (_("invalid $ value"));
- return NULL;
- }
-
- rp = rule;
- i = 0;
-
- while (i < n)
- {
- rp = rp->next;
- if (rp == NULL || rp->sym == NULL)
- {
- complain (_("invalid $ value"));
- return NULL;
- }
- ++i;
- }
-
- return rp->sym->type_name;
-}
-\f
-/*------------------------------------------------------------------.
-| Copy the character C to OOUT, and insert quadigraphs when needed. |
-`------------------------------------------------------------------*/
-
-static inline void
-copy_character (struct obstack *oout, int c)
-{
- switch (c)
- {
- case '[':
- obstack_sgrow (oout, "@<:@");
- break;
-
- case ']':
- obstack_sgrow (oout, "@:>@");
- break;
-
- default:
- obstack_1grow (oout, c);
- }
-}
-
-/*------------------------------------------------------------.
-| Dump the string from FIN to OOUT if non null. MATCH is the |
-| delimiter of the string (either ' or "). |
-`------------------------------------------------------------*/
-
-static inline void
-copy_string2 (FILE *fin, struct obstack *oout, int match, int store)
-{
- int c;
-
- if (store)
- obstack_1grow (oout, match);
-
- c = getc (fin);
-
- while (c != match)
- {
- if (c == EOF)
- fatal (_("unterminated string at end of file"));
- if (c == '\n')
- {
- complain (_("unterminated string"));
- ungetc (c, fin);
- c = match; /* invent terminator */
- continue;
- }
-
- copy_character (oout, c);
-
- if (c == '\\')
- {
- c = getc (fin);
- if (c == EOF)
- fatal (_("unterminated string at end of file"));
- copy_character (oout, c);
-
- if (c == '\n')
- ++lineno;
- }
-
- c = getc (fin);
- }
-
- if (store)
- obstack_1grow (oout, c);
-}
-
-/* FIXME. */
-
-static inline void
-copy_string (FILE *fin, struct obstack *oout, int match)
-{
- copy_string2 (fin, oout, match, 1);
-}
-
-/* FIXME. */
-
-static inline void
-copy_identifier (FILE *fin, struct obstack *oout)
-{
- int c;
-
- while (isalnum (c = getc (fin)) || c == '_')
- obstack_1grow (oout, c);
-
- ungetc (c, fin);
-}
-
-
-/*------------------------------------------------------------------.
-| Dump the wannabee comment from IN to OOUT. In fact we just saw a |
-| `/', which might or might not be a comment. In any case, copy |
-| what we saw. |
-`------------------------------------------------------------------*/
-
-static inline void
-copy_comment (FILE *fin, struct obstack *oout)
-{
- int cplus_comment;
- int ended;
- int c;
-
- /* We read a `/', output it. */
- obstack_1grow (oout, '/');
-
- switch ((c = getc (fin)))
- {
- case '/':
- cplus_comment = 1;
- break;
- case '*':
- cplus_comment = 0;
- break;
- default:
- ungetc (c, fin);
- return;
- }
-
- obstack_1grow (oout, c);
- c = getc (fin);
-
- ended = 0;
- while (!ended)
- {
- if (!cplus_comment && c == '*')
- {
- while (c == '*')
- {
- obstack_1grow (oout, c);
- c = getc (fin);
- }
-
- if (c == '/')
- {
- obstack_1grow (oout, c);
- ended = 1;
- }
- }
- else if (c == '\n')
- {
- ++lineno;
- obstack_1grow (oout, c);
- if (cplus_comment)
- ended = 1;
- else
- c = getc (fin);
- }
- else if (c == EOF)
- fatal (_("unterminated comment"));
- else
- {
- copy_character (oout, c);
- c = getc (fin);
- }
- }
-}
-
-
-/*-------------------------------------------------------------------.
-| FIN is pointing to a location (i.e., a `@'). Output to OOUT a |
-| reference to this location. RULE_LENGTH 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 inline void
-copy_at (FILE *fin, struct obstack *oout, int rule_length)
-{
- int c = getc (fin);
- locations_flag = 1;
-
- if (c == '$')
- {
- obstack_sgrow (oout, "]b4_lhs_location[");
- }
- else if (isdigit (c) || c == '-')
- {
- int n;
-
- ungetc (c, fin);
- n = read_signed_integer (fin);
- if (n > rule_length)
- complain (_("invalid value: %s%d"), "@", n);
- else
- obstack_fgrow2 (oout, "]b4_rhs_location([%d], [%d])[",
- rule_length, n);
- }
- else
- {
- char buf[] = "@c";
- buf[1] = c;
- complain (_("%s is invalid"), quote (buf));
- }
-}
-
-
-/*------------------------------------------------------------------.
-| FIN is pointing to a wannabee semantic value (i.e., a `$'). |
-| |
-| Possible inputs: $[<TYPENAME>]($|integer) |
-| |
-| Output to OOUT a reference to this semantic value. RULE_LENGTH 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 inline void
-copy_dollar (FILE *fin, struct obstack *oout,
- symbol_list *rule, int rule_length)
-{
- 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;
- c = getc (fin);
- }
-
- if (c == '$')
- {
- if (!type_name)
- type_name = get_type_name (0, rule);
- if (!type_name && typed)
- complain (_("$$ of `%s' has no declared type"),
- rule->sym->tag);
- if (!type_name)
- type_name = "";
- obstack_fgrow1 (oout,
- "]b4_lhs_value([%s])[", type_name);
- }
- else if (isdigit (c) || c == '-')
- {
- int n;
- ungetc (c, fin);
- n = read_signed_integer (fin);
-
- if (n > rule_length)
- complain (_("invalid value: %s%d"), "$", n);
- else
- {
- if (!type_name && n > 0)
- type_name = get_type_name (n, rule);
- if (!type_name && typed)
- complain (_("$%d of `%s' has no declared type"),
- n, rule->sym->tag);
- if (!type_name)
- type_name = "";
- obstack_fgrow3 (oout, "]b4_rhs_value([%d], [%d], [%s])[",
- rule_length, n, type_name);
- }
- }
- else
- {
- char buf[] = "$c";
- buf[1] = c;
- complain (_("%s is invalid"), quote (buf));
- }
-}