title |
---|
4. Lexer and Parser Definition |
The lexical analyzer defines how the contents of a file are broken into tokens, which is the basis for supporting custom language features. The easiest way to create a lexer is to use JFlex.
Reference: Implementing Lexer
- bullet item {:toc}
The previous tutorial step Grammar and Parser, and this page, generate source files in the directory src/main/gen
.
To include those files, the project's sourceSets
must be expanded by inserting the following line in the project's build.gradle
file:
sourceSets.main.java.srcDirs 'src/main/gen'
Or the following line in the project's build.gradle.kts
file:
sourceSets["main"].java.srcDirs("src/main/gen")
Define a Simple.flex
file with rules for the Simple Language lexer, as demonstrated in org.intellij.sdk.language.Simple.flex
.
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/Simple.flex %}
Now generate a lexer class via JFlex Generator from the context menu on Simple.flex
file.
The Grammar-Kit plugin uses the JFlex lexer generation.
When running for the first time, JFlex prompts for a destination folder to download the JFlex library and skeleton.
Choose the project root directory, for example code_samples/simple_language_plugin
.
After that, the IDE generates the lexer under the gen
directory, for example in simple_language_plugin/src/main/gen/org/intellij/sdk/language/SimpleLexer
.
TIP Gradle plugin gradle-grammarkit-plugin can be used alternatively.
See Implementing Lexer for more information about using JFlex with the IntelliJ Platform.
The JFlex lexer needs to be adapted to the IntelliJ Platform Lexer API.
This is done by subclassing FlexAdapter
.
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLexerAdapter.java %}
The SimpleFile
implementation is the top-level node of the tree of PsiElements
for a Simple Language file.
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleFile.java %}
The Simple Language parser is defined by subclassing ParserDefinition
.
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleParserDefinition.java %}
Registering the parser definition in the plugin.xml
file makes it available to the IntelliJ Platform.
Use the com.intellij.lang.parserDefinition
extension point for registration.
For example, see simple_language_plugin/src/main/resources/META-INF/plugin.xml
.
<extensions defaultExtensionNs="com.intellij">
<lang.parserDefinition language="Simple"
implementationClass="org.intellij.sdk.language.SimpleParserDefinition"/>
</extensions>
With the simple_language_plugin
loaded in a Development Instance, create a test.simple
properties file with the following content:
# You are reading the ".properties" entry.
! The exclamation mark can also mark text as comments.
website = https://en.wikipedia.org/
language = English
# The backslash below tells the application to continue reading
# the value onto the next line.
message = Welcome to \
Wikipedia!
# Add spaces to the key
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
# Unicode
tab : \u0009
Now open the PsiViewer tool window and check how the lexer breaks the content of the file into tokens, and the parser parsed the tokens into PSI elements.