public void Add(Parser parser, Input input, OnChainResult continuation) { var tuple = new QueueTuple { Parser = parser, Input = input }; BackLinks.GetOrAdd(input, parsers => { if (!parsers.ContainsKey(parser)) { parsers.Add(parser, new HashSet<OnChainResult>()); } }, () => { var parsers = new Dictionary<Parser, HashSet<OnChainResult>>(); parsers.Add(parser, new HashSet<OnChainResult>()); return parsers; } ); BackLinks[input][parser].Add(continuation); Popped.Get(input, parsers => { if (parsers.ContainsKey(parser)) { foreach (var result in parsers[parser]) { Misc.Trace("Revisited: {0} *=> {1}", tuple, result); continuation(result); } return true; } return false; }, () => { Done.GetOrAdd(input, parsers => { if (!parsers.Contains(parser)) { AddTuple(parsers, tuple); } }, () => { var parsers = new HashSet<Parser>(); AddTuple(parsers, tuple); return parsers; } ); } ); }
private void AddTuple(ISet<Parser> parsers, QueueTuple tuple) { Queue.Push(tuple); parsers.Add(tuple.Parser); }