IntelliJ Platform SDK DevGuide

4. Lexer and Parser Definition

词法分析器定义文件内容如何分解为令牌.

创建词法分析器的最简单方法是使用JFlex

4.1.

定义词法分析器

使用我们词法分析器的规则定义*/com/simpleplugin/Simple.flex *文件.

package com.simpleplugin; import com.intellij.lexer.FlexLexer; import com.intellij.psi.tree.IElementType; import com.simpleplugin.psi.SimpleTypes; import com.intellij.psi.TokenType; %% %class SimpleLexer %implements FlexLexer %unicode %function advance %type IElementType %eof{ return; %eof} CRLF=\R WHITE_SPACE=[\ \n\t\f] FIRST_VALUE_CHARACTER=[^ \n\f\\] | "\\"{CRLF} | "\\". VALUE_CHARACTER=[^\n\f\\] | "\\"{CRLF} | "\\". END_OF_LINE_COMMENT=("#"|"!")[^\r\n]* SEPARATOR=[:=] KEY_CHARACTER=[^:=\ \n\t\f\\] | "\\ " %state WAITING_VALUE %% <YYINITIAL> {END_OF_LINE_COMMENT} { yybegin(YYINITIAL); return SimpleTypes.COMMENT; } <YYINITIAL> {KEY_CHARACTER}+ { yybegin(YYINITIAL); return SimpleTypes.KEY; } <YYINITIAL> {SEPARATOR} { yybegin(WAITING_VALUE); return SimpleTypes.SEPARATOR; } <WAITING_VALUE> {CRLF}({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; } <WAITING_VALUE> {WHITE_SPACE}+ { yybegin(WAITING_VALUE); return TokenType.WHITE_SPACE; } <WAITING_VALUE> {FIRST_VALUE_CHARACTER}{VALUE_CHARACTER}* { yybegin(YYINITIAL); return SimpleTypes.VALUE; } ({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; } [^] { return TokenType.BAD_CHARACTER; }

4.2.

生成词法分类器

现在我们可以从Simple.flex文件的上下文菜单中通过* JFlex Generator *生成一个词法分析器类.

Grammar-Kit插件使用JFlex lexer生成.

如果您是第一次运行它,它会让您选择一个文件夹来下载JFlex库和骨架.

选择项目根目录.

之后,IDE生成词法分析器:* com.simpleplugin.SimpleLexer *.

4.3.

定义适配器

package com.simpleplugin; import com.intellij.lexer.FlexAdapter; import java.io.Reader; public class SimpleLexerAdapter extends FlexAdapter { public SimpleLexerAdapter() { super(new SimpleLexer((Reader) null)); } }

4.4.

定义根文件

com.simpleplugin.psi命名空间中创建类.

package com.simpleplugin.psi; import com.intellij.extapi.psi.PsiFileBase; import com.intellij.openapi.fileTypes.FileType; import com.intellij.psi.FileViewProvider; import com.simpleplugin.*; import org.jetbrains.annotations.NotNull; import javax.swing.*; public class SimpleFile extends PsiFileBase { public SimpleFile(@NotNull FileViewProvider viewProvider) { super(viewProvider, SimpleLanguage.INSTANCE); } @NotNull @Override public FileType getFileType() { return SimpleFileType.INSTANCE; } @Override public String toString() { return "Simple File"; } @Override public Icon getIcon(int flags) { return super.getIcon(flags); } }

4.5.

定义解析器定义

package com.simpleplugin; import com.intellij.lang.*; import com.intellij.lexer.Lexer; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.tree.*; import com.simpleplugin.parser.SimpleParser; import com.simpleplugin.psi.*; import org.jetbrains.annotations.NotNull; public class SimpleParserDefinition implements ParserDefinition { public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE); public static final TokenSet COMMENTS = TokenSet.create(SimpleTypes.COMMENT); public static final IFileElementType FILE = new IFileElementType(SimpleLanguage.INSTANCE); @NotNull @Override public Lexer createLexer(Project project) { return new SimpleLexerAdapter(); } @NotNull public TokenSet getWhitespaceTokens() { return WHITE_SPACES; } @NotNull public TokenSet getCommentTokens() { return COMMENTS; } @NotNull public TokenSet getStringLiteralElements() { return TokenSet.EMPTY; } @NotNull public PsiParser createParser(final Project project) { return new SimpleParser(); } @Override public IFileElementType getFileNodeType() { return FILE; } public PsiFile createFile(FileViewProvider viewProvider) { return new SimpleFile(viewProvider); } public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) { return SpaceRequirements.MAY; } @NotNull public PsiElement createElement(ASTNode node) { return SimpleTypes.Factory.createElement(node); } }

4.6.

注册解析器定义

<lang.parserDefinition language="Simple" implementationClass="com.simpleplugin.SimpleParserDefinition"/>

4.7.

运行该项目

使用以下内容创建属性文件:

# You are reading the ".properties" entry. ! The exclamation mark can also mark text as comments. website = http://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

现在打开* PsiViewer *工具窗口,检查词法分析器如何将文件内容分解为标记,解析器将标记解析为PSI元素.

PSI Elements

Last modified: 11 May 2019