public IObservable <IParseResult <TResult> > Parse(IObservableCursor <TSource> source) { #if !SILVERLIGHT && !PORT_45 && !PORT_40 using (ParserTraceSources.TraceQueryCompilation(name)) #endif { IObservable <IParseResult <TResult> > results; if (parserFactory == null) { results = parse(source); Contract.Assume(results != null); } else { var parser = parserFactory.Value; Contract.Assume(parser != null); results = parser.Parse(source); } return(results); } }
public IObservable <IParseResult <TResult> > Parse(IObservableCursor <TSource> source) { if (Interlocked.Exchange(ref parsing, 1) == 1) { throw new InvalidOperationException(Errors.ParseCalledWhileParsing); } if (cursor != null) { cursor.Dispose(); } cursor = CreateCursor(source); object gate = new object(); bool allowSubscription = true; return(Observable.Create <IParseResult <TResult> >( observer => { lock (gate) { if (!allowSubscription) { throw new InvalidOperationException(Errors.ParseSubscribeCalledWhileParsing); } allowSubscription = false; } #if !SILVERLIGHT && !PORT_45 && !PORT_40 var parse = Observable.Using(() => ParserTraceSources.TraceExecution(Cursor, TraceName), Parse); #else var parse = Parse(); #endif var parseSubscription = parse.Subscribe(observer); var sourceSubscription = cursor.Connect(); return new CompositeDisposable(sourceSubscription, parseSubscription); }) .Finally(() => { lock (gate) { allowSubscription = true; } Interlocked.Exchange(ref parsing, 0); })); }
public IObservable <IParseResult <T> > Parse(IObservableCursor <T> source) { return(Observable.Create <IParseResult <T> >( observer => { return source.Subscribe( Observer.Create <T>( value => { #if !SILVERLIGHT && !PORT_45 && !PORT_40 ParserTraceSources.TraceInput(value); #endif observer.OnNext(ParseResult.Create(value, length: 1)); }, observer.OnError, observer.OnCompleted), count: 1); })); }
protected override IObservable <IParseResult <TResult> > Parse() #endif { return(Observable.Create <IParseResult <TResult> >( observer => { var cursor = Cursor; IObservableParser <TSource, TResult> compiledGrammar; #if !SILVERLIGHT && !PORT_45 && !PORT_40 using (ParserTraceSources.TraceGrammarCompilation()) { compiledGrammar = grammar(cursor); } #else compiledGrammar = grammar(cursor); #endif var subscription = new SerialDisposable(); /* This scheduler is only used for recursion. It must be Immediate. * * In testing, using a scheduler such as CurrentThread would cause the * ambiguous lab to miss values due to the order in which the ambiguous * parser enqueues the subscription to the underyling source and the * memoizing cursor, in relation to this parser's scheduling of recursion. */ var schedule = Scheduler.Immediate.Schedule( self => { #if !SILVERLIGHT && !PORT_45 && !PORT_40 traceContext.TraceBeginIteration(); #endif bool hasResult = false; subscription.SetDisposableIndirectly( () => compiledGrammar.Parse(cursor).SubscribeSafe( result => { var lookAhead = result as ILookAheadParseResult <TResult>; if (lookAhead != null) { lookAhead.OnCompleted(success: true); return; } hasResult = true; #if !SILVERLIGHT && !PORT_45 && !PORT_40 traceContext.TraceResult(result); #endif observer.OnNext(result); if (!cursor.AtEndOfSequence) { cursor.Move(result.Length); } }, observer.OnError, () => { if (!hasResult) { cursor.MoveToEnd(); } if (cursor.AtEndOfSequence) { observer.OnCompleted(); } else { self(); } })); }); return new CompositeDisposable(schedule, subscription); })); }