protected internal override NFATable GenNFATable(int[] map, List <char[]> revMap) { NFATable ret = new NFATable(map, revMap); ret.AddState(); ret.SetStateFinal(1); ret.AddTransition(0, 1, set); return(ret); }
protected internal override NFATable GenNFATable(int[] map, List <char[]> revMap) { NFATable ret = factors.First().GenNFATable(map, revMap); foreach (var factor in factors.Skip(1)) { ret = ret + factor.GenNFATable(map, revMap); } return(ret); }
protected internal override NFATable GenNFATable(int[] map, List <char[]> revMap) { NFATable ret = terms.First().GenNFATable(map, revMap); foreach (var term in terms.Skip(1)) { ret = ret | term.GenNFATable(map, revMap); } return(ret); }
/// <summary> /// Constructs a regular expression. /// </summary> /// <param name="src"> The regular expression. </param> public RegEx(string src) { ASTExpr ast = Parser.Parse(src); if (ast == null) { throw new ArgumentException("Can't parse this regex. Sorry~"); } NFATable nfaTable = ast.ToNFATable(); DFATable dfaTable = nfaTable.ToDFATable(); dfa = dfaTable.ToDFA(); }
/// <summary> /// Cat two NFATables together. /// </summary> /// <param name="nfa1"> The first NFATable. </param> /// <param name="nfa2"> The second NFATable. </param> /// <returns> A new NFATable. </returns> public static NFATable operator +(NFATable nfa1, NFATable nfa2) { NFATable ret = nfa1.Merge(nfa2); int offset = nfa1.table.Count(); // Connect this.final to other.start. foreach (int final in nfa1.finals) { ret.AddEpsilonTransition(final, offset); } // Set the final states. foreach (int final in nfa2.finals) { ret.SetStateFinal(final + offset); } return(ret); }
protected internal override NFATable GenNFATable(int[] map, List <char[]> revMap) { NFATable ret = atom.GenNFATable(map, revMap); switch (meta) { case MetaChar.STAR: return(ret.Star()); case MetaChar.PLUS: return(ret + ret.Star()); case MetaChar.QUES: return(ret.Ques()); case MetaChar.NULL: default: return(ret); } }
/// <summary> /// Copy this NFATable. /// Notice that the new NFATable has no final state. /// </summary> /// <returns> A new NFATable. </returns> private NFATable Copy() { NFATable ret = new NFATable(map, revMap); // Add the first nfa. // Starts from 1 to avoid two 0 state. for (int i = 1; i < table.Count(); ++i) { ret.AddState(); } for (int from = 0; from < table.Count(); ++from) { for (int i = 0; i < table[from].Count(); ++i) { ret.table[from][i] = new HashSet <int>(table[from][i]); } } return(ret); }
/// <summary> /// Or operation. /// </summary> /// <param name="nfa1"> The first NFATable. </param> /// <param name="nfa2"> The second NFATable. </param> /// <returns> A new NFATable. </returns> public static NFATable operator |(NFATable nfa1, NFATable nfa2) { NFATable ret = nfa1.Merge(nfa2); int offset = nfa1.table.Count(); ret.AddEpsilonTransition(0, offset); foreach (int final in nfa1.finals) { ret.SetStateFinal(final); } int end = nfa1.finals.First(); foreach (int final in nfa2.finals) { ret.AddEpsilonTransition(final + offset, end); } return(ret); }
/// <summary> /// Match one or more. /// </summary> /// <returns> A new NFATable. </returns> public NFATable Ques() { NFATable nfa = new NFATable(map, revMap); nfa.AddState(); nfa.AddEpsilonTransition(0, 1); NFATable ret = nfa.Merge(this); ret.AddEpsilonTransition(0, 2); ret.SetStateFinal(1); int offset = 2; foreach (int final in finals) { ret.AddEpsilonTransition(final + offset, 1); } return(ret); }
/// <summary> /// Merge this nfa with another one /// by adding their states at the end of the table. /// Notice that the new NFATable has no final state. /// </summary> /// <param name="other"> NFATable to be merged. </param> /// <returns> The new merged NFATable. </returns> private NFATable Merge(NFATable other) { NFATable ret = Copy(); // Add the second nfa. int offset = ret.table.Count(); for (int i = 0; i < other.table.Count(); ++i) { ret.AddState(); } for (int from = 0; from < other.table.Count(); ++from) { for (int i = 0; i < other.table[from].Count(); ++i) { foreach (int to in other.table[from][i]) { ret.table[from + offset][i].Add(to + offset); } } } return(ret); }