]> git.saurik.com Git - bison.git/blobdiff - src/output.c
Improves options in the manual.
[bison.git] / src / output.c
index 5391903dd62963d3c307406ae0bf8e3c3d02ef91..73e634855e6c2a4a184e2e2b2d9e38a4a6d4a493 100644 (file)
@@ -283,6 +283,58 @@ prepare_states (void)
 }
 
 
+/*-------------------------------------------------------.
+| Compare two symbols by type-name, and then by number.  |
+`-------------------------------------------------------*/
+
+static 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 (void)
+{
+  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; /* nothing */)
+    {
+      // 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.  |
@@ -344,34 +396,52 @@ merger_output (FILE *out)
 }
 
 
-/*---------------------------------------.
-| Output the symbol definitions to OUT.  |
-`---------------------------------------*/
+/*---------------------------------------------.
+| Prepare the muscles for symbol definitions.  |
+`---------------------------------------------*/
 
 static void
-symbol_definitions_output (FILE *out)
+prepare_symbol_definitions (void)
 {
   int i;
   for (i = 0; i < nsyms; ++i)
     {
       symbol *sym = symbols[i];
       const char *key;
+      const char *value;
 
 #define SET_KEY(Entry)                                                  \
       obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", i, Entry);     \
       obstack_1grow (&format_obstack, 0);                               \
       key = obstack_finish (&format_obstack);
 
+      // Whether the symbol has an identifier.
+      value = symbol_id_get (sym);
+      SET_KEY("has_id");
+      MUSCLE_INSERT_INT (key, !!value);
+
+      // Its identifier.
+      SET_KEY("id");
+      MUSCLE_INSERT_STRING (key, value ? value : "");
+
+      // Its tag.  Typically for documentation purpose.
       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("type_name");
+      SET_KEY("has_type");
+      MUSCLE_INSERT_INT (key, !!sym->type_name);
+
+      SET_KEY("type");
       MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
 
 #undef SET_KEY
@@ -523,15 +593,14 @@ static void
 muscles_output (FILE *out)
 {
   fputs ("m4_init()\n", out);
-
   merger_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
@@ -630,7 +699,6 @@ output_skeleton (void)
   free (full_m4bison);
   free (full_skeleton);
 
-
   if (trace_flag & trace_muscles)
     muscles_output (stderr);
   {
@@ -725,6 +793,7 @@ output (void)
   prepare_rules ();
   prepare_states ();
   prepare_actions ();
+  prepare_symbol_definitions ();
 
   prepare ();