]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
* src/bison.simple: Remove YYERROR_VERBOSE using.
[bison.git] / src / reader.c
index 9bf54dfbbb167dc6b01fde46b6a502184a7147b9..ac160aed449b93d59814299a2e1eee7a009374f2 100644 (file)
@@ -1,5 +1,5 @@
 /* Input parser for bison
 /* Input parser for bison
-   Copyright 1984, 1986, 1989, 1992, 1998, 2000
+   Copyright 1984, 1986, 1989, 1992, 1998, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 #include "conflicts.h"
 #include "muscle_tab.h"
 
 #include "conflicts.h"
 #include "muscle_tab.h"
 
-/* Number of slots allocated (but not necessarily used yet) in `rline'  */
-static int rline_allocated;
-
 typedef struct symbol_list
 {
   struct symbol_list *next;
   bucket *sym;
 typedef struct symbol_list
 {
   struct symbol_list *next;
   bucket *sym;
+  int line;
   bucket *ruleprec;
 }
 symbol_list;
   bucket *ruleprec;
 }
 symbol_list;
@@ -66,6 +64,19 @@ static int lastprec;
 
 static bucket *errtoken;
 static bucket *undeftoken;
 
 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
 
 /*===================\
 \f
 
 /*===================\
@@ -123,7 +134,7 @@ read_signed_integer (FILE *stream)
 `--------------------------------------------------------------*/
 
 static char *
 `--------------------------------------------------------------*/
 
 static char *
-get_type_name (int n, symbol_list * rule)
+get_type_name (int n, symbol_list *rule)
 {
   int i;
   symbol_list *rp;
 {
   int i;
   symbol_list *rp;
@@ -568,7 +579,8 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
       else
        {
          complain (_("`%s' is invalid in %s"),
       else
        {
          complain (_("`%s' is invalid in %s"),
-                   token_buffer, (what_is == token_sym) ? "%token" : "%nterm");
+                   token_buffer,
+                   (what_is == token_sym) ? "%token" : "%nterm");
          skip_to_char ('%');
        }
     }
          skip_to_char ('%');
        }
     }
@@ -724,7 +736,6 @@ token_buffer);
        }
 
       prev = t;
        }
 
       prev = t;
-
     }
 }
 
     }
 }
 
@@ -742,6 +753,13 @@ parse_union_decl (void)
   int c;
   int count = 0;
   struct obstack union_obstack;
   int c;
   int count = 0;
   struct obstack union_obstack;
+  const char *prologue = "\
+#ifndef YYSTYPE\n\
+typedef union";
+  const char *epilogue = "\
+ yystype;\n\
+# define YYSTYPE yystype\n\
+#endif\n";
 
   if (typed)
     complain (_("multiple %s declarations"), "%union");
 
   if (typed)
     complain (_("multiple %s declarations"), "%union");
@@ -750,13 +768,15 @@ parse_union_decl (void)
 
   /* FIXME: I'm worried: are you sure attrs_obstack is properly
      filled?  */
 
   /* FIXME: I'm worried: are you sure attrs_obstack is properly
      filled?  */
+  /* I don't see any reasons to keep this line, because we should
+     create a special skeleton for this option.  */
   if (no_lines_flag)
     obstack_1grow (&attrs_obstack, '\n');
 
   obstack_init (&union_obstack);
   obstack_sgrow (&union_obstack, "union");
   if (defines_flag)
   if (no_lines_flag)
     obstack_1grow (&attrs_obstack, '\n');
 
   obstack_init (&union_obstack);
   obstack_sgrow (&union_obstack, "union");
   if (defines_flag)
-    obstack_sgrow (&defines_obstack, "typedef union");
+    obstack_sgrow (&defines_obstack, prologue);
 
   c = getc (finput);
 
 
   c = getc (finput);
 
@@ -791,7 +811,7 @@ parse_union_decl (void)
          if (count <= 0)
            {
              if (defines_flag)
          if (count <= 0)
            {
              if (defines_flag)
-               obstack_sgrow (&defines_obstack, " YYSTYPE;\n");
+               obstack_sgrow (&defines_obstack, epilogue);
              /* JF don't choke on trailing semi */
              c = skip_white_space ();
              if (c != ';')
              /* JF don't choke on trailing semi */
              c = skip_white_space ();
              if (c != ';')
@@ -852,7 +872,7 @@ parse_thong_decl (void)
   token_t token;
   struct bucket *symbol;
   char *typename = 0;
   token_t token;
   struct bucket *symbol;
   char *typename = 0;
-  int usrtoknum;
+  int usrtoknum = SUNDEF;
 
   token = lex ();              /* fetch typename or first token */
   if (token == tok_typename)
 
   token = lex ();              /* fetch typename or first token */
   if (token == tok_typename)
@@ -883,8 +903,6 @@ parse_thong_decl (void)
       usrtoknum = numval;
       token = lex ();          /* okay, did number, now get literal */
     }
       usrtoknum = numval;
       token = lex ();          /* okay, did number, now get literal */
     }
