void DumpFiniteAutomaton(FiniteAutomatonState<char> state, ISet<FiniteAutomatonState<char>> visited) { if (visited.Contains(state)) return; visited.Add(state); Debug.WriteLine(state.GetHashCode() + ": "); if (state.AcceptTerminals != null) { foreach (var term in state.AcceptTerminals) { Debug.WriteLine(" Accept " + term.Name); } } if (state.RejectTerminals != null) { foreach (var term in state.RejectTerminals) { Debug.WriteLine(" Reject " + term.Name); } } if (state.Transitions != null) { foreach (var trans in state.Transitions) { Debug.WriteLine(" Transition:"); Debug.WriteLine(" Match Expression: " + trans.Characters); Debug.WriteLine(" MatchEof: " + trans.MatchEpsilon); Debug.WriteLine(" MatchEpsilon: " + trans.MatchEpsilon); Debug.WriteLine(" Target: " + trans.Target.GetHashCode()); } foreach (var trans in state.Transitions) { DumpFiniteAutomaton(trans.Target, visited); } } }
public void Initialize() { _expressionHelper = new ExpressionHelper(); var matchOpen = new HashSet<char> { '<' }; var matchClose = new HashSet<char> { '>' }; var matchSlash = new HashSet<char> { '/' }; var matchLetter = Utilities.AllLetters(); var matchLetterOrDigit = Utilities.Union(matchLetter, Utilities.AllDigits()); var matchw = new HashSet<char> { 'w' }; var matchh = new HashSet<char> { 'h' }; var matchi = new HashSet<char> { 'i' }; var matchl = new HashSet<char> { 'l' }; var matche = new HashSet<char> { 'e' }; var matchf = new HashSet<char> { 'f' }; var matchSpace = Utilities.AllWhitespace(); //_parserGenerator = new TerminalClassifier<char>(); // Simple XML tags (no attributes) _openTag = new Terminal<char> { Name = "OpenTag", ValueType = typeof(string) }; _closeTag = new Terminal<char> { Name = "CloseTag", ValueType = typeof(string) }; _leafTag = new Terminal<char> { Name = "LeafTag", ValueType = typeof(string) }; // Other terminals commonly found in programming languages. _if = new Terminal<char> { Name = "If", ValueType = typeof(void) }; _while = new Terminal<char> { Name = "While", ValueType = typeof(void) }; _identifier = new Terminal<char> { Name = "Identifier", ValueType = typeof(string) }; _whitespace = new Terminal<char> { Name = "Whitespace", ValueType = typeof(void) }; var openTagAccept = new FiniteAutomatonState<char> { IsAccepting = true, IsRejecting = false, }; var closeTagAccept = new FiniteAutomatonState<char> { IsAccepting = true, IsRejecting = false }; var leafTagAccept = new FiniteAutomatonState<char> { IsAccepting = true, IsRejecting = false }; var leafClose = new FiniteAutomatonState<char> { Transitions = new[] {new FiniteAutomatonStateTransition<char> { Characters = matchClose, Target = leafTagAccept } } }; var leafName = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchSlash, Target = leafClose}, new FiniteAutomatonStateTransition<char> { Characters = matchLetterOrDigit}} }; leafName.Transitions.Skip(1).First().Target = leafName; var beginLeafName = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchLetter, Target = leafName}} }; var leafOpen = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchOpen, Target = beginLeafName} } }; var closeClose = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchClose, Target = closeTagAccept} } }; var closeName = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { MatchEpsilon = true, Target = closeClose }, new FiniteAutomatonStateTransition<char> { Characters = matchLetterOrDigit } } }; closeName.Transitions.Skip(1).First().Target = closeName; var beginCloseName = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchLetter, Target = closeName } } }; var closeSlash = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchSlash, Target = beginCloseName} } }; var closeOpen = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchOpen, Target = closeSlash}} }; var openName = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchClose, Target = openTagAccept}, new FiniteAutomatonStateTransition<char> { Characters = matchLetterOrDigit} } }; openName.Transitions.Skip(1).First().Target = openName; var beginOpenName = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchLetter, Target = openName } } }; var openOpen = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchOpen, Target = beginOpenName}} }; _openTag.InitialState = openOpen; _closeTag.InitialState = closeOpen; _leafTag.InitialState = leafOpen; // Keywords & identifiers var acceptIf = new FiniteAutomatonState<char> { IsAccepting = true }; var fIf = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchf, Target = acceptIf } } }; var iIf = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchi, Target = fIf } } }; _if.InitialState = iIf; var acceptWhile = new FiniteAutomatonState<char> { IsAccepting = true }; var eWhile = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matche, Target = acceptWhile } } }; var lWhile = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchl, Target = eWhile} } }; var iWhile = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchi, Target = lWhile} } }; var hWhile = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchh, Target = iWhile} } }; var wWhile = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchw, Target = hWhile} } }; _while.InitialState = wWhile; var identifierChar = new FiniteAutomatonState<char> { IsAccepting = true, Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchLetterOrDigit } } }; identifierChar.Transitions.First().Target = identifierChar; var identifierBegin = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchLetter, Target = identifierChar } } }; _identifier.InitialState = identifierBegin; var whitespaceChar = new FiniteAutomatonState<char> { IsAccepting = true, Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchSpace } } }; whitespaceChar.Transitions.First().Target = whitespaceChar; var firstWhitespace = new FiniteAutomatonState<char> { Transitions = new[] { new FiniteAutomatonStateTransition<char> { Characters = matchSpace, Target=whitespaceChar } } }; _whitespace.InitialState = firstWhitespace; }
void DumpFiniteAutomaton(FiniteAutomatonState<char> initial) { DumpFiniteAutomaton(initial, new HashSet<FiniteAutomatonState<char>>()); }