]> git.saurik.com Git - bison.git/blobdiff - src/reader.c
(_AT_TEST_GLR_CXXTYPES): Do not include <assert.h>.
[bison.git] / src / reader.c
index 3c1fe2f2341a28348052f87e0fd97c41fbf690b5..5ed02b2e4971d0f9ed4a81517856b55e4ef514a4 100644 (file)
@@ -1,4 +1,4 @@
-/* Input parser for bison
+/* Input parser for Bison
    Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
    Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
@@ -22,7 +22,6 @@
 
 #include "system.h"
 #include "quotearg.h"
 
 #include "system.h"
 #include "quotearg.h"
-#include "quote.h"
 #include "getargs.h"
 #include "files.h"
 #include "symtab.h"
 #include "getargs.h"
 #include "files.h"
 #include "symtab.h"
@@ -34,7 +33,6 @@
 #include "conflicts.h"
 #include "muscle_tab.h"
 
 #include "conflicts.h"
 #include "muscle_tab.h"
 
-int lineno;
 static symbol_list_t *grammar = NULL;
 static int start_flag = 0;
 merger_list *merge_functions;
 static symbol_list_t *grammar = NULL;
 static int start_flag = 0;
 merger_list *merge_functions;
@@ -71,13 +69,10 @@ prologue_augment (const char *prologue, location_t location)
   struct obstack *oout =
     !typed ? &pre_prologue_obstack : &post_prologue_obstack;
 
   struct obstack *oout =
     !typed ? &pre_prologue_obstack : &post_prologue_obstack;
 
-  if (!no_lines_flag)
-    {
-      obstack_fgrow2 (oout, muscle_find ("linef"),
-                     location.first_line,
-                     quotearg_style (c_quoting_style,
-                                     muscle_find ("filename")));
-    }
+  obstack_fgrow1 (oout, "]b4_syncline([[%d]], [[",
+                 location.first_line);
+  MUSCLE_OBSTACK_SGROW (oout, quotearg_style (c_quoting_style, location.file));
+  obstack_sgrow (oout, "]])[\n");
   obstack_sgrow (oout, prologue);
 }
 
   obstack_sgrow (oout, prologue);
 }
 
@@ -89,31 +84,32 @@ prologue_augment (const char *prologue, location_t location)
 `----------------------*/
 
 void
 `----------------------*/
 
 void
-epilogue_set (const char *epilogue, location_t location)
+epilogue_augment (const char *epilogue, location_t location)
 {
 {
-  if (!no_lines_flag)
-    {
-      obstack_fgrow2 (&muscle_obstack, muscle_find ("linef"),
-                     location.first_line,
-                     quotearg_style (c_quoting_style,
-                                     muscle_find ("filename")));
-    }
+  char *extension = NULL;
+  obstack_fgrow1 (&muscle_obstack, "]b4_syncline([[%d]], [[",
+                 location.first_line);
+  MUSCLE_OBSTACK_SGROW (&muscle_obstack,
+                       quotearg_style (c_quoting_style, location.file));
+  obstack_sgrow (&muscle_obstack, "]])[\n");
   obstack_sgrow (&muscle_obstack, epilogue);
   obstack_1grow (&muscle_obstack, 0);
   obstack_sgrow (&muscle_obstack, epilogue);
   obstack_1grow (&muscle_obstack, 0);
-  muscle_insert ("epilogue", obstack_finish (&muscle_obstack));
+  extension = obstack_finish (&muscle_obstack);
+  muscle_grow ("epilogue", extension, "");
+  obstack_free (&muscle_obstack, extension);
 }
 
 
 \f
 
 }
 
 
 \f
 
- /*-------------------------------------------------------------------.
+/*-------------------------------------------------------------------.
 | Return the merger index for a merging function named NAME, whose   |
 | arguments have type TYPE.  Records the function, if new, in        |
 | Return the merger index for a merging function named NAME, whose   |
 | arguments have type TYPE.  Records the function, if new, in        |
-| merger_list.                                                      |
+| MERGER_LIST.                                                      |
 `-------------------------------------------------------------------*/
 
 static int
 `-------------------------------------------------------------------*/
 
 static int
-get_merge_function (const char* name, const char* type)
+get_merge_function (struniq_t name, struniq_t type, location_t loc)
 {
   merger_list *syms;
   merger_list head;
 {
   merger_list *syms;
   merger_list head;
@@ -123,21 +119,23 @@ get_merge_function (const char* name, const char* type)
     return 0;
 
   if (type == NULL)
     return 0;
 
   if (type == NULL)
-    type = "";
+    type = struniq_new ("");
 
   head.next = merge_functions;
   for (syms = &head, n = 1; syms->next != NULL; syms = syms->next, n += 1)
 
   head.next = merge_functions;
   for (syms = &head, n = 1; syms->next != NULL; syms = syms->next, n += 1)
-    if (strcmp (name, syms->next->name) == 0)
+    if (STRUNIQ_EQ (name, syms->next->name))
       break;
       break;
-  if (syms->next == NULL) {
-    syms->next = XMALLOC (merger_list, 1);
-    syms->next->name = strdup (name);
-    syms->next->type = strdup (type);
-    syms->next->next = NULL;
-    merge_functions = head.next;
-  } else if (strcmp (type, syms->next->type) != 0)
-    warn (_("result type clash on merge function %s: `%s' vs. `%s'"),
-         name, type, syms->next->type);
+  if (syms->next == NULL)
+    {
+      syms->next = XMALLOC (merger_list, 1);
+      syms->next->name = struniq_new (name);
+      syms->next->type = struniq_new (type);
+      syms->next->next = NULL;
+      merge_functions = head.next;
+    }
+  else if (!STRUNIQ_EQ (type, syms->next->type))
+    warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"),
+            name, type, syms->next->type);
   return n;
 }
 
   return n;
 }
 
