Пример #1
0
        public AppViewModel()
        {
            this.Tutorials = Tutorial.FindAll();

            var grammarTextChanges = this.WhenAny(x => x.GrammarText, grammarText => grammarText.GetValue());
            var testTextChanges    = this.WhenAny(x => x.TestText, testText => testText.GetValue());

            var pegParser   = new Pipeline.PegParser(grammarTextChanges);
            var pegCompiler = new Pipeline.PegCompiler(pegParser.Grammars);
            var csCompiler  = new Pipeline.CsCompiler(pegCompiler.Codes, pegParser.Grammars);

            this.RuleSelector = new Pipeline.RuleSelector(csCompiler.Parsers, pegParser.Grammars);
            var testParser  = new Pipeline.TestParser(this.RuleSelector.SelectedEntrypoints, testTextChanges);
            var testResults = testParser.Results.Select(r =>
            {
                return(r is string s ? s : JsonConvert.SerializeObject(r, Formatting.Indented));
            });

            var comparer  = new CompilerErrorListEqualityComparer();
            var allErrors = Observable.CombineLatest(
                pegParser.Errors.DistinctUntilChanged(comparer),
                pegCompiler.Errors.DistinctUntilChanged(comparer),
                csCompiler.Errors.DistinctUntilChanged(comparer),
                testParser.Errors.DistinctUntilChanged(comparer))
                            .Select(errorLists => errorLists.SelectMany(e => e));

            var grammarNameChanges = this.WhenAny(x => x.GrammarFileName, grammarFileName => grammarFileName.GetValue());
            var testNameChanges    = this.WhenAny(x => x.TestFileName, testFileName => testFileName.GetValue());

            var compileErrors = Observable.CombineLatest(
                allErrors,
                grammarNameChanges,
                testNameChanges,
                (errors, grammarName, testName) =>
            {
                return(errors.Select(e =>
                {
                    switch (e.FileName)
                    {
                    case Pipeline.PegParser.SentinelFileName:
                        return new CompilerError(grammarName, e.Line, e.Column, e.ErrorNumber, e.ErrorText)
                        {
                            IsWarning = e.IsWarning
                        };

                    case Pipeline.CsCompiler.SentinelFileName:
                        return new CompilerError(grammarName + ".g.cs", e.Line, e.Column, e.ErrorNumber, e.ErrorText)
                        {
                            IsWarning = e.IsWarning
                        };

                    case Pipeline.TestParser.SentinelFileName:
                        return new CompilerError(testName, e.Line, e.Column, e.ErrorNumber, e.ErrorText)
                        {
                            IsWarning = e.IsWarning
                        };

                    default:
                        return e;
                    }
                }).ToList());
            });

            this.pipeline = new CompositeDisposable(
                this.RuleSelector,
                testResults.BindTo(this, x => x.TestResults),
                compileErrors.BindTo(this, x => x.CompileErrors));

            this.Save = ReactiveCommand.CreateAsyncTask(grammarNameChanges.Select(n => n != "Untitled.peg"), async _ =>
            {
                Directory.CreateDirectory(Path.GetDirectoryName(this.grammarFileName));
                await FileUtilities.WriteAllTextAsync(this.grammarFileName, this.grammarText);
                this.GrammarChanged = false;
            });

            this.SaveAs = ReactiveCommand.CreateAsyncTask(async f =>
            {
                var fileName = (string)f;
                Directory.CreateDirectory(Path.GetDirectoryName(fileName));
                await FileUtilities.WriteAllTextAsync(fileName, this.grammarText);
                this.GrammarFileName = fileName;
                this.GrammarChanged  = false;
                return(true);
            });

            this.Load = ReactiveCommand.CreateAsyncTask(async f =>
            {
                var fileName         = (string)f;
                this.GrammarText     = await FileUtilities.ReadAllTextAsync(fileName);
                this.GrammarFileName = fileName;
                this.GrammarChanged  = false;
                this.TestText        = string.Empty;
                return(true);
            });

            this.LoadTutorial = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var tutorial         = (Tutorial)t;
                this.GrammarText     = File.Exists(tutorial.FileName) ? await FileUtilities.ReadAllTextAsync(tutorial.FileName) : tutorial.GrammarText;
                this.GrammarFileName = tutorial.FileName;
                this.GrammarChanged  = false;
                this.TestText        = tutorial.TestText;
                return(true);
            });
        }
Пример #2
0
        public AppViewModel()
        {
            this.tutorials = Tutorial.FindAll();

            var grammarNameChanges = this.WhenAny(x => x.GrammarFileName, x => x.Value);
            var grammarTextChanges = this.WhenAny(x => x.GrammarText, x => x.Value);
            var testNameChanges = this.WhenAny(x => x.TestFileName, x => x.Value);
            var testTextChanges = this.WhenAny(x => x.TestText, x => x.Value);

            var pegParser = new Pipeline.PegParser(grammarTextChanges, grammarNameChanges);
            var pegCompiler = new Pipeline.PegCompiler(pegParser.Grammars);
            var csCompiler = new Pipeline.CsCompiler(pegCompiler.Codes.Zip(pegParser.Grammars, Tuple.Create), grammarNameChanges);
            var testParser = new Pipeline.TestParser(csCompiler.Parsers, testTextChanges, testNameChanges);
            this.pipeline = new CompositeDisposable(pegParser, pegCompiler, csCompiler, testParser);

            testParser.Results.Select(r =>
            {
                var s = r as string;
                return s != null ? s : JsonConvert.SerializeObject(r, Formatting.Indented);
            }).BindTo(this, x => x.TestResults);

            var errorObvervables = new List<IObservable<IEnumerable<CompilerError>>>
            {
                pegParser.Errors,
                pegCompiler.Errors,
                csCompiler.Errors,
                testParser.Errors,
            };
            errorObvervables.Aggregate((a, b) => a.CombineLatest(b, (e, r) => e.Concat(r))).Select(e => e.ToList()).BindTo(this, x => x.CompileErrors);

            this.Save = new ReactiveCommand(grammarNameChanges.Select(n => n != "Untitled.peg"));
            this.Save.RegisterAsyncAction(_ =>
            {
                Directory.CreateDirectory(Path.GetDirectoryName(this.grammarFileName));
                File.WriteAllText(this.grammarFileName, this.grammarText);
                this.GrammarChanged = false;
            });

            this.SaveAs = new ReactiveCommand();
            this.SaveAs.RegisterAsyncAction(_ =>
            {
                var fileName = (string)_;
                Directory.CreateDirectory(Path.GetDirectoryName(fileName));
                File.WriteAllText(fileName, this.grammarText);
                this.GrammarFileName = fileName;
                this.GrammarChanged = false;
            });

            this.Load = new ReactiveCommand();
            this.Load.RegisterAsyncAction(_ =>
            {
                var fileName = (string)_;
                this.GrammarText = File.ReadAllText(fileName);
                this.GrammarFileName = fileName;
                this.GrammarChanged = false;
                this.TestText = "";
            });

            this.LoadTutorial = new ReactiveCommand();
            this.LoadTutorial.RegisterAsyncAction(_ =>
            {
                var tutorial = (Tutorial)_;
                this.GrammarText = File.Exists(tutorial.FileName) ? File.ReadAllText(tutorial.FileName) : tutorial.GrammarText;
                this.GrammarFileName = tutorial.FileName;
                this.GrammarChanged = false;
                this.TestText = tutorial.TestText;
            });
        }