]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
* tests/regression.at (Web2c Actions): Blindly move the actual
[bison.git] / src / reader.c
index b09b3447d221ef1861287a94f8b8f4fe83c0a437..bebbc1539b494ff3ab31b817aa1a9b3d36c029c8 100644 (file)
@@ -68,9 +68,10 @@ static int typed;
 /* Incremented for each %left, %right or %nonassoc seen */
 static int lastprec;
 
-static bucket *errtoken;
-static bucket *undeftoken;
-
+static bucket *errtoken = NULL;
+static bucket *undeftoken = NULL;
+static bucket *eoftoken = NULL;
+static bucket *axiom = NULL;
 
 static symbol_list *
 symbol_list_new (bucket *sym)
@@ -441,7 +442,7 @@ copy_definition (void)
     {
       obstack_fgrow2 (&attrs_obstack, muscle_find ("linef"),
                      lineno, quotearg_style (c_quoting_style,
-                                             muscle_find("filename")));
+                                             muscle_find ("filename")));
     }
 
   after_percent = 0;
@@ -573,6 +574,9 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not)
       else if (symbol && token == tok_number)
        {
          symbol->user_token_number = numval;
+         /* User defined EOF token? */
+         if (numval == 0)
+           eoftoken = symbol;
        }
       else
        {
@@ -902,8 +906,8 @@ static void
 parse_muscle_decl (void)
 {
   int ch = ungetc (skip_white_space (), finput);
-  charmuscle_key;
-  charmuscle_value;
+  char *muscle_key;
+  char *muscle_value;
 
   /* Read key. */
   if (!isalpha (ch) && ch != '_')
@@ -1447,12 +1451,8 @@ readgram (void)
        t = lex ();
       }
 
-
   /* grammar has been read.  Do some checking */
 
-  if (nsyms > MAXSHORT)
-    fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
-          MAXSHORT);
   if (nrules == 0)
     fatal (_("no rules in the input grammar"));
 
@@ -1468,6 +1468,25 @@ readgram (void)
        bp->value = nvars++;
       }
 
+  /* Insert the initial rule, which line is that of the first rule
+     (not that of the start symbol):
+
+     axiom: %start EOF.  */
+  p = symbol_list_new (axiom);
+  p->line = grammar->line;
+  p->next = symbol_list_new (startval);
+  p->next->next = symbol_list_new (eoftoken);
+  p->next->next->next = symbol_list_new (NULL);
+  p->next->next->next->next = grammar;
+  nrules += 1;
+  nitems += 3;
+  grammar = p;
+  startval = axiom;
+
+  if (nsyms > MAXSHORT)
+    fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
+          MAXSHORT);
+
   ntokens = nsyms - nvars;
 }
 
@@ -1486,7 +1505,7 @@ read_additionnal_code (void)
     {
       obstack_fgrow2 (&el_obstack, muscle_find ("linef"),
                      lineno, quotearg_style (c_quoting_style,
-                                             muscle_find("filename")));
+                                             muscle_find ("filename")));
     }
 
   while ((c = getc (finput)) != EOF)
@@ -1549,7 +1568,6 @@ packsymbols (void)
   bucket *bp = NULL;
   int tokno = 1;
   int last_user_token_number;
-  static char DOLLAR[] = "$";
 
   tags = XCALLOC (char *, nsyms + 1);
   user_toknums = XCALLOC (short, nsyms + 1);
@@ -1557,10 +1575,6 @@ packsymbols (void)
   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;
 
@@ -1572,11 +1586,18 @@ packsymbols (void)
        }
       else if (bp->alias)
        {
-         /* this symbol and its alias are a single token defn.
-            allocate a tokno, and assign to both check agreement of
-            ->prec and ->assoc fields and make both the same */
-         if (bp->value == 0)
-           bp->value = bp->alias->value = tokno++;
+         /* This symbol and its alias are a single token defn.
+            Allocate a tokno, and assign to both check agreement of
+            prec and assoc fields and make both the same */
+         if (bp->value == -1)
+           {
+             if (bp == eoftoken || bp->alias == eoftoken)
+               bp->value = bp->alias->value = 0;
+             else
+               {
+                 bp->value = bp->alias->value = tokno++;
+               }
+           }
 
          if (bp->prec != bp->alias->prec)
            {
@@ -1602,13 +1623,17 @@ packsymbols (void)
                bp->assoc = bp->alias->assoc;
            }
 
+         /* Do not do processing below for SALIASs.  */
          if (bp->user_token_number == SALIAS)
-           continue;           /* do not do processing below for SALIASs */
+           continue;
 
        }
-      else                     /* bp->class == token_sym */
+      else /* bp->class == token_sym */
        {
-         bp->value = tokno++;
+         if (bp == eoftoken)
+           bp->value = 0;
+         else
+           bp->value = tokno++;
        }
 
       if (bp->class == token_sym)
@@ -1647,13 +1672,11 @@ symbols_save (void)
 {
   struct obstack tokendefs;
   bucket *bp;
-  char *cp, *symbol;
-  char c;
   obstack_init (&tokendefs);
 
   for (bp = firstsymbol; bp; bp = bp->next)
     {
-      symbol = bp->tag;                /* get symbol */
+      char *symbol = bp->tag;                /* get symbol */
 
       if (bp->value >= ntokens)
        continue;
@@ -1673,9 +1696,7 @@ symbols_save (void)
        }
 
       /* Don't #define nonliteral tokens whose names contain periods.  */
-      cp = symbol;
-      while ((c = *cp++) && c != '.');
-      if (c != '\0')
+      if (strchr (symbol, '.'))
        continue;
 
       obstack_fgrow2 (&tokendefs, "# define %s\t%d\n",
@@ -1759,6 +1780,8 @@ packgram (void)
     }
 
   ritem[itemno] = 0;
+  nritems = itemno;
+  assert (nritems == nitems);
 
   if (trace_flag)
     ritem_print (stderr);
@@ -1778,7 +1801,7 @@ reader (void)
   start_flag = 0;
   startval = NULL;             /* start symbol not specified yet. */
 
-  nsyms = 1;
+  nsyms = 0;
   nvars = 0;
   nrules = 0;
   nitems = 0;
@@ -1800,6 +1823,11 @@ reader (void)
   /* Initialize the symbol table.  */
   tabinit ();
 
+  /* Construct the axiom symbol. */
+  axiom = getsym ("$axiom");
+  axiom->class = nterm_sym;
+  axiom->value = nvars++;
+
   /* Construct the error token */
   errtoken = getsym ("error");
   errtoken->class = token_sym;
@@ -1822,6 +1850,16 @@ reader (void)
      TABLE_OBSTACK and FDEFINES file.  Also notice any %token, %left,
      etc. found there.  */
   read_declarations ();
+
+  /* If the user did not define her EOFTOKEN, do it now. */
+  if (!eoftoken)
+    {
+      eoftoken = getsym ("$");
+      eoftoken->class = token_sym;
+      /* Value specified by POSIX.  */
+      eoftoken->user_token_number = 0;
+    }
+
   /* Read in the grammar, build grammar in list form.  Write out
      guards and actions.  */
   readgram ();