public override void Chain(Trampoline t, Input input, OnChainResult result) { if (IsLL1()) { if (input.EOF) { result(Result.Failure(input, FailureType.UnexpectedEndOfStream)); } else { var predict = Predict(); Parser parser; if (predict.TryGetValue(input.Current, out parser)) { parser.Chain(t, input, result); } else { result(Result.Failure(input, FailureType.UnexpectedChars)); } } } else { var thunk = new ThunkParser(this, (tr, i, onResult) => { var results = new HashSet<IResult>(); var predicted = false; var gather = Gather(); foreach (var p in gather) { if ((!i.EOF || p.First() == Misc.UniversalCharSet) || (i.EOF || p.First().Contains(i.Current))) { predicted = true; tr.Add(p, i, r => { if (!results.Contains(r)) { Misc.Trace("Reduced: {0} *=> {1}", this, r); onResult(r); results.Add(r); } }); } } if (!predicted) { if (i.EOF) { onResult(Result.Failure(i, FailureType.UnexpectedEndOfStream)); } else { onResult(Result.Failure(i, FailureType.UnexpectedChars)); } } }); t.Add(thunk, input, result); } }