-  else
-    usrtoknum = 0;
 
   /* process literal string token */
 
 
   /* process literal string token */
 
@@ -956,6 +974,16 @@ parse_skel_decl (void)
   /* Complete with parse_dquoted_param () on the CVS branch 1.29.  */
 }
 
   /* Complete with parse_dquoted_param () on the CVS branch 1.29.  */
 }
 
+/*---------------------------------------.
+| Parse what comes after %skeleton_path. |
+`---------------------------------------*/
+
+void
+parse_include_decl (void)
+{
+  /* Complete with parse_dquoted_param () on the CVS branch 1.29.  */
+}
+
 /*----------------------------------------------------------------.
 | Read from finput until `%%' is seen.  Discard the `%%'.  Handle |
 | any `%' declarations, and copy the contents of any `%{ ... %}'  |
 /*----------------------------------------------------------------.
 | Read from finput until `%%' is seen.  Discard the `%%'.  Handle |
 | any `%' declarations, and copy the contents of any `%{ ... %}'  |
@@ -965,16 +993,13 @@ parse_skel_decl (void)
 static void
 read_declarations (void)
 {
 static void
 read_declarations (void)
 {
-  int c;
-  int tok;
-
   for (;;)
     {
   for (;;)
     {
-      c = skip_white_space ();
+      int c = skip_white_space ();
 
       if (c == '%')
        {
 
       if (c == '%')
        {
-         tok = parse_percent_token ();
+         token_t tok = parse_percent_token ();
 
          switch (tok)
            {
 
          switch (tok)
            {
@@ -1033,9 +1058,20 @@ read_declarations (void)
              parse_skel_decl ();
              break;
 
              parse_skel_decl ();
              break;
 
+           case tok_include:
+             parse_include_decl ();
+             break;
+             
            case tok_noop:
              break;
 
            case tok_noop:
              break;
 
+           case tok_stropt:
+           case tok_intopt:
+           case tok_obsolete:
+             abort ();
+             break;
+
+           case tok_illegal:
            default:
              complain (_("unrecognized: %s"), token_buffer);
              skip_to_char ('%');
            default:
              complain (_("unrecognized: %s"), token_buffer);
              skip_to_char ('%');
@@ -1241,20 +1277,6 @@ copy_guard (symbol_list *rule, int stack_offset)
 }
 \f
 
 }
 \f
 
-static void
-record_rule_line (void)
-{
-  /* Record each rule's source line number in rline table.  */
-
-  if (nrules >= rline_allocated)
-    {
-      rline_allocated = nrules * 2;
-      rline = XREALLOC (rline, short, rline_allocated);
-    }
-  rline[nrules] = lineno;
-}
-
-
 /*-------------------------------------------------------------------.
 | Generate a dummy symbol, a nonterminal, whose name cannot conflict |
 | with the user's names.                                             |
 /*-------------------------------------------------------------------.
 | Generate a dummy symbol, a nonterminal, whose name cannot conflict |
 | with the user's names.                                             |
@@ -1397,10 +1419,7 @@ readgram (void)
          nrules++;
          nitems++;
 
          nrules++;
          nitems++;
 
-         record_rule_line ();
-
-         p = XCALLOC (symbol_list, 1);
-         p->sym = lhs;
+         p = symbol_list_new (lhs);
 
          crule1 = p1;
          if (p1)
 
          crule1 = p1;
          if (p1)
@@ -1462,36 +1481,35 @@ readgram (void)
                 non-terminal.  */
              if (action_flag)
                {
                 non-terminal.  */
              if (action_flag)
                {
-                 bucket *sdummy;
-
                  /* Since the action was written out with this rule's
                     number, we must give the new rule this number by
                     inserting the new rule before it.  */
 
                  /* Make a dummy nonterminal, a gensym.  */
                  /* Since the action was written out with this rule's
                     number, we must give the new rule this number by
                     inserting the new rule before it.  */
 
                  /* Make a dummy nonterminal, a gensym.  */
-                 sdummy = gensym ();
+                 bucket *sdummy = gensym ();
 
 
-                 /* Make a new rule, whose body is empty,
-                    before the current one, so that the action
-                    just read can belong to it.  */
+                 /* Make a new rule, whose body is empty, before the
+                    current one, so that the action just read can
+                    belong to it.  */
                  nrules++;
                  nitems++;
                  nrules++;
                  nitems++;
-                 record_rule_line ();
-                 p = XCALLOC (symbol_list, 1);
+                 p = symbol_list_new (sdummy);
+                 /* Attach its lineno to that of the host rule. */
+                 p->line = crule->line;
                  if (crule1)
                    crule1->next = p;
                  else
                    grammar = p;
                  if (crule1)
                    crule1->next = p;
                  else
                    grammar = p;
-                 p->sym = sdummy;
-                 crule1 = XCALLOC (symbol_list, 1);
-                 p->next = crule1;
+                 /* End of the rule. */
+                 crule1 = symbol_list_new (NULL);
                  crule1->next = crule;
 
                  crule1->next = crule;
 
+                 p->next = crule1;
+
                  /* Insert the dummy generated by that rule into this
                     rule.  */
                  nitems++;
                  /* Insert the dummy generated by that rule into this
                     rule.  */
                  nitems++;
-                 p = XCALLOC (symbol_list, 1);
-                 p->sym = sdummy;
+                 p = symbol_list_new (sdummy);
                  p1->next = p;
                  p1 = p;
 
                  p1->next = p;
                  p1 = p;
 
@@ -1501,8 +1519,7 @@ readgram (void)
              if (t == tok_identifier)
                {
                  nitems++;
              if (t == tok_identifier)
                {
                  nitems++;
-                 p = XCALLOC (symbol_list, 1);
-                 p->sym = symval;
+                 p = symbol_list_new (symval);
                  p1->next = p;
                  p1 = p;
                }
                  p1->next = p;
                  p1 = p;
                }
@@ -1516,7 +1533,7 @@ readgram (void)
            }                   /* end of  read rhs of rule */
 
          /* Put an empty link in the list to mark the end of this rule  */
            }                   /* end of  read rhs of rule */
 
          /* Put an empty link in the list to mark the end of this rule  */
