1

我是intellij插件写作的新手。我开始为我们的一种自定义语言编写一个 intellij 插件。我正在按照intellij 官方网站中给出的教程进行操作。我还从 github下载了他们的Grammar-Kit 存储库以了解代码库。

在编写我的插件时,我将 jflex 用于 Lexer,将 bnf 语法用于解析器。我发现很难实现一个词法分析器来向解析器发送正确的标记。

我在 Grammar-Kit 存储库中看到Lexer(用于 bnf)非常简单,它只识别字符串、数字、Id、空格、注释和特殊字符('('、'*' 等)。它确实无法识别 bnf 关键字,例如“private”、“external”、“meta”等。

现在,当我看到示例 bnf 文件的 PSI 树时,请说该行,

private myRule ::= '(' myExpression ')' ';'

如下,

BnfFile:Dummy.bnf(0,43)
  BNF_RULE:myRule(0,43)
    BNF_MODIFIER(0,7)
      PsiElement(id)('private')(0,7)
    PsiWhiteSpace(' ')(7,8)
    PsiElement(id)('myRule')(8,14)
    PsiWhiteSpace(' ')(14,15)
    PsiElement(::=)('::=')(15,18)
    PsiWhiteSpace(' ')(18,19)
    BNF_SEQUENCE: '(' myExpression ')' ';'(19,43)
      BNF_STRING_LITERAL_EXPRESSION: '('(19,22)
        PsiElement(string)(''('')(19,22)
      PsiWhiteSpace(' ')(22,23)
      BNF_REFERENCE_OR_TOKEN: myExpression(23,35)
        PsiElement(id)('myExpression')(23,35)
      PsiWhiteSpace(' ')(35,36)
      BNF_STRING_LITERAL_EXPRESSION: ')'(36,39)
        PsiElement(string)('')'')(36,39)
      PsiWhiteSpace(' ')(39,40)
      BNF_STRING_LITERAL_EXPRESSION: ';'(40,43)
        PsiElement(string)('';'')(40,43)

我在这里看到的是“私有”被 Lexer 识别PsiElement.id,之后一些代码用 BnfModifier 对象包装它,该对象被声明为 bnf文件。BNF_SEQUENCE、BNF_REFERENCE_OR_TOKEN、BNF_STRING_LITERAL_EXPRESSION 等也是如此。它们都不能被 Lexer 识别,但是一些代码用 bnf 文件声明的对象包装它们。

我想了解这种包装是如何在 Lexer 识别的标记之上完成的。它将帮助我识别 DSL 中的关键字并以不同的方式突出显示它们,自动完成它们等。

谢谢,

苏霍吉特

4

0 回答 0