-#include "conflicts.h"
-#include "muscle_tab.h"
-
-typedef struct symbol_list
-{
- struct symbol_list *next;
- bucket *sym;
- int line;
- bucket *ruleprec;
-}
-symbol_list;
-
-int lineno;
-char **tags;
-short *user_toknums;
-static symbol_list *grammar;
-static int start_flag;
-static bucket *startval;
-
-/* Nonzero if components of semantic values are used, implying
- they must be unions. */
-static int value_components_used;
-
-/* Nonzero if %union has been seen. */
-static int typed;
-
-/* Incremented for each %left, %right or %nonassoc seen */
-static int lastprec;
-
-static bucket *errtoken;
-static bucket *undeftoken;
-
-
-static symbol_list *
-symbol_list_new (bucket *sym)
-{
- symbol_list *res = XMALLOC (symbol_list, 1);
- res->next = NULL;
- res->sym = sym;
- res->line = lineno;
- res->ruleprec = NULL;
- return res;
-}
-
-\f
-
-/*===================\
-| 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
-/*------------------------------------------------------------.
-| 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;
- }
-
- obstack_1grow (oout, c);
-
- if (c == '\\')
- {
- c = getc (fin);
- if (c == EOF)
- fatal (_("unterminated string at end of file"));
- obstack_1grow (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 OUT1 and OUT2 (which can be |
-| NULL). In fact we just saw a `/', which might or might not be a |
-| comment. In any case, copy what we saw. |
-| |
-| OUT2 might be NULL. |
-`-----------------------------------------------------------------*/
-
-static inline void
-copy_comment2 (FILE *fin, struct obstack *oout1, struct obstack *oout2)
-{
- int cplus_comment;
- int ended;
- int c;
-
- /* We read a `/', output it. */
- obstack_1grow (oout1, '/');
- if (oout2)
- obstack_1grow (oout2, '/');
-
- switch ((c = getc (fin)))
- {
- case '/':
- cplus_comment = 1;
- break;
- case '*':
- cplus_comment = 0;
- break;
- default:
- ungetc (c, fin);
- return;
- }
-
- obstack_1grow (oout1, c);
- if (oout2)
- obstack_1grow (oout2, c);
- c = getc (fin);
-
- ended = 0;
- while (!ended)
- {
- if (!cplus_comment && c == '*')
- {
- while (c == '*')
- {
- obstack_1grow (oout1, c);
- if (oout2)
- obstack_1grow (oout2, c);
- c = getc (fin);
- }
-
- if (c == '/')
- {
- obstack_1grow (oout1, c);
- if (oout2)
- obstack_1grow (oout2, c);
- ended = 1;
- }
- }
- else if (c == '\n')
- {
- lineno++;
- obstack_1grow (oout1, c);
- if (oout2)
- obstack_1grow (oout2, c);
- if (cplus_comment)
- ended = 1;
- else
- c = getc (fin);
- }
- else if (c == EOF)
- fatal (_("unterminated comment"));
- else
- {
- obstack_1grow (oout1, c);
- if (oout2)
- obstack_1grow (oout2, c);
- c = getc (fin);
- }
- }
-}
-
-
-/*-------------------------------------------------------------------.
-| Dump the comment (actually the current string starting with a `/') |
-| from FIN to OOUT. |
-`-------------------------------------------------------------------*/
-
-static inline void
-copy_comment (FILE *fin, struct obstack *oout)
-{
- copy_comment2 (fin, oout, NULL);
-}
-
-
-/*-----------------------------------------------------------------.
-| FIN is pointing to a location (i.e., a `@'). Output to OOUT a |
-| reference to this location. 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 inline void
-copy_at (FILE *fin, struct obstack *oout, int stack_offset)
-{
- int c;
-
- c = getc (fin);
- if (c == '$')
- {
- obstack_sgrow (oout, "yyloc");
- locations_flag = 1;
- }
- else if (isdigit (c) || c == '-')
- {
- int n;
-
- ungetc (c, fin);
- n = read_signed_integer (fin);
-
- obstack_fgrow1 (oout, "yylsp[%d]", n - stack_offset);
- locations_flag = 1;
- }
- 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. 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 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);