1 #ifdef RE2C_DEBUG
2
3 #include "src/util/c99_stdint.h"
4 #include <map>
5 #include <stdio.h>
6 #include <string>
7 #include <utility>
8 #include <valarray>
9 #include <vector>
10
11 #include "src/adfa/adfa.h"
12 #include "src/debug/debug.h"
13 #include "src/dfa/tcmd.h"
14 #include "src/regexp/rule.h"
15 #include "src/regexp/tag.h"
16
17
18 namespace re2c {
19
dump_adfa_range(uint32_t lower,uint32_t upper)20 static void dump_adfa_range(uint32_t lower, uint32_t upper)
21 {
22 fprintf(stderr, "%u", lower);
23 if (--upper > lower) {
24 fprintf(stderr, "-%u", upper);
25 }
26 }
27
dump_adfa(const DFA & dfa)28 void dump_adfa(const DFA &dfa)
29 {
30 std::map<const State*, uint32_t> st2idx;
31 uint32_t idx = 0;
32 for (const State *s = dfa.head; s; s = s->next) {
33 st2idx[s] = idx++;
34 }
35
36 fprintf(stderr,
37 "digraph DFA {\n"
38 " rankdir=LR\n"
39 " node[shape=Mrecord fontname=fixed]\n"
40 " edge[arrowhead=vee fontname=fixed]\n\n");
41
42 fprintf(stderr,
43 " n [shape=point]"
44 " n -> n%u [style=dotted label=\"", st2idx[dfa.head]);
45 dump_tcmd(dfa.tcpool[dfa.tags0]);
46 fprintf(stderr, "\"]\n");
47
48 for (const State *s = dfa.head; s; s = s->next) {
49 const char *attr;
50 Action::type_t action = s->action.type;
51
52 if (action == Action::ACCEPT) {
53 attr = "style=filled fillcolor=gray";
54 } else if (action == Action::RULE) {
55 attr = "style=filled fillcolor=lightgray";
56 } else {
57 attr = "";
58 }
59 fprintf(stderr, " n%u [height=0.2 width=0.2 label=\"", st2idx[s]);
60 if (s->fill && action != Action::MOVE) {
61 fprintf(stderr, "F(%u) ", (uint32_t)s->fill);
62 }
63 if (action == Action::RULE) {
64 const Rule &r = dfa.rules[s->action.info.rule];
65 for (size_t t = r.ltag; t < r.htag; ++t) {
66 if (t > r.ltag) fprintf(stderr, " ");
67 const std::string *name = dfa.tags[t].name;
68 fprintf(stderr, "%s(%d)",
69 name ? name->c_str() : "/", dfa.finvers[t]);
70 }
71 }
72 dump_tcmd(dfa.tcpool[s->stadfa_tags]);
73 dump_tcmd(dfa.tcpool[s->go.tags]);
74 fprintf(stderr, "\" %s]\n", attr);
75
76 if (action == Action::ACCEPT) {
77 const accept_t &accept = *s->action.info.accepts;
78 for (uint32_t i = 0; i < accept.size(); ++i) {
79 fprintf(stderr, " n%u -> n%u [label=\"", st2idx[s],
80 st2idx[accept[i].first]);
81 dump_tcmd(dfa.tcpool[accept[i].second]);
82 fprintf(stderr, "\" style=dotted]\n");
83 }
84 }
85
86 const Span *x = s->go.span, *e = x + s->go.nspans;
87 for (uint32_t lb = 0; x < e; lb = x->ub, ++x) {
88 if (!x->to) continue;
89
90 bool eat = true;
91 const Action::type_t act = x->to->action.type;
92 if (act == Action::MOVE || act == Action::RULE) {
93 attr = "style=dotted";
94 eat = false;
95 } else {
96 attr = "";
97 }
98 fprintf(stderr, " n%u -> n%u [label=\"", st2idx[s], st2idx[x->to]);
99 if (eat) dump_adfa_range(lb, x->ub);
100 dump_tcmd(dfa.tcpool[x->tags]);
101 fprintf(stderr, "\" %s]\n", attr);
102 }
103 }
104
105 fprintf(stderr, "}\n");
106 }
107
108 } // namespace re2c
109
110 #endif // RE2C_DEBUG
111