public RuleSelector(IObservable <dynamic> parsers, IObservable <Grammar> grammars) { var entrypoints = parsers .Zip(grammars, (parser, grammar) => new { parser, grammar }) .Select(p => { var list = new List <ParserEntrypoint>(); if (p.grammar != null) { var rules = PublicRuleFinder.Find(p.grammar); if (rules.StartRule != null) { list.Add(new StartRuleEntrypoint(p.parser, rules.StartRule)); } list.AddRange(rules.PublicRules.Select(rule => new PublicRuleEntrypoint(p.parser, rule))); list.AddRange(rules.ExportedRules.Select(rule => new ExportedRuleEntrypoint(p.parser, rule))); } return(list); }); this.SelectedEntrypoints = this.WhenAny(x => x.SelectedEntrypoint, selectedEntrypoint => selectedEntrypoint.GetValue()); var intentDetector = Observable.CombineLatest( entrypoints, this.SelectedEntrypoints.StartWith(default(ParserEntrypoint)), this.SelectedEntrypoints.Where(e => e != null).StartWith(default(ParserEntrypoint)), (list, current, intent) => new { list, current, intent }); this.disposable = new CompositeDisposable( entrypoints.BindTo(this, x => x.Entrypoints), intentDetector.Subscribe(tuple => { if (tuple.current == null && tuple.list.Count > 0) { ParserEntrypoint intended = null; if (tuple.intent != null) { intended = tuple.list.Where(e => ParserEntrypointEqualityComparer.Instance.Equals(e, tuple.intent)).FirstOrDefault(); } intended = intended ?? tuple.list.FirstOrDefault(); if (intended != null) { this.SelectedEntrypoint = intended; } } })); }
private static ParseResult ParseTest(ParserEntrypoint entrypoint, string subject) { if (entrypoint == null) { return(new ParseResult { Errors = new CompilerError[0], Result = null, }); } subject = subject ?? string.Empty; try { var tracer = new WarningsPerformanceTracer(); var result = entrypoint.Parse(subject, SentinelFileName, tracer); return(new ParseResult { Result = result, Errors = tracer.Recommendations, }); } catch (Exception ex) { var cursor = ex.Data["cursor"] as Cursor ?? new Cursor(subject, 0, SentinelFileName); var parts = Regex.Split(ex.Message, @"(?<=^\w+):"); if (parts.Length == 1) { parts = new[] { string.Empty, parts[0] }; } return(new ParseResult { Errors = new List <CompilerError> { new CompilerError(SentinelFileName, cursor.Line, cursor.Column, errorNumber: parts[0], errorText: parts[1]), }.AsReadOnly(), }); } }