@@ -162,7 +160,7 @@ free_merger_functions (void)
 
 \f
 /*-------------------------------------------------------------------.
 
 \f
 /*-------------------------------------------------------------------.
-| Parse the input grammar into a one symbol_list_t structure.  Each    |
+| Parse the input grammar into a one symbol_list_t structure.  Each  |
 | rule is represented by a sequence of symbols: the left hand side   |
 | followed by the contents of the right hand side, followed by a     |
 | null pointer instead of a symbol to terminate the rule.  The next  |
 | rule is represented by a sequence of symbols: the left hand side   |
 | followed by the contents of the right hand side, followed by a     |
 | null pointer instead of a symbol to terminate the rule.  The next  |
@@ -244,31 +242,32 @@ static void
 grammar_current_rule_check (void)
 {
   symbol_t *lhs = current_rule->sym;
 grammar_current_rule_check (void)
 {
   symbol_t *lhs = current_rule->sym;
+  char const *lhs_type = lhs->type_name;
   symbol_t *first_rhs = current_rule->next->sym;
 
   /* If there is an action, then there is nothing we can do: the user
   symbol_t *first_rhs = current_rule->next->sym;
 
   /* If there is an action, then there is nothing we can do: the user
-     is allowed to shoot in her foot.  */
+     is allowed to shoot herself in the foot.  */
   if (current_rule->action)
     return;
 
   if (current_rule->action)
     return;
 
-  /* If $$ is being set in default way, report if any type mismatch.
-     */
+  /* Don't worry about the default action if $$ is untyped, since $$'s
+     value can't be used.  */
+  if (! lhs_type)
+    return;
+
+  /* If $$ is being set in default way, report if any type mismatch.  */
   if (first_rhs)
     {
   if (first_rhs)
     {
-      const char *lhs_type = lhs->type_name       ? lhs->type_name       : "";
       const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : "";
       const char *rhs_type = first_rhs->type_name ? first_rhs->type_name : "";
-      if (strcmp (lhs_type, rhs_type))
+      if (!STRUNIQ_EQ (lhs_type, rhs_type))
        complain_at (current_rule->location,
        complain_at (current_rule->location,
-                    _("type clash (`%s' `%s') on default action"),
+                    _("type clash on default action: <%s> != <%s>"),
                     lhs_type, rhs_type);
     }
   /* Warn if there is no default for $$ but we need one.  */
   else
                     lhs_type, rhs_type);
     }
   /* Warn if there is no default for $$ but we need one.  */
   else
-    {
-      if (lhs->type_name)
-       complain_at (current_rule->location,
-                    _("empty rule for typed nonterminal, and no action"));
-    }
+    complain_at (current_rule->location,
+                _("empty rule for typed nonterminal, and no action"));
 }
 
 
 }
 
 
@@ -338,7 +337,7 @@ void
 grammar_current_rule_prec_set (symbol_t *precsym, location_t location)
 {
   if (current_rule->ruleprec)
 grammar_current_rule_prec_set (symbol_t *precsym, location_t location)
 {
   if (current_rule->ruleprec)
-    complain_at (location, _("two @prec's in a row"));
+    complain_at (location, _("only one %s allowed per rule"), "%prec");
   current_rule->ruleprec = precsym;
 }
 
   current_rule->ruleprec = precsym;
 }
 
