// B->C*{starNFA}|C+{plusNFA}|C private bool EvalB() { int saved_index = current_index_; if (!EvalC()) { current_index_ = saved_index; return(false); } bool success = false; saved_index = current_index_; do { if (regex_.Length <= current_index_) { break; } if (regex_[current_index_] != '*' && regex_[current_index_] != '+') { break; } if (nfa_stack_.Count < 1) { break; } NFA op = nfa_stack_.Pop(); NFA result = null; if (regex_[current_index_] == '*') { result = NFA.StarNFA(op); } else { result = NFA.PlusNFA(op); } if (result == null) { return(false); } nfa_stack_.Push(result); current_index_++; success = true; } while (false); if (!success) { current_index_ = saved_index; } return(true); }
// S'->|A{unionNFA}S'|epsilon private bool EvalSp() { bool success = false; int saved_index = current_index_; // S'->|A{unionNFA}S' do { if (regex_.Length <= current_index_) { break; } if (regex_[current_index_] != '|') { break; } // S'->|A{unionNFA}S' current_index_++; if (!EvalA()) { break; } if (nfa_stack_.Count < 2) { break; } NFA op2 = nfa_stack_.Pop(); NFA op1 = nfa_stack_.Pop(); NFA result = NFA.UnionNFA(op1, op2); if (result == null) { return(false); } nfa_stack_.Push(result); if (EvalSp() == false) { break; } success = true; } while (false); // not S'->|A{unionNFA}S' // Use S'->epsilon if (!success) { current_index_ = saved_index; success = true; } return(success); }
// C->(S)|others{createInput} private bool EvalC() { int saved_index = current_index_; if (regex_.Length <= current_index_) { return(false); } // C->(S) if (regex_[current_index_++] == '(' && EvalS() && current_index_ < regex_.Length && regex_[current_index_++] == ')') { return(true); } // C->others{createInput} char[] SPECIAL_MARK = { '(', ')', '*', '|', '\\', '+' }; current_index_ = saved_index; if (regex_[current_index_] == '\\') { if (regex_.Length <= current_index_ + 1) { return(false); } if (!SPECIAL_MARK.Contains(regex_[current_index_ + 1])) { return(false); } current_index_++; } else if (SPECIAL_MARK.Contains(regex_[current_index_])) { return(false); } NFA result = NFA.CreateFromInput(regex_[current_index_]); if (result == null) { current_index_ = saved_index; return(false); } nfa_stack_.Push(result); current_index_++; return(true); }
public static NFA CreateFromInput(char input) { AutomataStatus start = new AutomataStatus(); AutomataStatus end = new AutomataStatus(); start.AddTransition(input, end); NFA nfa = new NFA(); nfa.startStatus_ = start; nfa.endStatus_ = end; return(nfa); }
public static NFA PlusNFA(NFA op) { AutomataStatus start = new AutomataStatus(); AutomataStatus end = new AutomataStatus(); start.AddTransition((char)0, op.startStatus_); op.endStatus_.AddTransition((char)0, end); op.endStatus_.AddTransition((char)0, op.startStatus_); NFA nfa = new NFA(); nfa.startStatus_ = start; nfa.endStatus_ = end; return(nfa); }
// A'->B{concatNFA}A' | epsilon private bool EvalAp() { bool success = false; int saved_index = current_index_; // A'->B{concatNFA}A' do { if (!EvalB()) { break; } if (nfa_stack_.Count < 2) { break; } NFA op2 = nfa_stack_.Pop(); NFA op1 = nfa_stack_.Pop(); NFA result = NFA.ConcatNFA(op1, op2); if (result == null) { return(false); } nfa_stack_.Push(result); if (!EvalAp()) { break; } success = true; } while (false); // not A'->B{concatNFA}A' // Use A'->epsilon if (!success) { current_index_ = saved_index; success = true; } return(success); }
static void Main(string[] args) { NFATranslator t = new NFATranslator("ab*"); NFA nfa = t.GetNFA(); bool ret = nfa.Match("a"); }