Version

Create Custom Language

Topic Overview

Purpose

This topic explains the process of creating a custom language.

Required background

The following topics are prerequisites to understanding this topic:

Topic Purpose

This topic provides an overview of the Syntax Parsing Engine.

This topic provides an overview of the Syntax Parsing Engine’s Grammar.

This topic gives an overview of the EBNF file format used to define a grammar.

This topic explains the process of creating a grammar from EBNF content.

Create Custom Language

Overview

Once a grammar definition is complete you can use it to parse documents which must conform to that grammatical structure. Here are the steps for doing this:

  • create a Grammar instance from the EBNF grammar definition or construct a Grammar instance with code

  • create a custom language class, which derives from LanguageBase and owns the Grammar instance

  • create a TextDocument and set its Language property to an instance of the custom language class

Note
Note

Once a Grammar is used to create a language, it can never be modified again. Trying to change the Grammar or any object directly or indirectly owned by the Grammar will throw an exception. A Grammar which has been used to create a language will have its IsMutable readonly property set to False.

There are two ways to create a custom language from a grammar:

Using the CustomLanguage class

You can create a custom language for a grammar by passing the Grammar instance to the constructor of the CustomLanguage class, which is derived from LanguageBase. This will create a CustomLanguage instance specifically built to parse documents based on the provided Grammar instance.

The following table contains the members that are publicly exposed on the CustomLanguage class:

Property * Description*

The Grammar instance used to create the instance.

An instance for managing services available to an editor when documents are edited in this language.

Event * Description*

Occurs when a global ambiguity is detected while parsing a document. For more information, please refer to the Ambiguities topic.

Generate a language class

You can create a custom language from a grammar by generating a LanguageBase-derived class specifically built to parse documents with a specific grammar definition. Creating a CustomLanguage can be thought of as dynamic creation of a language whereas generating a language class can be thought of as pre-compiling a language. Building the lexical and syntax analyzers can be slow for complex grammars. If the CustomLanguage approach is used, that building phase needs to happen the first time a document is parsed for each run of the application. This may be acceptable for simple languages or when debugging a grammar definition on a developer’s machine, but for a complex language being used on a user’s machine, it may not be. By using the language generation approach, the lexical and syntax analyzers are built once on the developer’s machine. Then information about how to reconstruct the analyzers and Grammar is written out to a generated class file. Each class file generated derives from LanguageBase, has a static property named Instance returning a singleton instance of itself, and a public constructor in case two copies of the language need to be created with different services in their ServicesManager. In addition, the generated class has a Grammar property which returns an identical copy of the Grammar used to generate the language.

Note
Note

Although the Grammar property returns a copy of the original Grammar, accessing the Grammar property on different instances of the same generated language type will always return the same Grammar instance.

One of the options for generating the language class is to give it the “partial” modifier. This allows you to create another file for the derived language so you can override certain members on LanguageBase or add your own. The members that can be overridden on LanguageBase are as follows

Protected Virtual Method * Description*

Returns a string containing a display name for the symbol when used in error messages. For more information please refer to the Customize Error Messages topic.

Initializes the default services in the ServicesManager for the language.

Called when the syntax analyzer discovers an error. For more information please refer to the Customize Error Messages topic.

Called when a global ambiguity is detected when parsing text. For more information, please refer to the Ambiguities topic.

You can generate a language by using the LanguageGenerator class in the Infragistics.Documents.Parsing namespace. This class has the following static methods:

Static Method * Description*

Generates a language file using the specified options and returns the string containing the content of the file.

Generates a language file using the specified options and writes it to the specified stream.

The LanguageGenerationParams class used as argument in the GenerateClass methods has several options to customize the language generation process. They are as follows:

Property * Description*

The name to give the generated language class.

Indicates in which coding language the class file should be generated. Available values are

  • CSharp

  • VisualBasic

The value is CSharp by default.

Indicates whether to generate a nested SymbolNames class in the generated language which contains constants for the names of all symbol which could have nodes represent them in the syntax tree (symbols which will always be pruned out of the syntax tree will not have symbol name constants generated). The value is true by default.

The Grammar instance which will be used to generate the class.

Indicates whether the "partial" modifier should be added to the class. The value is false by default.

Indicates whether the “public” modifier should be added to the class. If false, the “internal” modifier will be added instead. The value is true by default.

Indicates whether the “sealed” modifier should be added to the class. The value is true by default.

The namespace in which to place the generated language class. If null, it will be placed in the Infragistics.Documents.Parsing namespace.

The documentation summary comment to add to the class.

Related Content

Topics

The following topics provide additional information related to this topic.

Topic Purpose

This topic explains how to customize the error messages produced by the Syntax Parsing Engine.

This topic introduces the TextDocument and explains how to set a language on the TextDocument.

The topics in this group explain in detail how to work with the Syntax Tree.