/Examples/SciChart.Examples.Demo/CodeHighlighter/Parsing/LanguageParser.cs
https://github.com/ABTSoftware/SciChart.WPF.Examples · C# · 204 lines · 164 code · 34 blank · 6 comment · 23 complexity · d349bfaf56466a21d4adb62956ff80cf MD5 · raw file
- // (c) Copyright Microsoft Corporation.
- // This source is subject to the Microsoft Public License (Ms-PL).
- // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
- // All other rights reserved.
- // <auto-generated />
- // No style analysis for imported project.
- using System;
- using System.Collections.Generic;
- using System.Text.RegularExpressions;
- using CodeHighlighter.Common;
- using CodeHighlighter.Compilation;
- namespace CodeHighlighter.Parsing
- {
- internal class LanguageParser : ILanguageParser
- {
- private readonly ILanguageCompiler languageCompiler;
- private readonly ILanguageRepository languageRepository;
- public LanguageParser(ILanguageCompiler languageCompiler,
- ILanguageRepository languageRepository)
- {
- this.languageCompiler = languageCompiler;
- this.languageRepository = languageRepository;
- }
- public void Parse(string sourceCode,
- ILanguage language,
- Action<string, IList<Scope>> parseHandler)
- {
- if (string.IsNullOrEmpty(sourceCode))
- return;
- CompiledLanguage compiledLanguage = languageCompiler.Compile(language);
- Parse(sourceCode, compiledLanguage, parseHandler);
- }
- private void Parse(string sourceCode,
- CompiledLanguage compiledLanguage,
- Action<string, IList<Scope>> parseHandler)
- {
- Match regexMatch = compiledLanguage.Regex.Match(sourceCode);
- if (!regexMatch.Success)
- parseHandler(sourceCode, new List<Scope>());
- else
- {
- int currentIndex = 0;
- while (regexMatch.Success)
- {
- string sourceCodeBeforeMatch = sourceCode.Substring(currentIndex, regexMatch.Index - currentIndex);
- if (!string.IsNullOrEmpty(sourceCodeBeforeMatch))
- parseHandler(sourceCodeBeforeMatch, new List<Scope>());
- string matchedSourceCode = sourceCode.Substring(regexMatch.Index, regexMatch.Length);
- if (!string.IsNullOrEmpty(matchedSourceCode))
- {
- List<Scope> capturedStylesForMatchedFragment = GetCapturedStyles(regexMatch, regexMatch.Index, compiledLanguage);
- List<Scope> capturedStyleTree = CreateCapturedStyleTree(capturedStylesForMatchedFragment);
- parseHandler(matchedSourceCode, capturedStyleTree);
- }
- currentIndex = regexMatch.Index + regexMatch.Length;
- regexMatch = regexMatch.NextMatch();
- }
- string sourceCodeAfterAllMatches = sourceCode.Substring(currentIndex);
- if (!string.IsNullOrEmpty(sourceCodeAfterAllMatches))
- parseHandler(sourceCodeAfterAllMatches, new List<Scope>());
- }
- }
- private static List<Scope> CreateCapturedStyleTree(IList<Scope> capturedStyles)
- {
- capturedStyles.SortStable((x, y) => x.Index.CompareTo(y.Index));
- var capturedStyleTree = new List<Scope>(capturedStyles.Count);
- Scope currentScope = null;
- foreach (Scope capturedStyle in capturedStyles)
- {
- if (currentScope == null)
- {
- capturedStyleTree.Add(capturedStyle);
- currentScope = capturedStyle;
- continue;
- }
- AddScopeToNestedScopes(capturedStyle, ref currentScope, capturedStyleTree);
- }
- return capturedStyleTree;
- }
- private static void AddScopeToNestedScopes(Scope scope,
- ref Scope currentScope,
- ICollection<Scope> capturedStyleTree)
- {
- if (scope.Index >= currentScope.Index && (scope.Index + scope.Length <= currentScope.Index + currentScope.Length))
- {
- currentScope.AddChild(scope);
- currentScope = scope;
- }
- else
- {
- currentScope = currentScope.Parent;
- if (currentScope != null)
- AddScopeToNestedScopes(scope, ref currentScope, capturedStyleTree);
- else
- capturedStyleTree.Add(scope);
- }
- }
- private List<Scope> GetCapturedStyles(Match regexMatch,
- int currentIndex,
- CompiledLanguage compiledLanguage)
- {
- var capturedStyles = new List<Scope>();
- for (int i = 0; i < regexMatch.Groups.Count; i++)
- {
- Group regexGroup = regexMatch.Groups[i];
- string styleName = compiledLanguage.Captures[i];
- if (regexGroup.Length == 0 || String.IsNullOrEmpty(styleName))
- continue;
- else
- foreach (Capture regexCapture in regexGroup.Captures)
- AppendCapturedStylesForRegexCapture(regexCapture, currentIndex, styleName, capturedStyles);
- }
- return capturedStyles;
- }
- private void AppendCapturedStylesForRegexCapture(Capture regexCapture,
- int currentIndex,
- string styleName,
- ICollection<Scope> capturedStyles)
- {
- if (styleName.StartsWith(ScopeName.LanguagePrefix))
- {
- string nestedGrammarId = styleName.Substring(1);
- AppendCapturedStylesForNestedLanguage(regexCapture, regexCapture.Index - currentIndex, nestedGrammarId, capturedStyles);
- }
- else
- capturedStyles.Add(new Scope(styleName, regexCapture.Index - currentIndex, regexCapture.Length));
- }
- private void AppendCapturedStylesForNestedLanguage(Capture regexCapture,
- int offset,
- string nestedLanguageId,
- ICollection<Scope> capturedStyles)
- {
- ILanguage nestedLanguage = languageRepository.FindById(nestedLanguageId);
- if (nestedLanguage == null)
- throw new InvalidOperationException("The nested language was not found in the language repository.");
- else
- {
- CompiledLanguage nestedCompiledLanguage = languageCompiler.Compile(nestedLanguage);
- Match regexMatch = nestedCompiledLanguage.Regex.Match(regexCapture.Value, 0, regexCapture.Value.Length);
- if (!regexMatch.Success)
- return;
- else
- {
- while (regexMatch.Success)
- {
- List<Scope> capturedStylesForMatchedFragment = GetCapturedStyles(regexMatch, 0, nestedCompiledLanguage);
- List<Scope> capturedStyleTree = CreateCapturedStyleTree(capturedStylesForMatchedFragment);
- foreach (Scope nestedCapturedStyle in capturedStyleTree)
- {
- IncreaseCapturedStyleIndicies(capturedStyleTree, offset);
- capturedStyles.Add(nestedCapturedStyle);
- }
- regexMatch = regexMatch.NextMatch();
- }
- }
- }
- }
- private static void IncreaseCapturedStyleIndicies(IList<Scope> capturedStyles,
- int amountToIncrease)
- {
- for (int i = 0; i < capturedStyles.Count; i++)
- {
- Scope scope = capturedStyles[i];
- scope.Index += amountToIncrease;
- if (scope.Children.Count > 0)
- IncreaseCapturedStyleIndicies(scope.Children, amountToIncrease);
- }
- }
- }
- }