24#define DECLARE_VISIT(Type) virtual void Visit##Type(Type##Node* that);
32 os_ <<
"digraph G {\n graph [label=\"";
48 os_ <<
"}" << std::endl;
52 if (node->info()->visited)
return;
53 node->info()->visited =
true;
58 os_ <<
" n" << from <<
" -> n" << on_failure <<
" [style=dotted];\n";
75 os_ <<
"{" << name <<
"}";
78 if (value < 0)
return;
80 os_ <<
"{" << name <<
"|" << value <<
"}";
89 os_ <<
" a" << that <<
" [shape=Mrecord, color=grey, fontcolor=grey, "
90 <<
"margin=0.1, fontsize=10, label=\"{";
93 printer.
PrintBit(
"NI", info->follows_newline_interest);
94 printer.
PrintBit(
"WI", info->follows_word_interest);
95 printer.
PrintBit(
"SI", info->follows_start_interest);
99 <<
" a" << that <<
" -> n" << that
100 <<
" [style=dashed, color=grey, arrowhead=none];\n";
103void DotPrinterImpl::VisitChoice(
ChoiceNode* that) {
104 os_ <<
" n" << that <<
" [shape=Mrecord, label=\"?\"];\n";
105 for (
int i = 0;
i < that->alternatives()->
length();
i++) {
107 os_ <<
" n" << that <<
" -> n" << alt.
node();
109 for (
int i = 0;
i < that->alternatives()->
length();
i++) {
110 GuardedAlternative alt = that->alternatives()->at(
i);
116void DotPrinterImpl::VisitLoopChoice(LoopChoiceNode* that) {
120void DotPrinterImpl::VisitNegativeLookaroundChoice(
121 NegativeLookaroundChoiceNode* that) {
125void DotPrinterImpl::VisitText(TextNode* that) {
126 Zone* zone = that->zone();
127 os_ <<
" n" << that <<
" [label=\"";
128 for (
int i = 0;
i < that->elements()->
length();
i++) {
129 if (
i > 0)
os_ <<
" ";
130 TextElement elm = that->elements()->at(
i);
131 switch (elm.text_type()) {
133 base::Vector<const base::uc16> data = elm.atom()->data();
134 for (
int j = 0; j < data.length(); j++) {
140 RegExpClassRanges* node = elm.class_ranges();
142 if (node->is_negated())
os_ <<
"^";
143 for (
int j = 0; j < node->ranges(zone)->
length(); j++) {
144 CharacterRange range = node->ranges(zone)->at(j);
145 os_ << AsUC32(range.from()) <<
"-" << AsUC32(range.to());
154 os_ <<
"\", shape=box, peripheries=2];\n";
156 os_ <<
" n" << that <<
" -> n" << that->on_success() <<
";\n";
157 Visit(that->on_success());
160void DotPrinterImpl::VisitBackReference(BackReferenceNode* that) {
161 os_ <<
" n" << that <<
" [label=\"$" << that->start_register() <<
"..$"
162 << that->end_register() <<
"\", shape=doubleoctagon];\n";
164 os_ <<
" n" << that <<
" -> n" << that->on_success() <<
";\n";
165 Visit(that->on_success());
168void DotPrinterImpl::VisitEnd(EndNode* that) {
169 os_ <<
" n" << that <<
" [style=bold, shape=point];\n";
173void DotPrinterImpl::VisitAssertion(AssertionNode* that) {
174 os_ <<
" n" << that <<
" [";
175 switch (that->assertion_type()) {
177 os_ <<
"label=\"$\", shape=septagon";
180 os_ <<
"label=\"^\", shape=septagon";
183 os_ <<
"label=\"\\b\", shape=septagon";
186 os_ <<
"label=\"\\B\", shape=septagon";
189 os_ <<
"label=\"(?<=\\n)\", shape=septagon";
194 RegExpNode* successor = that->on_success();
195 os_ <<
" n" << that <<
" -> n" << successor <<
";\n";
199void DotPrinterImpl::VisitAction(ActionNode* that) {
200 os_ <<
" n" << that <<
" [";
201 switch (that->action_type_) {
203 os_ <<
"label=\"$" << that->data_.u_store_register.reg
204 <<
":=" << that->data_.u_store_register.value <<
"\", shape=octagon";
207 os_ <<
"label=\"$" << that->data_.u_increment_register.reg
208 <<
"++\", shape=octagon";
211 os_ <<
"label=\"$" << that->data_.u_position_register.reg
212 <<
":=$pos\", shape=octagon";
215 os_ <<
"label=\"$" << that->data_.u_submatch.current_position_register
216 <<
":=$pos,begin-positive\", shape=septagon";
219 os_ <<
"label=\"$" << that->data_.u_submatch.current_position_register
220 <<
":=$pos,begin-negative\", shape=septagon";
223 os_ <<
"label=\"escape\", shape=septagon";
226 os_ <<
"label=\"$" << that->data_.u_empty_match_check.start_register
227 <<
"=$pos?,$" << that->data_.u_empty_match_check.repetition_register
228 <<
"<" << that->data_.u_empty_match_check.repetition_limit
229 <<
"?\", shape=septagon";
232 os_ <<
"label=\"clear $" << that->data_.u_clear_captures.range_from
233 <<
" to $" << that->data_.u_clear_captures.range_to
234 <<
"\", shape=septagon";
238 os_ <<
"label=\"flags $" << that->flags() <<
"\", shape=septagon";
244 RegExpNode* successor = that->on_success();
245 os_ <<
" n" << that <<
" -> n" << successor <<
";\n";
#define DECLARE_VISIT(type)
@ POSITIVE_SUBMATCH_SUCCESS
@ BEGIN_POSITIVE_SUBMATCH
@ BEGIN_NEGATIVE_SUBMATCH
void PrintPositive(const char *name, int value)
AttributePrinter(std::ostream &os)
void PrintBit(const char *name, bool value)
void PrintNode(const char *label, RegExpNode *node)
void Visit(RegExpNode *node)
void PrintAttributes(RegExpNode *from)
void PrintOnFailure(RegExpNode *from, RegExpNode *to)
DotPrinterImpl(std::ostream &os)
static void DotPrint(const char *label, RegExpNode *node)
virtual void Accept(NodeVisitor *visitor)=0
#define FOR_EACH_NODE_TYPE(VISIT)