-         p = XCALLOC (symbol_list, 1);
+         p = symbol_list_new (NULL);
          p1->next = p;
          p1 = p;
 
          p1->next = p;
          p1 = p;
 
@@ -1699,6 +1716,46 @@ output_token_defines (struct obstack *oout)
 }
 
 
 }
 
 
+/*------------------------------------------------------------------.
+| Set TOKEN_TRANSLATIONS.  Check that no two symbols share the same |
+| number.                                                           |
+`------------------------------------------------------------------*/
+
+static void
+token_translations_init (void)
+{
+  bucket *bp = NULL;
+  int i;
+
+  token_translations = XCALLOC (short, max_user_token_number + 1);
+
+  /* Initialize all entries for literal tokens to 2, the internal
+     token number for $undefined., which represents all invalid
+     inputs.  */
+  for (i = 0; i <= max_user_token_number; i++)
+    token_translations[i] = 2;
+
+  for (bp = firstsymbol; bp; bp = bp->next)
+    {
+      /* Non-terminal? */
+      if (bp->value >= ntokens)
+       continue;
+      /* A token string alias? */
+      if (bp->user_token_number == SALIAS)
+       continue;
+
+      assert (bp->user_token_number != SUNDEF);
+
+      /* A token which translation has already been set? */
+      if (token_translations[bp->user_token_number] != 2)
+       complain (_("tokens %s and %s both assigned number %d"),
+                 tags[token_translations[bp->user_token_number]],
+                 bp->tag, bp->user_token_number);
+      token_translations[bp->user_token_number] = bp->value;
+    }
+}
+
+
 /*------------------------------------------------------------------.
 | Assign symbol numbers, and write definition of token names into   |
 | FDEFINES.  Set up vectors TAGS and SPREC of names and precedences |
 /*------------------------------------------------------------------.
 | Assign symbol numbers, and write definition of token names into   |
 | FDEFINES.  Set up vectors TAGS and SPREC of names and precedences |
@@ -1710,18 +1767,19 @@ packsymbols (void)
 {
   bucket *bp = NULL;
   int tokno = 1;
 {
   bucket *bp = NULL;
   int tokno = 1;
-  int i, j;
   int last_user_token_number;
   static char DOLLAR[] = "$";
 
   tags = XCALLOC (char *, nsyms + 1);
   int last_user_token_number;
   static char DOLLAR[] = "$";
 
   tags = XCALLOC (char *, nsyms + 1);
-  tags[0] = DOLLAR;
   user_toknums = XCALLOC (short, nsyms + 1);
   user_toknums = XCALLOC (short, nsyms + 1);
-  user_toknums[0] = 0;
 
   sprec = XCALLOC (short, nsyms);
   sassoc = XCALLOC (short, nsyms);
 
 
   sprec = XCALLOC (short, nsyms);
   sassoc = XCALLOC (short, nsyms);
 
+  /* The EOF token. */
+  tags[0] = DOLLAR;
+  user_toknums[0] = 0;
+
   max_user_token_number = 256;
   last_user_token_number = 256;
 
   max_user_token_number = 256;
   last_user_token_number = 256;
 
