/// <summary> /// Input to automaton /// </summary> /// <param name="c">Key code</param> /// <param name="valid">Returns the character is valid</param> /// <param name="custom">Input custom</param> /// <returns>Next automaton</returns> public InputAutomaton Input(int c, ref bool valid, IInputCustom custom) { if (!_connect.ContainsKey(c)) { // reject valid = false; return(this); } else { valid = true; if (custom != null) { custom.SetFlags(_connect[c].Flags); } return(_connect[c].Automaton); } }
/// <summary> /// Build string from automaton. /// </summary> /// <param name="root">Root state</param> /// <param name="current">Current State</param> /// <param name="inputCustom">Input custom (do not modify)</param> /// <param name="pos">Return current position</param> /// <param name="nextCharacter">Return next valid character.</param> /// <returns>If nextCharacter is -1, Return only next character, otherwise, return all the string.</returns> public virtual string FromAutomaton(InputAutomaton root, InputAutomaton current, IInputCustom custom, ref int pos, ref int nextCharacter) { var result = new StringBuilder(); pos = 0; InputAutomaton automaton = root; while (!(automaton.IsAccept())) { bool found = false; KeyValuePair <int, InputAutomaton.Connect> select = new KeyValuePair <int, InputAutomaton.Connect>(); foreach (var i in automaton.GetConnect()) { // Use first connection because no need to consider customization int c = i.Key; bool valid = false; InputAutomaton automaton_tmp = automaton.Input(c, ref valid, null); if (current == automaton_tmp) { select = i; found = true; } } if (!found) { // Found no route, use the first route select = automaton.GetConnect().First(); } int c2 = select.Key; string addstring = select.Value.Character; // In CPU mode, use only first key if (nextCharacter != -1) { nextCharacter = c2; break; } // Go to next automaton bool valid2 = false; result.Append(addstring); automaton = automaton.Input(c2, ref valid2, null); if (current == automaton) { pos = result.Length; } } return(result.ToString()); }
/// <summary> /// Build string from automaton. /// </summary> /// <param name="root">Root state</param> /// <param name="current">Current State</param> /// <param name="inputCustom">Input custom (do not modify)</param> /// <param name="pos">Return current position</param> /// <param name="nextCharacter">Return next valid character.</param> /// <returns>If nextCharacter is -1, Return only next character, otherwise, return all the string.</returns> public virtual string FromAutomaton(InputAutomaton root, InputAutomaton current, IInputCustom custom, ref int pos, ref int nextCharacter) { var result = new StringBuilder(); pos = 0; InputAutomaton automaton = root; while (!(automaton.IsAccept())) { int c = '\0'; string addstring = ""; // If we have perfect input custom, use that foreach (var i in automaton.GetConnect()) { if (custom.IsSet(i.Value.Flags)) { c = i.Key; addstring = i.Value.Character; break; } } if (c == '\0') { // Found no route, use the first route c = automaton.GetConnect().First().Key; addstring = automaton.GetConnect().First().Value.Character; } // In CPU mode, use only first key if (nextCharacter != -1) { nextCharacter = c; break; } // Go to next automaton bool valid = false; result.Append(addstring); automaton = automaton.Input(c, ref valid, null); if (current == automaton) { pos = result.Length; } } return(result.ToString()); }
/// <summary> /// Build string from automaton. /// </summary> /// <param name="root">Root state</param> /// <param name="current">Current State</param> /// <param name="inputCustom">Input custom (do not modify)</param> /// <param name="pos">Return current position</param> /// <param name="nextCharacter">Return next valid character.</param> /// <returns>If nextCharacter is -1, Return only next character, otherwise, return all the string.</returns> public virtual string FromAutomaton(InputAutomaton root, InputAutomaton current, IInputCustom custom, ref int pos, ref int nextCharacter) { var result = new StringBuilder(); pos = 0; InputAutomaton automaton = root; while (!(automaton.IsAccept())) { // Select first connection var select = automaton.GetConnect().First(); int c2 = select.Key; string addstring = select.Value.Character; // In CPU mode, use only first key if (nextCharacter != -1) { nextCharacter = c2; break; } // Go to next automaton bool valid2 = false; result.Append(addstring); automaton = automaton.Input(c2, ref valid2, null); if (current == automaton) { pos = result.Length; } } return(result.ToString()); }