@@ -348,11 +347,12 @@ void
 grammar_current_rule_dprec_set (int dprec, location_t location)
 {
   if (! glr_parser)
 grammar_current_rule_dprec_set (int dprec, location_t location)
 {
   if (! glr_parser)
-    warn_at (location, _("%%dprec affects only GLR parsers"));
+    warn_at (location, _("%s affects only GLR parsers"), "%dprec");
   if (dprec <= 0)
   if (dprec <= 0)
-    complain_at (location, _("%%dprec must be followed by positive number"));
+    complain_at (location,
+                _("%s must be followed by positive number"), "%dprec");
   else if (current_rule->dprec != 0)
   else if (current_rule->dprec != 0)
-    complain_at (location, _("only one %%dprec allowed per rule"));
+    complain_at (location, _("only one %s allowed per rule"), "%dprec");
   current_rule->dprec = dprec;
 }
 
   current_rule->dprec = dprec;
 }
 
@@ -360,14 +360,14 @@ grammar_current_rule_dprec_set (int dprec, location_t location)
    rule. */
 
 void
    rule. */
 
 void
-grammar_current_rule_merge_set (const char* name, location_t location)
+grammar_current_rule_merge_set (struniq_t name, location_t location)
 {
   if (! glr_parser)
 {
   if (! glr_parser)
-    warn_at (location, _("%%merge affects only GLR parsers"));
+    warn_at (location, _("%s affects only GLR parsers"), "%merge");
   if (current_rule->merger != 0)
   if (current_rule->merger != 0)
-    complain_at (location, _("only one %%merge allowed per rule"));
+    complain_at (location, _("only one %s allowed per rule"), "%merge");
   current_rule->merger =
   current_rule->merger =
-    get_merge_function (name, current_rule->sym->type_name);
+    get_merge_function (name, current_rule->sym->type_name, location);
 }
 
 /* Attach a SYMBOL to the current rule.  If needed, move the previous
 }
 
 /* Attach a SYMBOL to the current rule.  If needed, move the previous
@@ -403,17 +403,13 @@ grammar_current_rule_action_append (const char *action, location_t location)
 static void
 packgram (void)
 {
 static void
 packgram (void)
 {
-  unsigned int itemno;
-  int ruleno;
-  symbol_list_t *p;
+  unsigned int itemno = 0;
+  rule_number_t ruleno = 0;
+  symbol_list_t *p = grammar;
 
   ritem = XCALLOC (item_number_t, nritems);
 
   ritem = XCALLOC (item_number_t, nritems);
-  rules = XCALLOC (rule_t, nrules) - 1;
+  rules = XCALLOC (rule_t, nrules);
 
 
-  itemno = 0;
-  ruleno = 1;
-
-  p = grammar;
   while (p)
     {
       symbol_t *ruleprec = p->ruleprec;
   while (p)
     {
       symbol_t *ruleprec = p->ruleprec;
@@ -422,7 +418,7 @@ packgram (void)
       rules[ruleno].lhs = p->sym;
       rules[ruleno].rhs = ritem + itemno;
       rules[ruleno].location = p->location;
       rules[ruleno].lhs = p->sym;
       rules[ruleno].rhs = ritem + itemno;
       rules[ruleno].location = p->location;
-      rules[ruleno].useful = TRUE;
+      rules[ruleno].useful = true;
       rules[ruleno].action = p->action;
       rules[ruleno].action_location = p->action_location;
       rules[ruleno].dprec = p->dprec;
       rules[ruleno].action = p->action;
       rules[ruleno].action_location = p->action_location;
       rules[ruleno].dprec = p->dprec;
@@ -449,16 +445,17 @@ packgram (void)
          rules[ruleno].precsym = ruleprec;
          rules[ruleno].prec = ruleprec;
        }
          rules[ruleno].precsym = ruleprec;
          rules[ruleno].prec = ruleprec;
        }
-      ritem[itemno++] = -ruleno;
+      ritem[itemno++] = rule_number_as_item_number (ruleno);
       ++ruleno;
 
       if (p)
        p = p->next;
     }
 
       ++ruleno;
 
       if (p)
        p = p->next;
     }
 
-  assert (itemno == nritems);
+  if (itemno != nritems)
+    abort ();
 
 
-  if (trace_flag)
+  if (trace_flag & trace_sets)
     ritem_print (stderr);
 }
 \f
     ritem_print (stderr);
 }
 \f
@@ -473,15 +470,14 @@ void
 reader (void)
 {
   gram_control_t gram_control;
 reader (void)
 {
   gram_control_t gram_control;
-  lineno = 1;
 
   /* Initialize the symbol table.  */
   symbols_new ();
 
 
   /* Initialize the symbol table.  */
   symbols_new ();
 
-  /* Construct the axiom symbol. */
-  axiom = symbol_get ("$axiom", empty_location);
-  axiom->class = nterm_sym;
-  axiom->number = nvars++;
+  /* Construct the accept symbol. */
+  accept = symbol_get ("$accept", empty_location);
+  accept->class = nterm_sym;
+  accept->number = nvars++;
 
   /* Construct the error token */
   errtoken = symbol_get ("error", empty_location);
 
   /* Construct the error token */
   errtoken = symbol_get ("error", empty_location);
@@ -490,7 +486,7 @@ reader (void)
 
   /* Construct a token that represents all undefined literal tokens.
      It is always token number 2.  */
 
   /* Construct a token that represents all undefined literal tokens.
      It is always token number 2.  */
-  undeftoken = symbol_get ("$undefined.", empty_location);
+  undeftoken = symbol_get ("$undefined", empty_location);
   undeftoken->class = token_sym;
   undeftoken->number = ntokens++;
 
   undeftoken->class = token_sym;
   undeftoken->number = ntokens++;
 
@@ -498,14 +494,19 @@ reader (void)
   obstack_init (&pre_prologue_obstack);
   obstack_init (&post_prologue_obstack);
 
   obstack_init (&pre_prologue_obstack);
   obstack_init (&post_prologue_obstack);
 
-  finput = xfopen (infile, "r");
+  finput = xfopen (grammar_file, "r");
   gram_in = finput;
 
   gram_in = finput;
 
-  gram_debug = !!getenv ("parse");
-  gram__flex_debug = !!getenv ("scan");
+  gram__flex_debug = trace_flag & trace_scan;
+  gram_debug = trace_flag & trace_parse;
   scanner_initialize ();
   gram_parse (&gram_control);
 
   scanner_initialize ();
   gram_parse (&gram_control);
 
+  /* If something went wrong during the parsing, don't try to
+     continue.  */
+  if (complaint_issued)
+    return;
+
   /* Grammar has been read.  Do some checking */
   if (nrules == 0)
     fatal (_("no rules in the input grammar"));
   /* Grammar has been read.  Do some checking */
   if (nrules == 0)
     fatal (_("no rules in the input grammar"));
@@ -513,25 +514,25 @@ reader (void)
   /* Report any undefined symbols and consider them nonterminals.  */
   symbols_check_defined ();
 
   /* Report any undefined symbols and consider them nonterminals.  */
   symbols_check_defined ();
 
-  /* If the user did not define her EOFTOKEN, do it now. */
-  if (!eoftoken)
+  /* If the user did not define her ENDTOKEN, do it now. */
+  if (!endtoken)
     {
     {
-      eoftoken = symbol_get ("$", empty_location);
-      eoftoken->class = token_sym;
-      eoftoken->number = 0;
+      endtoken = symbol_get ("$end", empty_location);
+      endtoken->class = token_sym;
+      endtoken->number = 0;
       /* Value specified by POSIX.  */
       /* Value specified by POSIX.  */
-      eoftoken->user_token_number = 0;
+      endtoken->user_token_number = 0;
     }
 
   /* Insert the initial rule, which line is that of the first rule
      (not that of the start symbol):
 
     }
 
   /* Insert the initial rule, which line is that of the first rule
      (not that of the start symbol):
 
-     axiom: %start EOF.  */
+     accept: %start EOF.  */
   {
   {
-    symbol_list_t *p = symbol_list_new (axiom, empty_location);
+    symbol_list_t *p = symbol_list_new (accept, empty_location);
     p->location = grammar->location;
     p->next = symbol_list_new (startsymbol, empty_location);
     p->location = grammar->location;
     p->next = symbol_list_new (startsymbol, empty_location);
-    p->next->next = symbol_list_new (eoftoken, empty_location);
+    p->next->next = symbol_list_new (endtoken, empty_location);
     p->next->next->next = symbol_list_new (NULL, empty_location);
     p->next->next->next->next = grammar;
     nrules += 1;
     p->next->next->next = symbol_list_new (NULL, empty_location);
     p->next->next->next->next = grammar;
     nrules += 1;
@@ -539,11 +540,8 @@ reader (void)
     grammar = p;
   }
 
     grammar = p;
   }
 
-  if (nsyms > SHRT_MAX)
-    fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
-          SHRT_MAX);
-
-  assert (nsyms == ntokens + nvars);
+  if (! (nsyms <= SYMBOL_NUMBER_MAX && nsyms == ntokens + nvars))
+    abort ();
 
   xfclose (finput);
 
 
   xfclose (finput);