@@ -1774,7 +1832,7 @@ packsymbols (void)
 
       if (bp->class == token_sym)
        {
 
       if (bp->class == token_sym)
        {
-         if (!bp->user_token_number)
+         if (bp->user_token_number == SUNDEF)
            bp->user_token_number = ++last_user_token_number;
          if (bp->user_token_number > max_user_token_number)
            max_user_token_number = bp->user_token_number;
            bp->user_token_number = ++last_user_token_number;
          if (bp->user_token_number > max_user_token_number)
            max_user_token_number = bp->user_token_number;
@@ -1786,29 +1844,26 @@ packsymbols (void)
       sassoc[bp->value] = bp->assoc;
     }
 
       sassoc[bp->value] = bp->assoc;
     }
 
-  token_translations = XCALLOC (short, max_user_token_number + 1);
+  token_translations_init ();
 
 
-  /* initialize all entries for literal tokens to 2, the internal
-     token number for $undefined., which represents all invalid
-     inputs.  */
-  for (j = 0; j <= max_user_token_number; j++)
-    token_translations[j] = 2;
+  error_token_number = errtoken->value;
 
 
-  for (bp = firstsymbol; bp; bp = bp->next)
-    {
-      if (bp->value >= ntokens)
-       continue;               /* non-terminal */
-      if (bp->user_token_number == SALIAS)
-       continue;
-      if (token_translations[bp->user_token_number] != 2)
-       complain (_("tokens %s and %s both assigned number %d"),
-                 tags[token_translations[bp->user_token_number]],
-                 bp->tag, bp->user_token_number);
-      token_translations[bp->user_token_number] = bp->value;
-    }
+  if (startval->class == unknown_sym)
+    fatal (_("the start symbol %s is undefined"), startval->tag);
+  else if (startval->class == token_sym)
+    fatal (_("the start symbol %s is a token"), startval->tag);
 
 
-  error_token_number = errtoken->value;
+  start_symbol = startval->value;
+}
+
+
+/*-----------------------------------.
+| Output definition of token names.  |
+`-----------------------------------*/
 
 
+static void
+symbols_output (void)
+{
   {
     struct obstack tokendefs;
     obstack_init (&tokendefs);
   {
     struct obstack tokendefs;
     obstack_init (&tokendefs);
@@ -1823,13 +1878,6 @@ packsymbols (void)
     output_token_defines (&table_obstack);
 #endif
 
     output_token_defines (&table_obstack);
 #endif
 
-  if (startval->class == unknown_sym)
-    fatal (_("the start symbol %s is undefined"), startval->tag);
-  else if (startval->class == token_sym)
-    fatal (_("the start symbol %s is a token"), startval->tag);
-
-  start_symbol = startval->value;
-
   if (defines_flag)
     {
       output_token_defines (&defines_obstack);
   if (defines_flag)
     {
       output_token_defines (&defines_obstack);
@@ -1845,19 +1893,23 @@ packsymbols (void)
        }
 
       if (semantic_parser)
        }
 
       if (semantic_parser)
-       for (i = ntokens; i < nsyms; i++)
-         {
-           /* don't make these for dummy nonterminals made by gensym.  */
-           if (*tags[i] != '@')
-              obstack_fgrow2 (&defines_obstack,
-                              "# define\tNT%s\t%d\n", tags[i], i);
-         }
+       {
+         int i;
+
+         for (i = ntokens; i < nsyms; i++)
+           {
+             /* don't make these for dummy nonterminals made by gensym.  */
+             if (*tags[i] != '@')
+               obstack_fgrow2 (&defines_obstack,
+                               "# define\tNT%s\t%d\n", tags[i], i);
+           }
 #if 0
 #if 0
-      /* `fdefines' is now a temporary file, so we need to copy its
-         contents in `done', so we can't close it here.  */
-      fclose (fdefines);
-      fdefines = NULL;
+         /* `fdefines' is now a temporary file, so we need to copy its
+            contents in `done', so we can't close it here.  */
+         fclose (fdefines);
+         fdefines = NULL;
 #endif
 #endif
+       }
     }
 }
 
     }
 }
 
