/// <summary> /// Loads two languages and creates a state transition from XML to C# within ASP-style directives. /// </summary> private void CreateDirectiveXmlToCSharpLanguage() { string outputSyntaxFilePath = Slyce.Common.SyntaxEditorHelper.GetLanguageFileName(TemplateContentLanguage.PlainText); string scriptSyntaxFilePath = Slyce.Common.SyntaxEditorHelper.GetLanguageFileName(TemplateContentLanguage.CSharp); if (!File.Exists(outputSyntaxFilePath)) { MessageBox.Show(this, "Language syntax file could not be loaded: " + outputSyntaxFilePath); return; } if (!File.Exists(scriptSyntaxFilePath)) { MessageBox.Show(this, "Language syntax file could not be loaded: " + scriptSyntaxFilePath); return; } DynamicSyntaxLanguage language = DynamicSyntaxLanguage.LoadFromXml(outputSyntaxFilePath, 0); DynamicSyntaxLanguage cSharpLanguage = DynamicSyntaxLanguage.LoadFromXml(scriptSyntaxFilePath, 0); cSharpLanguage.DefaultLexicalState.DefaultHighlightingStyle.ForeColor = Color.Red; language.Tag = "TemplateLanguage"; cSharpLanguage.Tag = "ScriptLanguage"; // Mark that updating is starting language.IsUpdating = true; cSharpLanguage.IsUpdating = true; // Add a highlighting style language.HighlightingStyles.Add(new HighlightingStyle("ASPDirectiveDelimiterStyle", null, Color.Black, Color.Yellow)); // Create a new lexical state DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ASPDirectiveState"); lexicalState.DefaultTokenKey = "ASPDirectiveDefaultToken"; lexicalState.DefaultHighlightingStyle = language.HighlightingStyles["DefaultStyle"]; lexicalState.LexicalStateTransitionLexicalState = cSharpLanguage.LexicalStates["DefaultState"]; language.LexicalStates.Add(lexicalState); // Add the new lexical state at the beginning of the child states... // Remember that with an NFA regular expression, the first match is taken... // So since a < scope pattern is already in place, we must insert the new one before it language.LexicalStates["DefaultState"].ChildLexicalStates.Insert(0, lexicalState); // Create a lexical scope with a lexical state transition DynamicLexicalScope lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalScope.StartLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveStartToken", language.HighlightingStyles["ASPDirectiveDelimiterStyle"], "#"); lexicalScope.EndLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveEndToken", language.HighlightingStyles["ASPDirectiveDelimiterStyle"], "#"); // Mark that updating is complete (since linking is complete, the flag setting // will filter from the XML language into the C# language) language.IsUpdating = false; syntaxEditorFilename.Document.Language = language; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Initializes a new instance of the <see cref="ASPStyleTransitionSyntaxLanguage"/> class. /// </summary> public TagStyleTransitionSyntaxLanguage() : base("Xml") { // Initialize this root language with the XML language definition ActiproSoftware.ProductSamples.SyntaxEditorSamples.Common.SyntaxEditorHelper.InitializeLanguageFromResourceStream(this, "Xml.langdef"); // Load the C# child language ISyntaxLanguage cSharpLanguage = ActiproSoftware.ProductSamples.SyntaxEditorSamples.Common.SyntaxEditorHelper.LoadLanguageDefinitionFromResourceStream("CSharp.langdef"); // Get the lexer for the parent language DynamicLexer parentLexer = this.GetLexer() as DynamicLexer; // Get the lexer for the child language DynamicLexer childLexer = cSharpLanguage.GetLexer() as DynamicLexer; // Get the classification types that will be used (they were already registered by the XML language load) IClassificationType xmlNameClassificationType = AmbientHighlightingStyleRegistry.Instance["XmlName"]; IClassificationType xmlDelimiterClassificationType = AmbientHighlightingStyleRegistry.Instance["XmlDelimiter"]; // Since we will be dynamically modifying the parent lexer, wrap it with a change batch using (IDisposable batch = parentLexer.CreateChangeBatch()) { // Create a new transition lexical state in the parent language that will serve as the bridge between the two languages... // Add child states similar to the XML's 'StartTag' state so that attributes are allowed in the 'script' tag DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ScriptStartTag"); lexicalState.DefaultTokenKey = "StartTagText"; lexicalState.DefaultClassificationType = xmlNameClassificationType; lexicalState.ChildLexicalStates.Add(parentLexer.LexicalStates["StartTagAttributeDoubleQuoteValue"]); lexicalState.ChildLexicalStates.Add(parentLexer.LexicalStates["StartTagAttributeSingleQuoteValue"]); parentLexer.LexicalStates.Add(lexicalState); // Insert the transition lexical state at the beginning of the parent language's // default state's child states list so that it has top matching priority parentLexer.DefaultLexicalState.ChildLexicalStates.Insert(0, lexicalState); // Create the lexical scope for the transition lexical state DynamicLexicalScope lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalScope.StartLexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "StartTagStartDelimiter", xmlDelimiterClassificationType); lexicalScope.StartLexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(@"<")); lexicalScope.StartLexicalPatternGroup.LookAheadPattern = @"script"; lexicalScope.EndLexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "StartTagEndDelimiter", xmlDelimiterClassificationType); lexicalScope.EndLexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(@"/? >")); // Create a second lexical scope that will be transitioned into as soon as the first lexical scope // is exited (after the '<script>' tag)... this second scope indicates the child language's // lexical state to transition into along with the pattern group that will be used to exit // back out to the parent language DynamicLexicalScope transitionLexicalScope = new DynamicLexicalScope(); transitionLexicalScope.EndLexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "EndTagStartDelimiter", xmlDelimiterClassificationType); transitionLexicalScope.EndLexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(@"</")); transitionLexicalScope.EndLexicalPatternGroup.LookAheadPattern = @"script"; lexicalScope.Transition = new LexicalStateTransition(cSharpLanguage, childLexer.DefaultLexicalState, transitionLexicalScope); } }
///////////////////////////////////////////////////////////////////////////////////////////////////// // OBJECT ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Initializes a new instance of the <see cref="AspStyleTransitionSyntaxLanguage"/> class. /// </summary> public AspStyleTransitionSyntaxLanguage() : base("Xml") { // Initialize this root language with the XML language definition ActiproSoftware.ProductSamples.SyntaxEditorSamples.Common.SyntaxEditorHelper.InitializeLanguageFromResourceStream(this, "Xml.langdef"); // Load the C# child language ISyntaxLanguage cSharpLanguage = ActiproSoftware.ProductSamples.SyntaxEditorSamples.Common.SyntaxEditorHelper.LoadLanguageDefinitionFromResourceStream("CSharp.langdef"); // Get the lexer for the parent language DynamicLexer parentLexer = this.GetLexer() as DynamicLexer; // Get the lexer for the child language DynamicLexer childLexer = cSharpLanguage.GetLexer() as DynamicLexer; // Get the classification types that will be used (create and register if necessary) IClassificationType serverSideScriptClassificationType = AmbientHighlightingStyleRegistry.Instance["ServerSideScript"]; if (serverSideScriptClassificationType == null) { serverSideScriptClassificationType = new ClassificationType("ServerSideScript", "Server-Side Script"); AmbientHighlightingStyleRegistry.Instance.Register(serverSideScriptClassificationType, new HighlightingStyle(Colors.Black, Color.FromArgb(0xff, 0xff, 0xee, 0x62))); } // Since we will be dynamically modifying the parent lexer, wrap it with a change batch using (IDisposable batch = parentLexer.CreateChangeBatch()) { // Create a new transition lexical state in the parent language that will serve as the bridge between the two languages DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ASPDirective"); lexicalState.DefaultTokenKey = "ASPDirectiveText"; parentLexer.LexicalStates.Add(lexicalState); // Insert the transition lexical state at the beginning of the parent language's // default state's child states list so that it has top matching priority parentLexer.DefaultLexicalState.ChildLexicalStates.Insert(0, lexicalState); // Create the lexical scope for the transition lexical state DynamicLexicalScope lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalScope.StartLexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "ASPDirectiveStartDelimiter", serverSideScriptClassificationType); lexicalScope.StartLexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(@"<%")); lexicalScope.EndLexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "ASPDirectiveEndDelimiter", serverSideScriptClassificationType); lexicalScope.EndLexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(@"%>")); // Set up a direct transition on the lexical state so that when it is entered, // it will transition directly to the child language's default lexical state lexicalState.Transition = new LexicalStateTransition(cSharpLanguage, childLexer.DefaultLexicalState, null); } }
/// <summary> /// Initializes a new instance of the <c>JsonLexer</c> class. /// </summary> /// <param name="classificationTypeProvider">A <see cref="IJsonClassificationTypeProvider"/> that provides classification types used by this lexer.</param> public JsonLexer(IJsonClassificationTypeProvider classificationTypeProvider) { if ((classificationTypeProvider == null)) { throw new ArgumentNullException("classificationTypeProvider"); } // Create lexical states IKeyedObservableCollection <DynamicLexicalState> lexicalStates = ((IKeyedObservableCollection <DynamicLexicalState>)(this.LexicalStates)); this.DefaultLexicalState.Id = JsonLexicalStateId.Default; lexicalStates.Add(new DynamicLexicalState(JsonLexicalStateId.PrimaryString, "PrimaryString")); DynamicLexicalState lexicalState = null; DynamicLexicalScope lexicalScope = null; DynamicLexicalPatternGroup lexicalPatternGroup = null; // Initialize the Default lexical state lexicalState = lexicalStates["Default"]; lexicalState.ChildLexicalStates.Add(lexicalStates["PrimaryString"]); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Whitespace", null); lexicalPatternGroup.TokenId = JsonTokenId.Whitespace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{LineTerminatorWhitespace}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Comma", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.Comma; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(",")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Colon", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.Colon; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(":")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "OpenCurlyBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.OpenCurlyBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "CloseCurlyBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.CloseCurlyBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("}")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "OpenSquareBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.OpenSquareBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "CloseSquareBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.CloseSquareBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("]")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "True", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = JsonTokenId.True; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.AutoCorrect; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("true")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "False", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = JsonTokenId.False; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.AutoCorrect; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("false")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Null", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = JsonTokenId.Null; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.AutoCorrect; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("null")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Number", classificationTypeProvider.Number); lexicalPatternGroup.TokenId = JsonTokenId.Number; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]?{Digit}* \\. {Digit}+ ([Ee] [\\+\\-]? {Digit}+)?")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]?{Digit}+ [Ee] [\\+\\-]? {Digit}+")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]?{Digit}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); // Initialize the PrimaryString lexical state lexicalState = lexicalStates["PrimaryString"]; lexicalState.DefaultClassificationType = classificationTypeProvider.String; lexicalState.DefaultTokenId = JsonTokenId.PrimaryStringText; lexicalState.DefaultTokenKey = "PrimaryStringText"; lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "StringStartDelimiter", null); lexicalPatternGroup.TokenId = JsonTokenId.StringStartDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\"")); lexicalScope.StartLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "StringEndDelimiter", null); lexicalPatternGroup.TokenId = JsonTokenId.StringEndDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\"")); lexicalScope.EndLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "EscapedCharacter", null); lexicalPatternGroup.TokenId = JsonTokenId.EscapedCharacter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\\"")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\\\")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\/")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\b")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\f")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\n")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\r")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\t")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "EscapedUnicode", null); lexicalPatternGroup.TokenId = JsonTokenId.EscapedUnicode; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\\\u[0-9a-fA-F]{4}")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "StringText", null); lexicalPatternGroup.TokenId = JsonTokenId.StringText; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[^\\\"\\\\\\n]+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); }
/// <summary> /// Initializes a new instance of the <c>JsonLexer</c> class. /// </summary> /// <param name="classificationTypeProvider">A <see cref="IJsonClassificationTypeProvider"/> that provides classification types used by this lexer.</param> public JsonLexer(IJsonClassificationTypeProvider classificationTypeProvider) { if ((classificationTypeProvider == null)) { throw new ArgumentNullException("classificationTypeProvider"); } // Create lexical states IKeyedObservableCollection<DynamicLexicalState> lexicalStates = ((IKeyedObservableCollection<DynamicLexicalState>)(this.LexicalStates)); this.DefaultLexicalState.Id = JsonLexicalStateId.Default; lexicalStates.Add(new DynamicLexicalState(JsonLexicalStateId.PrimaryString, "PrimaryString")); DynamicLexicalState lexicalState = null; DynamicLexicalScope lexicalScope = null; DynamicLexicalPatternGroup lexicalPatternGroup = null; // Initialize the Default lexical state lexicalState = lexicalStates["Default"]; lexicalState.ChildLexicalStates.Add(lexicalStates["PrimaryString"]); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Whitespace", null); lexicalPatternGroup.TokenId = JsonTokenId.Whitespace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{LineTerminatorWhitespace}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Comma", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.Comma; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(",")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Colon", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.Colon; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(":")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "OpenCurlyBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.OpenCurlyBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "CloseCurlyBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.CloseCurlyBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("}")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "OpenSquareBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.OpenSquareBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "CloseSquareBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = JsonTokenId.CloseSquareBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("]")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "True", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = JsonTokenId.True; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.AutoCorrect; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("true")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "False", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = JsonTokenId.False; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.AutoCorrect; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("false")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Null", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = JsonTokenId.Null; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.AutoCorrect; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("null")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Number", classificationTypeProvider.Number); lexicalPatternGroup.TokenId = JsonTokenId.Number; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]?{Digit}* \\. {Digit}+ ([Ee] [\\+\\-]? {Digit}+)?")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]?{Digit}+ [Ee] [\\+\\-]? {Digit}+")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]?{Digit}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); // Initialize the PrimaryString lexical state lexicalState = lexicalStates["PrimaryString"]; lexicalState.DefaultClassificationType = classificationTypeProvider.String; lexicalState.DefaultTokenId = JsonTokenId.PrimaryStringText; lexicalState.DefaultTokenKey = "PrimaryStringText"; lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "StringStartDelimiter", null); lexicalPatternGroup.TokenId = JsonTokenId.StringStartDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\"")); lexicalScope.StartLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "StringEndDelimiter", null); lexicalPatternGroup.TokenId = JsonTokenId.StringEndDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\"")); lexicalScope.EndLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "EscapedCharacter", null); lexicalPatternGroup.TokenId = JsonTokenId.EscapedCharacter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\\"")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\\\")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\/")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\b")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\f")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\n")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\r")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\t")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "EscapedUnicode", null); lexicalPatternGroup.TokenId = JsonTokenId.EscapedUnicode; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\\\u[0-9a-fA-F]{4}")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "StringText", null); lexicalPatternGroup.TokenId = JsonTokenId.StringText; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[^\\\"\\\\\\n]+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); }
/// <summary> /// Loads two languages and creates a state transition from XML to C# within ASP-style directives. /// </summary> public static void SetupEditorTemplateAndScriptLanguages(SyntaxEditor editor, TemplateContentLanguage textLanguage, ScriptLanguageTypes scriptLanguage, string delimiterStart, string delimiterEnd) { DynamicSyntaxLanguage language = GetDynamicLanguage(textLanguage); DynamicSyntaxLanguage cSharpLanguage = GetDynamicLanguage(GetScriptingLanguage(scriptLanguage)); language.AutomaticOutliningBehavior = AutomaticOutliningBehavior.PostSemanticParse; cSharpLanguage.AutomaticOutliningBehavior = AutomaticOutliningBehavior.PostSemanticParse; language.Tag = "TemplateLanguage"; cSharpLanguage.Tag = "ScriptLanguage"; // Mark that updating is starting language.IsUpdating = true; cSharpLanguage.IsUpdating = true; // Add StateTransitions to current language as well nested languages eg: HTML -> JavaScript, VBScript etc. for (int i = 0; i <= language.ChildLanguages.Count; i++) { DynamicSyntaxLanguage lan; if (i == language.ChildLanguages.Count) { lan = language; } else { lan = (DynamicSyntaxLanguage)language.ChildLanguages[i]; } // Add a highlighting style lan.HighlightingStyles.Add(new HighlightingStyle("ASPDirectiveDelimiterStyle", null, Color.Black, ASP_DIRECTIVE_COLOUR)); lan.AutomaticOutliningBehavior = AutomaticOutliningBehavior.SemanticParseDataChange; // Create a new lexical state DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ASPDirectiveState"); lexicalState.DefaultTokenKey = "ASPDirectiveDefaultToken"; lexicalState.DefaultHighlightingStyle = lan.HighlightingStyles["DefaultStyle"]; lexicalState.LexicalStateTransitionLexicalState = cSharpLanguage.LexicalStates["DefaultState"]; lan.LexicalStates.Add(lexicalState); // Add the new lexical state at the beginning of the child states... // Remember that with an NFA regular expression, the first match is taken... // So since a < scope pattern is already in place, we must insert the new one before it lan.LexicalStates["DefaultState"].ChildLexicalStates.Insert(0, lexicalState); #region Extra Transition points - Eg: comments if (lan.LexicalStates.IndexOf("XMLCommentState") >= 0) // C# { lan.LexicalStates["XMLCommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("CommentState") >= 0) // C# { lan.LexicalStates["CommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StringState") >= 0) // SQL { // Note: Had to modify the RegexPatternGroup for StringState in ActiproSoftware.SQL.xml to: <RegexPatternGroup TokenKey="StringDefaultToken" PatternValue="[^<^']+" /> lan.LexicalStates["StringState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("SquareStringState") >= 0) // SQL { lan.LexicalStates["SquareStringState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("MultiLineCommentState") >= 0) // SQL { lan.LexicalStates["MultiLineCommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagState") >= 0) // HTML { lan.LexicalStates["StartTagState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagAttributeStringValueState") >= 0) // HTML { lan.LexicalStates["StartTagAttributeStringValueState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagAttributeState") >= 0) // HTML { lan.LexicalStates["StartTagAttributeState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagAttributeValueState") >= 0) // HTML { lan.LexicalStates["StartTagAttributeValueState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } // Create a lexical scope with a lexical state transition DynamicLexicalScope lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalScope.StartLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveStartToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterStart); lexicalScope.StartLexicalPatternGroup.LookBehindPattern = @"\\{2}|([^\\]|^)"; // @"\\{2}|[^\\]"; lexicalScope.EndLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveEndToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterEnd); lexicalScope.AncestorEndScopeCheckEnabled = false; } #endregion // Mark that updating is complete (since linking is complete, the flag setting // will filter from the XML language into the C# language) language.IsUpdating = false; editor.Document.Language = language; }
/// <summary> /// Initializes a new instance of the <c>PascalLexer</c> class. /// </summary> /// <param name="classificationTypeProvider">A <see cref="IPascalClassificationTypeProvider"/> that provides classification types used by this lexer.</param> public PascalLexer(IPascalClassificationTypeProvider classificationTypeProvider) { if ((classificationTypeProvider == null)) { throw new ArgumentNullException("classificationTypeProvider"); } // Create lexical macros this.LexicalMacros.Add(new DynamicLexicalMacro("Word", "[a-zA-Z0-9]")); this.LexicalMacros.Add(new DynamicLexicalMacro("NonWord", "[^a-zA-Z0-9]")); // Create lexical states IKeyedObservableCollection <DynamicLexicalState> lexicalStates = ((IKeyedObservableCollection <DynamicLexicalState>)(this.LexicalStates)); this.DefaultLexicalState.Id = PascalLexicalStateId.Default; lexicalStates.Add(new DynamicLexicalState(PascalLexicalStateId.PrimaryString, "PrimaryString")); lexicalStates.Add(new DynamicLexicalState(PascalLexicalStateId.MultiLineComment, "MultiLineComment")); DynamicLexicalState lexicalState = null; DynamicLexicalScope lexicalScope = null; DynamicLexicalPatternGroup lexicalPatternGroup = null; // Initialize the Default lexical state lexicalState = lexicalStates["Default"]; lexicalState.ChildLexicalStates.Add(lexicalStates["PrimaryString"]); lexicalState.ChildLexicalStates.Add(lexicalStates["MultiLineComment"]); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Whitespace", null); lexicalPatternGroup.TokenId = PascalTokenId.Whitespace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{Whitespace}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "LineTerminator", null); lexicalPatternGroup.TokenId = PascalTokenId.LineTerminator; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{LineTerminator}")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "OpenParenthesis", null); lexicalPatternGroup.TokenId = PascalTokenId.OpenParenthesis; lexicalPatternGroup.LookAheadPattern = "$|[^\\*\\.]"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("(")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "CloseParenthesis", null); lexicalPatternGroup.TokenId = PascalTokenId.CloseParenthesis; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(")")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "OpenSquareBrace", null); lexicalPatternGroup.TokenId = PascalTokenId.OpenSquareBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\[")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\(\\.")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "CloseSquareBrace", null); lexicalPatternGroup.TokenId = PascalTokenId.CloseSquareBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\]")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\.\\)")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Punctuation", null); lexicalPatternGroup.TokenId = PascalTokenId.Punctuation; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(".. . , : ; ^ @")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Keyword", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = PascalTokenId.Keyword; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.Sensitive; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("and")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("array")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("begin")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("case")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("const")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("div")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("downto")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("do")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("else")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("end")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("file")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("for")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("function")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("goto")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("if")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("in")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("label")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("mod")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("nil")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("not")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("of")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("or")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("packed")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("procedure")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("program")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("record")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("repeat")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("set")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("then")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("to")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("type")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("until")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("var")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("while")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("with")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Identifier", classificationTypeProvider.Identifier); lexicalPatternGroup.TokenId = PascalTokenId.Identifier; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{Alpha}({Word})*")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Operator", classificationTypeProvider.Operator); lexicalPatternGroup.TokenId = PascalTokenId.Operator; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("*")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("+")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("-")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("/")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(":=")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("<=")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("<>")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("<")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("=")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(">=")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(">")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "RealNumber", classificationTypeProvider.Number); lexicalPatternGroup.TokenId = PascalTokenId.RealNumber; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]? {Digit}+ \\. {Digit}+ (e [\\+\\-]? {Digit}+)?")); lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]? {Digit}+ e [\\+\\-]? {Digit}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "IntegerNumber", classificationTypeProvider.Number); lexicalPatternGroup.TokenId = PascalTokenId.IntegerNumber; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[\\+\\-]? {Digit}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); // Initialize the PrimaryString lexical state lexicalState = lexicalStates["PrimaryString"]; lexicalState.DefaultClassificationType = classificationTypeProvider.String; lexicalState.DefaultTokenId = PascalTokenId.PrimaryStringText; lexicalState.DefaultTokenKey = "PrimaryStringText"; lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "PrimaryStringStartDelimiter", null); lexicalPatternGroup.TokenId = PascalTokenId.PrimaryStringStartDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\"")); lexicalScope.StartLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "PrimaryStringEndDelimiter", null); lexicalPatternGroup.TokenId = PascalTokenId.PrimaryStringEndDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("((?<!\\\\)\\\"|\\n)")); lexicalScope.EndLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "PrimaryStringEscapedDelimiter", null); lexicalPatternGroup.TokenId = PascalTokenId.PrimaryStringEscapedDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\"\"")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "PrimaryStringText", null); lexicalPatternGroup.TokenId = PascalTokenId.PrimaryStringText; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("(\\\\\"|[^\"\\n])+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); // Initialize the MultiLineComment lexical state lexicalState = lexicalStates["MultiLineComment"]; lexicalState.DefaultClassificationType = classificationTypeProvider.Comment; lexicalState.DefaultTokenId = PascalTokenId.MultiLineCommentText; lexicalState.DefaultTokenKey = "MultiLineCommentText"; lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "MultiLineCommentStartDelimiter", null); lexicalPatternGroup.TokenId = PascalTokenId.MultiLineCommentStartDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{")); lexicalScope.StartLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "MultiLineCommentEndDelimiter", null); lexicalPatternGroup.TokenId = PascalTokenId.MultiLineCommentEndDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("}")); lexicalScope.EndLexicalPatternGroup = lexicalPatternGroup; lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "MultiLineCommentStartDelimiter", null); lexicalPatternGroup.TokenId = PascalTokenId.MultiLineCommentStartDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("(*")); lexicalScope.StartLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "MultiLineCommentEndDelimiter", null); lexicalPatternGroup.TokenId = PascalTokenId.MultiLineCommentEndDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("*)")); lexicalScope.EndLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "MultiLineCommentLineTerminator", null); lexicalPatternGroup.TokenId = PascalTokenId.MultiLineCommentLineTerminator; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\n")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "MultiLineCommentText", null); lexicalPatternGroup.TokenId = PascalTokenId.MultiLineCommentText; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[^\\}\\*\\n]+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); }
/// <summary> /// Initializes a new instance of the <c>SimpleLexer</c> class. /// </summary> /// <param name="classificationTypeProvider">A <see cref="ISimpleClassificationTypeProvider"/> that provides classification types used by this lexer.</param> public SimpleLexer(ISimpleClassificationTypeProvider classificationTypeProvider) { if ((classificationTypeProvider == null)) { throw new ArgumentNullException("classificationTypeProvider"); } // Create lexical states IKeyedObservableCollection <DynamicLexicalState> lexicalStates = ((IKeyedObservableCollection <DynamicLexicalState>)(this.LexicalStates)); this.DefaultLexicalState.Id = SimpleLexicalStateId.Default; lexicalStates.Add(new DynamicLexicalState(SimpleLexicalStateId.SingleLineComment, "SingleLineComment")); lexicalStates.Add(new DynamicLexicalState(SimpleLexicalStateId.MultiLineComment, "MultiLineComment")); DynamicLexicalState lexicalState = null; DynamicLexicalScope lexicalScope = null; DynamicLexicalPatternGroup lexicalPatternGroup = null; // Initialize the Default lexical state lexicalState = lexicalStates["Default"]; lexicalState.ChildLexicalStates.Add(lexicalStates["SingleLineComment"]); lexicalState.ChildLexicalStates.Add(lexicalStates["MultiLineComment"]); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Whitespace", null); lexicalPatternGroup.TokenId = SimpleTokenId.Whitespace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{LineTerminatorWhitespace}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "OpenParenthesis", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = SimpleTokenId.OpenParenthesis; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("(")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "CloseParenthesis", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = SimpleTokenId.CloseParenthesis; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(")")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "OpenCurlyBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = SimpleTokenId.OpenCurlyBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "CloseCurlyBrace", classificationTypeProvider.Delimiter); lexicalPatternGroup.TokenId = SimpleTokenId.CloseCurlyBrace; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("}")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Function", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = SimpleTokenId.Function; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.Sensitive; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("function")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Return", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = SimpleTokenId.Return; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.Sensitive; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("return")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Var", classificationTypeProvider.Keyword); lexicalPatternGroup.TokenId = SimpleTokenId.Var; lexicalPatternGroup.CaseSensitivity = CaseSensitivity.Sensitive; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("var")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Identifier", classificationTypeProvider.Identifier); lexicalPatternGroup.TokenId = SimpleTokenId.Identifier; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("(_ | {Alpha})({Word})*")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Equality", null); lexicalPatternGroup.TokenId = SimpleTokenId.Equality; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("==")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Inequality", null); lexicalPatternGroup.TokenId = SimpleTokenId.Inequality; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("!=")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Assignment", null); lexicalPatternGroup.TokenId = SimpleTokenId.Assignment; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("=")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Addition", null); lexicalPatternGroup.TokenId = SimpleTokenId.Addition; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Subtraction", null); lexicalPatternGroup.TokenId = SimpleTokenId.Subtraction; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("-")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Multiplication", null); lexicalPatternGroup.TokenId = SimpleTokenId.Multiplication; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("*")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Division", null); lexicalPatternGroup.TokenId = SimpleTokenId.Division; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("/")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "Comma", null); lexicalPatternGroup.TokenId = SimpleTokenId.Comma; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(",")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "SemiColon", null); lexicalPatternGroup.TokenId = SimpleTokenId.SemiColon; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern(";")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Number", classificationTypeProvider.Number); lexicalPatternGroup.TokenId = SimpleTokenId.Number; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{Digit}* \\. {Digit}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "Number", classificationTypeProvider.Number); lexicalPatternGroup.TokenId = SimpleTokenId.Number; lexicalPatternGroup.LookAheadPattern = "{NonWord}|\\z"; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("{Digit}+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); // Initialize the SingleLineComment lexical state lexicalState = lexicalStates["SingleLineComment"]; lexicalState.DefaultClassificationType = classificationTypeProvider.Comment; lexicalState.DefaultTokenId = SimpleTokenId.SingleLineCommentText; lexicalState.DefaultTokenKey = "SingleLineCommentText"; lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "SingleLineCommentStartDelimiter", null); lexicalPatternGroup.TokenId = SimpleTokenId.SingleLineCommentStartDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("//")); lexicalScope.StartLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "SingleLineCommentEndDelimiter", null); lexicalPatternGroup.TokenId = SimpleTokenId.SingleLineCommentEndDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\n")); lexicalScope.EndLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "SingleLineCommentText", null); lexicalPatternGroup.TokenId = SimpleTokenId.SingleLineCommentText; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[^\\n]+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); // Initialize the MultiLineComment lexical state lexicalState = lexicalStates["MultiLineComment"]; lexicalState.DefaultClassificationType = classificationTypeProvider.Comment; lexicalState.DefaultTokenId = SimpleTokenId.MultiLineCommentText; lexicalState.DefaultTokenKey = "MultiLineCommentText"; lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "MultiLineCommentStartDelimiter", null); lexicalPatternGroup.TokenId = SimpleTokenId.MultiLineCommentStartDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("/*")); lexicalScope.StartLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Explicit, "MultiLineCommentEndDelimiter", null); lexicalPatternGroup.TokenId = SimpleTokenId.MultiLineCommentEndDelimiter; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("*/")); lexicalScope.EndLexicalPatternGroup = lexicalPatternGroup; lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "MultiLineCommentLineTerminator", null); lexicalPatternGroup.TokenId = SimpleTokenId.MultiLineCommentLineTerminator; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("\\n")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); lexicalPatternGroup = new DynamicLexicalPatternGroup(DynamicLexicalPatternType.Regex, "MultiLineCommentText", null); lexicalPatternGroup.TokenId = SimpleTokenId.MultiLineCommentText; lexicalPatternGroup.Patterns.Add(new DynamicLexicalPattern("[^\\*\\n]+")); lexicalState.LexicalPatternGroups.Add(lexicalPatternGroup); }
/// <summary> /// Loads two languages and creates a state transition from XML to C# within ASP-style directives. /// </summary> public static void SetupEditorTemplateAndScriptLanguages(SyntaxEditor editor, TemplateContentLanguage textLanguage, ScriptLanguageTypes scriptLanguage, string delimiterStart, string delimiterEnd) { DynamicSyntaxLanguage language = GetDynamicLanguage(textLanguage); DynamicSyntaxLanguage cSharpLanguage = GetDynamicLanguage(GetScriptingLanguage(scriptLanguage)); language.AutomaticOutliningBehavior = AutomaticOutliningBehavior.PostSemanticParse; cSharpLanguage.AutomaticOutliningBehavior = AutomaticOutliningBehavior.PostSemanticParse; language.Tag = "TemplateLanguage"; cSharpLanguage.Tag = "ScriptLanguage"; // Mark that updating is starting language.IsUpdating = true; cSharpLanguage.IsUpdating = true; // Add StateTransitions to current language as well nested languages eg: HTML -> JavaScript, VBScript etc. for (int i = 0; i <= language.ChildLanguages.Count; i++) { DynamicSyntaxLanguage lan; if (i == language.ChildLanguages.Count) { lan = language; } else { lan = (DynamicSyntaxLanguage)language.ChildLanguages[i]; } // Add a highlighting style lan.HighlightingStyles.Add(new HighlightingStyle("ASPDirectiveDelimiterStyle", null, Color.Black, ASP_DIRECTIVE_COLOUR)); lan.AutomaticOutliningBehavior = AutomaticOutliningBehavior.SemanticParseDataChange; // Create a new lexical state DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ASPDirectiveState"); lexicalState.DefaultTokenKey = "ASPDirectiveDefaultToken"; lexicalState.DefaultHighlightingStyle = lan.HighlightingStyles["DefaultStyle"]; lexicalState.LexicalStateTransitionLexicalState = cSharpLanguage.LexicalStates["DefaultState"]; lan.LexicalStates.Add(lexicalState); // Add the new lexical state at the beginning of the child states... // Remember that with an NFA regular expression, the first match is taken... // So since a < scope pattern is already in place, we must insert the new one before it lan.LexicalStates["DefaultState"].ChildLexicalStates.Insert(0, lexicalState); #region Extra Transition points - Eg: comments if (lan.LexicalStates.IndexOf("XMLCommentState") >= 0) // C# { lan.LexicalStates["XMLCommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("CommentState") >= 0) // C# { lan.LexicalStates["CommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StringState") >= 0) // SQL { // Note: Had to modify the RegexPatternGroup for StringState in ActiproSoftware.SQL.xml to: <RegexPatternGroup TokenKey="StringDefaultToken" PatternValue="[^<^']+" /> lan.LexicalStates["StringState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("SquareStringState") >= 0) // SQL { lan.LexicalStates["SquareStringState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("MultiLineCommentState") >= 0) // SQL { lan.LexicalStates["MultiLineCommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagState") >= 0) // HTML { lan.LexicalStates["StartTagState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagAttributeStringValueState") >= 0) // HTML { lan.LexicalStates["StartTagAttributeStringValueState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagAttributeState") >= 0) // HTML { lan.LexicalStates["StartTagAttributeState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } if (lan.LexicalStates.IndexOf("StartTagAttributeValueState") >= 0) // HTML { lan.LexicalStates["StartTagAttributeValueState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments } // Create a lexical scope with a lexical state transition DynamicLexicalScope lexicalScope = new DynamicLexicalScope(); lexicalState.LexicalScopes.Add(lexicalScope); lexicalScope.StartLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveStartToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterStart); lexicalScope.StartLexicalPatternGroup.LookBehindPattern = @"\\{2}|([^\\]|^)";// @"\\{2}|[^\\]"; lexicalScope.EndLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveEndToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterEnd); lexicalScope.AncestorEndScopeCheckEnabled = false; } #endregion // Mark that updating is complete (since linking is complete, the flag setting // will filter from the XML language into the C# language) language.IsUpdating = false; editor.Document.Language = language; }