| 3580 | #endif |
| 3581 | |
| 3582 | void Pattern::graph_dfa(const DFA::State *start) const |
| 3583 | { |
| 3584 | #ifndef WITH_NO_CODEGEN |
| 3585 | for (std::vector<std::string>::const_iterator it = opt_.f.begin(); it != opt_.f.end(); ++it) |
| 3586 | { |
| 3587 | const std::string& filename = *it; |
| 3588 | size_t len = filename.length(); |
| 3589 | if ((len > 3 && filename.compare(len - 3, 3, ".gv") == 0) |
| 3590 | || (len > 4 && filename.compare(len - 4, 4, ".dot") == 0)) |
| 3591 | { |
| 3592 | FILE *file = NULL; |
| 3593 | int err = 0; |
| 3594 | if (filename.compare(0, 7, "stdout.") == 0) |
| 3595 | file = stdout; |
| 3596 | else if (filename.at(0) == '+') |
| 3597 | err = reflex::fopen_s(&file, filename.c_str() + 1, "a"); |
| 3598 | else |
| 3599 | err = reflex::fopen_s(&file, filename.c_str(), "w"); |
| 3600 | if (!err && file) |
| 3601 | { |
| 3602 | ::fprintf(file, "digraph %s {\n\t\trankdir=LR;\n\t\tconcentrate=true;\n\t\tnode [fontname=\"ArialNarrow\"];\n\t\tedge [fontname=\"Courier\"];\n\n\t\tinit [root=true,peripheries=0,label=\"%s\",fontname=\"Courier\"];\n\t\tinit -> N%p;\n", opt_.n.empty() ? "FSM" : opt_.n.c_str(), opt_.n.c_str(), (void*)start); |
| 3603 | for (const DFA::State *state = start; state != NULL; state = state->next) |
| 3604 | { |
| 3605 | if (opt_.g > 1 && state != start && state->first != 0 && state->first < cut_) |
| 3606 | continue; |
| 3607 | if (state == start) |
| 3608 | ::fprintf(file, "\n/*START*/\t"); |
| 3609 | if (state->redo) |
| 3610 | ::fprintf(file, "\n/*REDO*/\t"); |
| 3611 | else if (state->accept) |
| 3612 | ::fprintf(file, "\n/*ACCEPT %u*/\t", state->accept); |
| 3613 | for (Lookaheads::const_iterator i = state->heads.begin(); i != state->heads.end(); ++i) |
| 3614 | ::fprintf(file, "\n/*HEAD %u*/\t", *i); |
| 3615 | for (Lookaheads::const_iterator i = state->tails.begin(); i != state->tails.end(); ++i) |
| 3616 | ::fprintf(file, "\n/*TAIL %u*/\t", *i); |
| 3617 | if (state != start && !state->accept && state->heads.empty() && state->tails.empty()) |
| 3618 | ::fprintf(file, "\n/*STATE*/\t"); |
| 3619 | ::fprintf(file, "N%p [label=\"", (void*)state); |
| 3620 | #ifdef DEBUG |
| 3621 | size_t k = 1; |
| 3622 | size_t n = std::sqrt(state->size()) + 0.5; |
| 3623 | const char *sep = ""; |
| 3624 | for (Positions::const_iterator i = state->begin(); i != state->end(); ++i) |
| 3625 | { |
| 3626 | ::fprintf(file, "%s", sep); |
| 3627 | if (i->accept()) |
| 3628 | { |
| 3629 | ::fprintf(file, "(%u)", i->accepts()); |
| 3630 | } |
| 3631 | else |
| 3632 | { |
| 3633 | if (i->iter()) |
| 3634 | ::fprintf(file, "%u.", i->iter()); |
| 3635 | ::fprintf(file, "%u", i->loc()); |
| 3636 | } |
| 3637 | if (i->lazy()) |
| 3638 | ::fprintf(file, "?%u", i->lazy()); |
| 3639 | if (i->anchor()) |