@@ -1874,14 +1926,8 @@ packgram (void)
   int ruleno;
   symbol_list *p;
 
   int ruleno;
   symbol_list *p;
 
-  bucket *ruleprec;
-
   ritem = XCALLOC (short, nitems + 1);
   ritem = XCALLOC (short, nitems + 1);
-  rlhs = XCALLOC (short, nrules) - 1;
-  rrhs = XCALLOC (short, nrules) - 1;
-  rprec = XCALLOC (short, nrules) - 1;
-  rprecsym = XCALLOC (short, nrules) - 1;
-  rassoc = XCALLOC (short, nrules) - 1;
+  rule_table = XCALLOC (rule_t, nrules) - 1;
 
   itemno = 0;
   ruleno = 1;
 
   itemno = 0;
   ruleno = 1;
@@ -1889,9 +1935,10 @@ packgram (void)
   p = grammar;
   while (p)
     {
   p = grammar;
   while (p)
     {
-      rlhs[ruleno] = p->sym->value;
-      rrhs[ruleno] = itemno;
-      ruleprec = p->ruleprec;
+      bucket *ruleprec = p->ruleprec;
+      rule_table[ruleno].lhs = p->sym->value;
+      rule_table[ruleno].rhs = itemno;
+      rule_table[ruleno].line = p->line;
 
       p = p->next;
       while (p && p->sym)
 
       p = p->next;
       while (p && p->sym)
@@ -1901,8 +1948,8 @@ packgram (void)
             of the last token in it.  */
          if (p->sym->class == token_sym)
            {
             of the last token in it.  */
          if (p->sym->class == token_sym)
            {
-             rprec[ruleno] = p->sym->prec;
-             rassoc[ruleno] = p->sym->assoc;
+             rule_table[ruleno].prec = p->sym->prec;
+             rule_table[ruleno].assoc = p->sym->assoc;
            }
          if (p)
            p = p->next;
            }
          if (p)
            p = p->next;
@@ -1912,9 +1959,9 @@ packgram (void)
          the specified symbol's precedence replaces the default.  */
       if (ruleprec)
        {
          the specified symbol's precedence replaces the default.  */
       if (ruleprec)
        {
-         rprec[ruleno] = ruleprec->prec;
-         rassoc[ruleno] = ruleprec->assoc;
-         rprecsym[ruleno] = ruleprec->value;
+         rule_table[ruleno].prec = ruleprec->prec;
+         rule_table[ruleno].assoc = ruleprec->assoc;
+         rule_table[ruleno].precsym = ruleprec->value;
        }
 
       ritem[itemno++] = -ruleno;
        }
 
       ritem[itemno++] = -ruleno;
@@ -1945,8 +1992,6 @@ reader (void)
   nvars = 0;
   nrules = 0;
   nitems = 0;
   nvars = 0;
   nrules = 0;
   nitems = 0;
-  rline_allocated = 10;
-  rline = XCALLOC (short, rline_allocated);
 
   typed = 0;
   lastprec = 0;
 
   typed = 0;
   lastprec = 0;
@@ -1993,6 +2038,9 @@ reader (void)
   /* Assign the symbols their symbol numbers.  Write #defines for the
      token symbols into FDEFINES if requested.  */
   packsymbols ();
   /* Assign the symbols their symbol numbers.  Write #defines for the
      token symbols into FDEFINES if requested.  */
   packsymbols ();
+  symbols_output ();
   /* Convert the grammar into the format described in gram.h.  */
   packgram ();
   /* Convert the grammar into the format described in gram.h.  */
   packgram ();
+  /* Output the headers. */
+  symbols_output ();
 }
 }