add -> mul add'
add' -> + mul add' | ε
ε(读作 epsilon)是空集的意思
ε转换。也就是没有任何输入的情况下,也可以从一个状态迁移到另一个状态
这种转移通常在非确定性有限自动机(NFA)的转移过程中使用,尤其是在模式匹配和字符串匹配等任务中。
具体来说,ε转换是在状态图中添加一条边,将一个状态连接到另一个状态,而不需要任何输入字符。这种转移通常用于表示空字符匹配的情况,即在没有任何输入字符的情况下,程序可以从一个状态转移到另一个状态。
具体代码
/**
* 用NFA来匹配字符串
* @param state 当前所在的状态
* @param str 要匹配的字符串,用数组表示
* @param indexi1 当前匹配的字符开始的位置
* @return 匹配后,新的index的位置。指向匹配成功的字符的下一个字符
*/
int Regex::matchWithNFA(State *state, string str, int index1)
{
cout << "trying state : " << state->getName() << ", index = " << index1 << endl;
int index2 = index1;
vector<shared_ptr<Transition>> transitions = state->getTransitions();
for (size_t i = 0; i < transitions.size(); i++) {
Transition *transition = transitions[i].get();
State *nextState = state->getState(transition);
// epsilon转换
if (transition->isEpsilon()) {
index2 = matchWithNFA(nextState, str, index1);
if (index2 == str.length()) {
break;
}
} else if (transition->match(str[index1])) { // 消化一个字符,指针前移
index2++; // 消耗掉一个字符
if (index2 < str.length()) {
index2 = matchWithNFA(nextState, str, index1 + 1);
} else {
/**
* 如果已经扫描完所有的字符
* 检查当前状态是否是接受状态,或者可以通过epsilon到达接受状态
* 如果状态机还没有到达接受状态,本次匹配失败
*/
if (acceptable(nextState)) {
break;
} else {
index2 = -1;
}
}
}
}
return index2;
}