X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/d69c9694a7a7038b4c3eb20acbf8ba8354bcf7a1..c265fd6beb1a50426e06b64ed8c59c61597544b4:/src/output.c diff --git a/src/output.c b/src/output.c index 5391903d..73e63485 100644 --- a/src/output.c +++ b/src/output.c @@ -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); } @@ -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 ();