| 3108 | } |
| 3109 | |
| 3110 | void Pattern::gencode_dfa(const DFA::State *start) const |
| 3111 | { |
| 3112 | #ifndef WITH_NO_CODEGEN |
| 3113 | for (std::vector<std::string>::const_iterator it = opt_.f.begin(); it != opt_.f.end(); ++it) |
| 3114 | { |
| 3115 | const std::string& filename = *it; |
| 3116 | size_t len = filename.length(); |
| 3117 | if ((len > 2 && filename.compare(len - 2, 2, ".h" ) == 0) |
| 3118 | || (len > 3 && filename.compare(len - 3, 3, ".hh" ) == 0) |
| 3119 | || (len > 4 && filename.compare(len - 4, 4, ".hpp") == 0) |
| 3120 | || (len > 4 && filename.compare(len - 4, 4, ".hxx") == 0) |
| 3121 | || (len > 3 && filename.compare(len - 3, 3, ".cc" ) == 0) |
| 3122 | || (len > 4 && filename.compare(len - 4, 4, ".cpp") == 0) |
| 3123 | || (len > 4 && filename.compare(len - 4, 4, ".cxx") == 0)) |
| 3124 | { |
| 3125 | FILE *file = NULL; |
| 3126 | int err = 0; |
| 3127 | if (filename.compare(0, 7, "stdout.") == 0) |
| 3128 | file = stdout; |
| 3129 | else if (filename.at(0) == '+') |
| 3130 | err = reflex::fopen_s(&file, filename.c_str() + 1, "a"); |
| 3131 | else |
| 3132 | err = reflex::fopen_s(&file, filename.c_str(), "w"); |
| 3133 | if (err || file == NULL) |
| 3134 | throw regex_error(regex_error::save_tables, filename); |
| 3135 | ::fprintf(file, |
| 3136 | "#include <reflex/matcher.h>\n\n" |
| 3137 | "#if defined(OS_WIN)\n" |
| 3138 | "#pragma warning(disable:4101 4102)\n" |
| 3139 | "#elif defined(__GNUC__)\n" |
| 3140 | "#pragma GCC diagnostic ignored \"-Wunused-variable\"\n" |
| 3141 | "#pragma GCC diagnostic ignored \"-Wunused-label\"\n" |
| 3142 | "#elif defined(__clang__)\n" |
| 3143 | "#pragma clang diagnostic ignored \"-Wunused-variable\"\n" |
| 3144 | "#pragma clang diagnostic ignored \"-Wunused-label\"\n" |
| 3145 | "#endif\n\n"); |
| 3146 | write_namespace_open(file); |
| 3147 | ::fprintf(file, |
| 3148 | "void reflex_code_%s(reflex::Matcher& m)\n" |
| 3149 | "{\n" |
| 3150 | " int c = 0;\n" |
| 3151 | " m.FSM_INIT(c);\n", opt_.n.empty() ? "FSM" : opt_.n.c_str()); |
| 3152 | for (const DFA::State *state = start; state != NULL; state = state->next) |
| 3153 | { |
| 3154 | ::fprintf(file, "\nS%u:\n", state->index); |
| 3155 | if (state == start) |
| 3156 | ::fprintf(file, " m.FSM_FIND();\n"); |
| 3157 | if (state->redo) |
| 3158 | ::fprintf(file, " m.FSM_REDO();\n"); |
| 3159 | else if (state->accept > 0) |
| 3160 | ::fprintf(file, " m.FSM_TAKE(%u);\n", state->accept); |
| 3161 | for (Lookaheads::const_iterator i = state->tails.begin(); i != state->tails.end(); ++i) |
| 3162 | ::fprintf(file, " m.FSM_TAIL(%u);\n", *i); |
| 3163 | for (Lookaheads::const_iterator i = state->heads.begin(); i != state->heads.end(); ++i) |
| 3164 | ::fprintf(file, " m.FSM_HEAD(%u);\n", *i); |
| 3165 | if (state->edges.rbegin() != state->edges.rend() && state->edges.rbegin()->first == META_DED) |
| 3166 | ::fprintf(file, " if (m.FSM_DENT()) goto S%u;\n", state->edges.rbegin()->second.second->index); |
| 3167 | bool peek = false; // if we need to read a character into c |
nothing calls this directly
no test coverage detected