X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/83bae26d3f9b374fb189703aa8795ecb3240bab2..ed91d427fe80ea2c5991c8862b0145613b9a0650:/src/graphviz.c diff --git a/src/graphviz.c b/src/graphviz.c index a2baa160..3ae0b546 100644 --- a/src/graphviz.c +++ b/src/graphviz.c @@ -53,7 +53,10 @@ start_graph (FILE *fout) "digraph %s\n" "{\n", quote (grammar_file)); - fprintf (fout, "node [shape=box]\n"); + fprintf (fout, + " node [fontname = courier, shape = box, colorscheme = paired6]\n" + " edge [fontname = courier]\n" + "\n"); } void @@ -93,13 +96,54 @@ no_reduce_bitset_init (state const *s, bitset *no_reduce_set) bitset_set (*no_reduce_set, s->errs->symbols[n]->number); } +static void +conclude_red (struct obstack *out, int source, rule_number ruleno, + bool enabled, bool first, FILE *fout) +{ + /* If no lookahead tokens were valid transitions, this reduction is + actually hidden, so cancel everything. */ + if (first) + return (void) obstack_finish0 (out); + else + { + char const *ed = enabled ? "e" : "d"; + char const *color = enabled ? ruleno ? "3" : "1" : "5"; + + /* First, build the edge's head. The name of reduction nodes is "nRm", + with n the source state and m the rule number. This is because we + don't want all the reductions bearing a same rule number to point to + the same state, since that is not the desired format. */ + fprintf (fout, " %1$d -> \"%1$dR%2$d%3$s\" [", + source, ruleno, ed); + + if (! obstack_empty_p (out)) + /* (The lookahead tokens have been added to the beginning of the + obstack, in the caller function.) */ + fprintf (fout, "label = \"[%s]\" ", obstack_finish0 (out)); + + /* Then, the edge's tail. */ + fprintf (fout, "style = solid]\n"); + + /* Build the associated diamond representation of the target rule. */ + fprintf (fout, " \"%dR%d%s\" [style = filled, " + "shape = diamond, fillcolor = %s, ", + source, ruleno, ed, color); + + if (ruleno) + fprintf (fout, "label = \"R%d\"]\n", ruleno); + else + fprintf (fout, "label = \"Acc\"]\n"); + + } +} + static bool print_token (struct obstack *out, bool first, char const *tok) { char const *q = escape (tok); if (! first) - obstack_sgrow (out, ","); + obstack_sgrow (out, ", "); obstack_sgrow (out, q); return false; } @@ -107,57 +151,59 @@ print_token (struct obstack *out, bool first, char const *tok) void output_red (state const *s, reductions const *reds, FILE *fout) { - int source = s->number; - int i, j; bitset no_reduce_set; - no_reduce_bitset_init (s, &no_reduce_set); + int j; + int source = s->number; - struct obstack oout; - obstack_init (&oout); + /* Two obstacks are needed: one for the enabled reductions, and one + for the disabled reductions, because in the end we want two + separate edges, even though in most cases only one will actually + be printed. */ + struct obstack dout; + struct obstack eout; + + no_reduce_bitset_init (s, &no_reduce_set); + obstack_init (&dout); + obstack_init (&eout); for (j = 0; j < reds->num; ++j) { - bool first = true; - bool disabled = false; - int ruleno = reds->rules[j]->user_number; + bool defaulted = false; + bool firstd = true; + bool firste = true; + rule_number ruleno = reds->rules[j]->user_number; rule *default_reduction = NULL; + if (yydefact[s->number] != 0) default_reduction = &rules[yydefact[s->number] - 1]; - /* First, print the edges that represent each possible reduction for - the given state. */ - obstack_printf (&oout, " %1$d -> \"%1$dR%2$d\" [label=\"", - source, ruleno); + /* Build the lookahead tokens lists, one for enabled transitions and one + for disabled transistions. */ if (default_reduction && default_reduction == reds->rules[j]) - first = print_token (&oout, true, "$default"); - else - for (i = 0; i < ntokens; i++) + defaulted = true; + if (reds->lookahead_tokens) + { + int i; + for (i = 0; i < ntokens; i++) if (bitset_test (reds->lookahead_tokens[j], i)) { - first = print_token (&oout, first, symbols[i]->tag); if (bitset_test (no_reduce_set, i)) - disabled = true; + firstd = print_token (&dout, firstd, symbols[i]->tag); + else + { + if (! defaulted) + firste = print_token (&eout, firste, symbols[i]->tag); + bitset_set (no_reduce_set, i); + } } - obstack_sgrow (&oout, "\" style=solid]\n"); - - /* Then, print the reduction's representation. This most be done later - because the we need the previously determined boolean to know if this - reduction is disabled or not. */ - obstack_printf (&oout, " \"%dR%d\" " - "[style=filled shape=diamond fillcolor=%s " - "label=\"R%d\"]\n", - source, ruleno, - disabled ? "firebrick1" : "yellowgreen", - ruleno); - - /* If no lookahead tokens were valid transitions, this reduction is - actually disabled, so don't print it. */ - if (first) - (void) obstack_finish0 (&oout); - else - fprintf (fout, obstack_finish0 (&oout)); + } + + /* Do the actual output. */ + conclude_red (&eout, source, ruleno, true, firste && !defaulted, fout); + conclude_red (&dout, source, ruleno, false, firstd, fout); } - obstack_free (&oout, 0); + obstack_free (&eout, 0); + obstack_free (&dout, 0); } void