]>
git.saurik.com Git - bison.git/blob - src/graphviz.c
e7611b0f3ebf05dce19ea530fbf5f79798acbb44
   1 /* Output Graphviz specification of a state machine generated by Bison. 
   3    Copyright (C) 2006-2007, 2009-2015 Free Software Foundation, Inc. 
   5    This file is part of Bison, the GNU Compiler Compiler. 
   7    This program is free software: you can redistribute it and/or modify 
   8    it under the terms of the GNU General Public License as published by 
   9    the Free Software Foundation, either version 3 of the License, or 
  10    (at your option) any later version. 
  12    This program is distributed in the hope that it will be useful, 
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15    GNU General Public License for more details. 
  17    You should have received a copy of the GNU General Public License 
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ 
  20 /* Written by Paul Eggert and Satya Kiran Popuri.  */ 
  32 /* Return an unambiguous printable representation for NAME, suitable 
  33    for C strings.  Use slot 2 since the user may use slots 0 and 1.  */ 
  36 quote (char const *name
) 
  38   return quotearg_n_style (2, c_quoting_style
, name
); 
  42 start_graph (FILE *fout
) 
  45            _("// Generated by %s.\n" 
  46              "// Report bugs to <%s>.\n" 
  47              "// Home page: <%s>.\n" 
  55            quote (grammar_file
)); 
  57            "  node [fontname = courier, shape = box, colorscheme = paired6]\n" 
  58            "  edge [fontname = courier]\n" 
  63 output_node (int id
, char const *label
, FILE *fout
) 
  65   fprintf (fout
, "  %d [label=\"%s\"]\n", id
, label
); 
  69 output_edge (int source
, int destination
, char const *label
, 
  70              char const *style
, FILE *fout
) 
  72   fprintf (fout
, "  %d -> %d [style=%s", source
, destination
, style
); 
  74     fprintf (fout
, " label=%s", quote (label
)); 
  79 escape (char const *name
) 
  81   char *q 
= quote (name
); 
  82   q
[strlen (q
) - 1] = '\0'; 
  87 no_reduce_bitset_init (state 
const *s
, bitset 
*no_reduce_set
) 
  90   *no_reduce_set 
= bitset_create (ntokens
, BITSET_FIXED
); 
  91   bitset_zero (*no_reduce_set
); 
  92   FOR_EACH_SHIFT (s
->transitions
, n
) 
  93     bitset_set (*no_reduce_set
, TRANSITION_SYMBOL (s
->transitions
, n
)); 
  94   for (n 
= 0; n 
< s
->errs
->num
; ++n
) 
  95     if (s
->errs
->symbols
[n
]) 
  96       bitset_set (*no_reduce_set
, s
->errs
->symbols
[n
]->number
); 
 100 conclude_red (struct obstack 
*out
, int source
, rule_number ruleno
, 
 101               bool enabled
, bool first
, FILE *fout
) 
 103   /* If no lookahead tokens were valid transitions, this reduction is 
 104      actually hidden, so cancel everything. */ 
 106     (void) obstack_finish0 (out
); 
 109       char const *ed 
= enabled 
? "" : "d"; 
 110       char const *color 
= enabled 
? ruleno 
? "3" : "1" : "5"; 
 112       /* First, build the edge's head. The name of reduction nodes is "nRm", 
 113          with n the source state and m the rule number. This is because we 
 114          don't want all the reductions bearing a same rule number to point to 
 115          the same state, since that is not the desired format. */ 
 116       fprintf (fout
, "  %1$d -> \"%1$dR%2$d%3$s\" [", 
 119       /* (The lookahead tokens have been added to the beginning of the 
 120          obstack, in the caller function.) */ 
 121       if (! obstack_empty_p (out
)) 
 123           char *label 
= obstack_finish0 (out
); 
 124           fprintf (fout
, "label=\"[%s]\", ", label
); 
 125           obstack_free (out
, label
); 
 128       /* Then, the edge's tail. */ 
 129       fprintf (fout
, "style=solid]\n"); 
 131       /* Build the associated diamond representation of the target rule. */ 
 132       fprintf (fout
, " \"%dR%d%s\" [label=\"", 
 135         fprintf (fout
, "R%d", ruleno
); 
 137         fprintf (fout
, "Acc"); 
 139       fprintf (fout
, "\", fillcolor=%s, shape=diamond, style=filled]\n", 
 145 print_token (struct obstack 
*out
, bool first
, char const *tok
) 
 147   char const *q 
= escape (tok
); 
 150     obstack_sgrow (out
, ", "); 
 151   obstack_sgrow (out
, q
); 
 156 output_red (state 
const *s
, reductions 
const *reds
, FILE *fout
) 
 158   bitset no_reduce_set
; 
 160   int source 
= s
->number
; 
 162   /* Two obstacks are needed: one for the enabled reductions, and one 
 163      for the disabled reductions, because in the end we want two 
 164      separate edges, even though in most cases only one will actually 
 169   no_reduce_bitset_init (s
, &no_reduce_set
); 
 170   obstack_init (&dout
); 
 171   obstack_init (&eout
); 
 173   for (j 
= 0; j 
< reds
->num
; ++j
) 
 175       bool defaulted 
= false; 
 178       rule_number ruleno 
= reds
->rules
[j
]->number
; 
 179       rule 
*default_reduction 
= NULL
; 
 181       if (yydefact
[s
->number
] != 0) 
 182         default_reduction 
= &rules
[yydefact
[s
->number
] - 1]; 
 184       /* Build the lookahead tokens lists, one for enabled transitions and one 
 185          for disabled transistions. */ 
 186       if (default_reduction 
&& default_reduction 
== reds
->rules
[j
]) 
 188       if (reds
->lookahead_tokens
) 
 191           for (i 
= 0; i 
< ntokens
; i
++) 
 192             if (bitset_test (reds
->lookahead_tokens
[j
], i
)) 
 194                 if (bitset_test (no_reduce_set
, i
)) 
 195                   firstd 
= print_token (&dout
, firstd
, symbols
[i
]->tag
); 
 199                       firste 
= print_token (&eout
, firste
, symbols
[i
]->tag
); 
 200                     bitset_set (no_reduce_set
, i
); 
 205       /* Do the actual output. */ 
 206       conclude_red (&dout
, source
, ruleno
, false, firstd
, fout
); 
 207       conclude_red (&eout
, source
, ruleno
, true, firste 
&& !defaulted
, fout
); 
 209   obstack_free (&dout
, 0); 
 210   obstack_free (&eout
, 0); 
 211   bitset_free (no_reduce_set
); 
 215 finish_graph (FILE *fout
)