void my_regex::NFA::create_nfa_node(const my_string ®) { // 第一遍遍历的时候主要处理\开头引出的特殊符号 std::vector<p_element> element_vec; element_vec.reserve(reg.length()); p_element elem; for (int i = 0; i < reg.length(); i++) { switch (reg[i]) { case my_char('+'): case my_char('?'): case my_char('*'): elem = p_element(new num_symbol(reg[i])); element_vec.push_back(elem); break; case my_char('\\'): elem = p_element(new num_symbol(reg[++i]));// 注意,这里现在是把所有跟在反斜杠后面的字符都当作普通字符来处理 element_vec.push_back(elem); break; case my_char('.'): elem = p_element(new point_symbol); element_vec.push_back(elem); break; case my_char('('): elem = p_element(new open_parentheses); element_vec.push_back(elem); break; case my_char(')'): elem = p_element(new close_parentheses); element_vec.push_back(elem); break; case my_char('|'): elem = p_element(new or_symbol); element_vec.push_back(elem); break; default: elem = p_element(new character(reg[i])); element_vec.push_back(elem); break; } } // 将基础元素转化为前缀表达式 element_vec_2_prefix_exp(element_vec); //assert(element_vec.size() == 1);//最后只剩下一个大的前缀表达式//已经在函数里判断过了 p_nfa_node begin(new nfa_node), end(new nfa_node); prefix_exp_2_nfa_node(element_vec, begin, end); end->accept = true; // todo:加入清理内存的操作 start = begin; }
size_t my_regex::NFA::try_match(const my_string &str) { size_t farthest = 0;//记录匹配到的最远距离 std::vector<cp_nfa_node> current_pnodes, next_pnodes; current_pnodes.push_back(start); get_epson_closure(current_pnodes); bool matched = start->accept;//当前字符匹配后是否满足正则表达式 for (auto &cur_node : current_pnodes) { matched |= cur_node->accept; } for (size_t i = 0; i < str.length(); i++) { matched = false; next_pnodes.clear(); for (auto &cur_node : current_pnodes) { // 先沿着正常边走 for (auto &n_edg : cur_node->norm_edgs) { if (n_edg.c == str[i]) { next_pnodes.push_back(n_edg.p_next_node); } } // 小数点通配符 for (auto &p_node : cur_node->point_edgs) { next_pnodes.push_back(p_node.p_next_node); } } if (next_pnodes.empty()) { // 匹配不下去了,停止 return farthest; } else { current_pnodes.swap(next_pnodes); get_epson_closure(current_pnodes); for (auto &cur_node : current_pnodes) { matched |= cur_node->accept; } if (matched) { farthest = i+1; } } } return farthest; }
my_string::my_string(my_string const &str) : data_(new char[str.length() + 1]) { strcpy(data_, str.c_str()); }