* src/uniqstr.h (UNIQSTR_CMP): New.
* src/output.c (symbol_type_name_cmp, symbols_by_type_name)
(type_names_output): New.
(muscles_output): Use it.
* data/lalr1.cc (b4_symbol_action_): Remove.
(b4_symbol_case_, b4_type_action_): New.
Adjust uses of b4_symbol_action_ to use b4_type_action_.
+2008-11-10 Akim Demaille <demaille@gostai.com>
+
+ Classify symbols by type-name.
+ * src/uniqstr.h (UNIQSTR_CMP): New.
+ * src/output.c (symbol_type_name_cmp, symbols_by_type_name)
+ (type_names_output): New.
+ (muscles_output): Use it.
+ * data/lalr1.cc (b4_symbol_action_): Remove.
+ (b4_symbol_case_, b4_type_action_): New.
+ Adjust uses of b4_symbol_action_ to use b4_type_action_.
+
2008-11-10 Akim Demaille <demaille@gostai.com>
Change the handling of the symbols in the skeletons.
])
-# b4_symbol_action_(NUM)
-# ----------------------
-# Invoke b4_dollar_dollar(SYMBOL_TYPENAME) for each symbol.
-m4_define([b4_symbol_action_],
-[m4_ifval(b4_symbol([$1], [type_name]),
+# b4_symbol_case_(SYMBOL-NUM)
+# ---------------------------
+# Issue a "case NUM" for SYMBOL-NUM.
+m4_define([b4_symbol_case_],
[ case b4_symbol([$1], [number]): // b4_symbol([$1], [tag])
+])
+
+
+# b4_type_action_(NUMS)
+# ---------------------
+# Run actions for the symbol NUMS that all have the same type-name.
+m4_define([b4_type_action_],
+[m4_map([b4_symbol_case_], [$@])[]dnl
b4_dollar_dollar([b4_symbol([$1], [number])],
[b4_symbol([$1], [tag])],
[b4_symbol([$1], [type_name])]);
break;
-])])
+
+])
# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS])
[$2.$3<$][3>(m4_shift3($@))])dnl
switch ($1)
{
-m4_map([b4_symbol_action_], m4_defn([b4_symbol_numbers]))
+m4_map([b4_type_action_], m4_defn([b4_type_names]))[]dnl
default:
break;
}
}]b4_variant_if([
// Type destructor.
- b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[
+ b4_symbol_variant([[yytype]], [[yysym.value]], [[template destroy]])])[
}
#if YYDEBUG
}
+/*-------------------------------------------------------.
+| Compare two symbols by type-name, and then by number. |
+`-------------------------------------------------------*/
+
+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;
+ const char *isep = "";
+ symbol **syms = symbols_by_type_name ();
+ fputs ("m4_define([b4_type_names],\n[", out);
+ for (i = 0; i < nsyms; )
+ if (syms[i]->type_name)
+ {
+ int j;
+ const char *jsep = "";
+ fprintf (out, "%s[", isep);
+ isep = ",\n";
+ for (j = i; j < nsyms; ++j)
+ {
+ if (syms[i]->type_name != syms[j]->type_name)
+ break;
+ fprintf (out, "%s%d", jsep, syms[j]->number);
+ jsep = ", ";
+ }
+ fputs ("]", out);
+ i = j;
+ }
+ else
+ ++i;
+ fputs ("])\n\n", out);
+ free (syms);
+}
+
/*-------------------------------------.
| The list of all the symbol numbers. |
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
free (full_m4bison);
free (full_skeleton);
-
if (trace_flag & trace_muscles)
muscles_output (stderr);
{
/* Keeping a unique copy of strings.
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2008 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
/* Two uniqstr values have the same value iff they are the same. */
#define UNIQSTR_EQ(USTR1, USTR2) ((USTR1) == (USTR2))
+/* Compare two uniqstr a la strlen: negative for <, nul for =, and
+ positive for >. */
+#define UNIQSTR_CMP(USTR1, USTR2) ((USTR1) - (USTR2))
+
/*--------------------------------------.
| Initializing, destroying, debugging. |
`--------------------------------------*/