Example #1
0
        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);
            }
        }