/* Output the generated parsing program for Bison.
Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_base_table, base_number)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_rule_number_table, rule_number)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_symbol_number_table, symbol_number)
-GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_item_number_table, item_number)
GENERATE_MUSCLE_INSERT_TABLE(muscle_insert_state_number_table, state_number)
}
-/*-------------------------------------------------------------.
-| Prepare the muscles related to the rules: rhs, prhs, r1, r2, |
-| rline, dprec, merger. |
-`-------------------------------------------------------------*/
+/*----------------------------------------------------------------.
+| Prepare the muscles related to the rules: r1, r2, rline, dprec, |
+| merger. |
+`----------------------------------------------------------------*/
static void
prepare_rules (void)
{
- rule_number r;
- unsigned int i = 0;
- item_number *rhs = xnmalloc (nritems, sizeof *rhs);
- unsigned int *prhs = xnmalloc (nrules, sizeof *prhs);
unsigned int *rline = xnmalloc (nrules, sizeof *rline);
symbol_number *r1 = xnmalloc (nrules, sizeof *r1);
unsigned int *r2 = xnmalloc (nrules, sizeof *r2);
int *dprec = xnmalloc (nrules, sizeof *dprec);
int *merger = xnmalloc (nrules, sizeof *merger);
+ rule_number r;
for (r = 0; r < nrules; ++r)
{
- item_number *rhsp = NULL;
- /* Index of rule R in RHS. */
- prhs[r] = i;
- /* RHS of the rule R. */
- for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
- rhs[i++] = *rhsp;
/* LHS of the rule R. */
r1[r] = rules[r].lhs->number;
/* Length of rule R's RHS. */
- r2[r] = i - prhs[r];
- /* Separator in RHS. */
- rhs[i++] = -1;
+ r2[r] = rule_rhs_length(&rules[r]);
/* Line where rule was defined. */
rline[r] = rules[r].location.start.line;
/* Dynamic precedence (GLR). */
/* Merger-function index (GLR). */
merger[r] = rules[r].merger;
}
- aver (i == nritems);
- muscle_insert_item_number_table ("rhs", rhs, ritem[0], 1, nritems);
- muscle_insert_unsigned_int_table ("prhs", prhs, 0, 0, nrules);
muscle_insert_unsigned_int_table ("rline", rline, 0, 0, nrules);
muscle_insert_symbol_number_table ("r1", r1, 0, 0, nrules);
muscle_insert_unsigned_int_table ("r2", r2, 0, 0, nrules);
MUSCLE_INSERT_INT ("rules_number", nrules);
MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
- free (rhs);
- free (prhs);
free (rline);
free (r1);
free (r2);
| Compare two symbols by type-name, and then by number. |
`-------------------------------------------------------*/
-int
+static int
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
{
int res = UNIQSTR_CMP((*lhs)->type_name, (*rhs)->type_name);
`----------------------------------------------------------------*/
static symbol **
-symbols_by_type_name ()
+symbols_by_type_name (void)
{
typedef int (*qcmp_type) (const void *, const void *);
symbol **res = xmemdup (symbols, nsyms * sizeof *res);
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;
+ 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);
}
}
-/*---------------------------------------.
-| 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 : "");
+#define CODE_PROP(PropName) \
+ do { \
+ code_props const *p = symbol_ ## PropName ## _get (sym); \
+ SET_KEY("has_" #PropName); \
+ MUSCLE_INSERT_INT (key, !!p->code); \
+ \
+ if (p->code) \
+ { \
+ SET_KEY(#PropName "_file"); \
+ MUSCLE_INSERT_STRING (key, p->location.start.file); \
+ \
+ SET_KEY(#PropName "_line"); \
+ MUSCLE_INSERT_INT (key, p->location.start.line); \
+ \
+ SET_KEY(#PropName); \
+ MUSCLE_INSERT_STRING_RAW (key, p->code); \
+ } \
+ } while (0)
+
+ CODE_PROP(destructor);
+ CODE_PROP(printer);
+#undef CODE_PROP
#undef SET_KEY
}
}
}
-/*---------------------------------------------------.
-| Output the symbol destructors or printers to OUT. |
-`---------------------------------------------------*/
-
-static void
-symbol_code_props_output (FILE *out, char const *what,
- code_props const *(*get)(symbol const *))
-{
- int i;
- char const *sep = "";
-
- fputs ("m4_define([b4_symbol_", out);
- fputs (what, out);
- fputs ("], \n[", out);
- for (i = 0; i < nsyms; ++i)
- {
- symbol *sym = symbols[i];
- char const *code = (*get) (sym)->code;
- if (code)
- {
- location loc = (*get) (sym)->location;
- /* Filename, lineno,
- Symbol-name, Symbol-number,
- code, optional typename. */
- fprintf (out, "%s[", sep);
- sep = ",\n";
- escaped_output (out, loc.start.file);
- fprintf (out, ", %d, ", loc.start.line);
- escaped_output (out, sym->tag);
- fprintf (out, ", %d, [[%s]]", sym->number, code);
- if (sym->type_name)
- fprintf (out, ", [[%s]]", sym->type_name);
- fputc (']', out);
- }
- }
- fputs ("])\n\n", out);
-}
-
-
static void
prepare_actions (void)
{
{
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);
/* Flags. */
MUSCLE_INSERT_BOOL ("debug_flag", debug_flag);
MUSCLE_INSERT_BOOL ("defines_flag", defines_flag);
- MUSCLE_INSERT_BOOL ("error_verbose_flag", error_verbose);
MUSCLE_INSERT_BOOL ("glr_flag", glr_parser);
MUSCLE_INSERT_BOOL ("locations_flag", locations_flag);
MUSCLE_INSERT_BOOL ("nondeterministic_flag", nondeterministic_parser);
prepare_rules ();
prepare_states ();
prepare_actions ();
+ prepare_symbol_definitions ();
prepare ();