]> git.saurik.com Git - bison.git/blobdiff - src/output.c
Work around Java's ``code too large'' problem for parser tables.
[bison.git] / src / output.c
index cac4ebfec9f800782e1222d607bcc05a01ca88f5..a7003edf99c59deac98191e7cd412a78514b6107 100644 (file)
@@ -143,6 +143,7 @@ prepare_symbols (void)
   MUSCLE_INSERT_BOOL ("token_table", token_table_flag);
   MUSCLE_INSERT_INT ("tokens_number", ntokens);
   MUSCLE_INSERT_INT ("nterms_number", nvars);
+  MUSCLE_INSERT_INT ("symbols_number", nsyms);
   MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
   MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
 
@@ -282,28 +283,71 @@ prepare_states (void)
 }
 
 
+/*-------------------------------------------------------.
+| Compare two symbols by type-name, and then by number.  |
+`-------------------------------------------------------*/
 
-/*-----------------------------------------------.
-| For each symbol type, its tags and type name.  |
-`-----------------------------------------------*/
+int
+symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
+{
+  int res = UNIQSTR_CMP((*lhs)->type_name, (*rhs)->type_name);
+  if (res)
+    return res;
+  return (*lhs)->number - (*rhs)->number;
+}
+
+
+/*----------------------------------------------------------------.
+| Return a (malloc'ed) table of the symbols sorted by type-name.  |
+`----------------------------------------------------------------*/
+
+static symbol **
+symbols_by_type_name ()
+{
+  typedef int (*qcmp_type) (const void *, const void *);
+  symbol **res = xmemdup (symbols, nsyms * sizeof *res);
+  qsort (res, nsyms, sizeof *res, (qcmp_type) &symbol_type_name_cmp);
+  return res;
+}
+
+
+/*------------------------------------------------------------------.
+| Define b4_type_names, which is a list of (lists of the numbers of |
+| symbols with same type-name).                                     |
+`------------------------------------------------------------------*/
 
 static void
 type_names_output (FILE *out)
 {
   int i;
-
+  symbol **syms = symbols_by_type_name ();
   fputs ("m4_define([b4_type_names],\n[", out);
-  for (i = 0; i < nsyms; ++i)
+  for (i = 0; i < nsyms; /* nothing */)
     {
-      symbol *sym = symbols[i];
-      /* Symbol-name, Symbol-number, optional typename.  */
-      fprintf (out, "%s[", i ? ",\n" : "");
-      escaped_output (out, sym->tag);
-      fprintf (out, ", %d, [[%s]]]",
-               sym->number,
-               sym->type_name ? sym->type_name : "");
+      // The index of the first symbol of the current type-name.
+      int i0 = i;
+      fputs (i ? ",\n[" : "[", out);
+      for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
+        fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
+      fputs ("]", out);
     }
   fputs ("])\n\n", out);
+  free (syms);
+}
+
+
+/*-------------------------------------.
+| The list of all the symbol numbers.  |
+`-------------------------------------*/
+
+static void
+symbol_numbers_output (FILE *out)
+{
+  int i;
+  fputs ("m4_define([b4_symbol_numbers],\n[", out);
+  for (i = 0; i < nsyms; ++i)
+    fprintf (out, "%s[%d]", i ? ", " : "", i);
+  fputs ("])\n\n", out);
 }
 
 
@@ -351,6 +395,49 @@ merger_output (FILE *out)
   fputs ("]])\n\n", out);
 }
 
+
+/*---------------------------------------.
+| Output the symbol definitions to OUT.  |
+`---------------------------------------*/
+
+static void
+symbol_definitions_output (FILE *out)
+{
+  int i;
+  for (i = 0; i < nsyms; ++i)
+    {
+      symbol *sym = symbols[i];
+      const char *key;
+
+#define SET_KEY(Entry)                                                  \
+      obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", i, Entry);     \
+      obstack_1grow (&format_obstack, 0);                               \
+      key = obstack_finish (&format_obstack);
+
+      SET_KEY("tag");
+      MUSCLE_INSERT_STRING (key, sym->tag);
+
+      SET_KEY("user_number");
+      MUSCLE_INSERT_INT (key, sym->user_token_number);
+
+      SET_KEY("is_token");
+      MUSCLE_INSERT_INT (key,
+                         i < ntokens && sym != errtoken && sym != undeftoken);
+
+      SET_KEY("number");
+      MUSCLE_INSERT_INT (key, sym->number);
+
+      SET_KEY("has_type_name");
+      MUSCLE_INSERT_INT (key, !!sym->type_name);
+
+      SET_KEY("type_name");
+      MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
+
+#undef SET_KEY
+    }
+}
+
+
 /*--------------------------------------.
 | Output the tokens definition to OUT.  |
 `--------------------------------------*/
@@ -495,14 +582,15 @@ static void
 muscles_output (FILE *out)
 {
   fputs ("m4_init()\n", out);
-
-  type_names_output (out);
-  user_actions_output (out);
   merger_output (out);
-  token_definitions_output (out);
   symbol_code_props_output (out, "destructors", &symbol_destructor_get);
   symbol_code_props_output (out, "printers", &symbol_printer_get);
-
+  symbol_definitions_output (out);
+  symbol_numbers_output (out);
+  token_definitions_output (out);
+  type_names_output (out);
+  user_actions_output (out);
+  // Must be last.
   muscles_m4_output (out);
 }
 \f
@@ -601,7 +689,6 @@ output_skeleton (void)
   free (full_m4bison);
   free (full_skeleton);
 
-
   if (trace_flag & trace_muscles)
     muscles_output (stderr);
   {