Parsing IntelliJ:语法工具包/BNF:如何从错误中恢复?

Parsing IntelliJ:语法工具包/BNF:如何从错误中恢复?,parsing,intellij-idea,bnf,intellij-plugin,grammar-kit,Parsing,Intellij Idea,Bnf,Intellij Plugin,Grammar Kit,我正在为IntelliJ编写一个自定义语言插件 下面是该语言的一个简化示例。请注意,该结构是递归的: 我已经成功地实现了FLEX和BNF文件,但我不确定如何添加错误恢复。我已经在语法工具包的HOWTO中读到了RecoverWhile和pin,但我不知道如何将它们应用到我的场景中 我将上面的棕色项目称为(“aaa”、“ccc”等…)项目 我把黄色的称为“bbb”、“ddd”和“properties” 每个项目都有一个项目名称(如“aaa”)、一个单一属性(如“bbb”),并且可以包含其他项目(如

我正在为IntelliJ编写一个自定义语言插件

下面是该语言的一个简化示例。请注意,该结构是递归的:

我已经成功地实现了FLEX和BNF文件,但我不确定如何添加错误恢复。我已经在语法工具包的HOWTO中读到了RecoverWhile和pin,但我不知道如何将它们应用到我的场景中

我将上面的棕色项目称为(“aaa”、“ccc”等…)项目

我把黄色的称为“bbb”、“ddd”和“properties”

每个项目都有一个项目名称(如“aaa”)、一个单一属性(如“bbb”),并且可以包含其他项目(如“aaa”包含“ccc”、“eeee”和“gg”)

目前,当一个项目的格式不正确时,插件的表现并不好。例如:

在本例中,我希望解析器“理解”一点,即“ccc”是缺少属性的项的名称(例如,通过检测右括号前的换行符)

我不希望被破坏的“ccc”项影响“eeee”的解析(但我确实希望PSI树具有文本中存在的“ccc”元素,在本例中为其名称)

以下是我使用的FLEX和BNF:

弹性:


我最终能够让它像这样工作:

myLangFile ::= (item|COMMENT|CRLF)
item ::=
    itemName
    itemProperties
    itemBody?
itemName ::= TYPE_FLEX_WORD
itemProperties ::= TYPE_FLEX_OPEN_SQUARE_BRACKET [!TYPE_FLEX_CLOSE_SQUARE_BRACKET itemProperty ((TYPE_FLEX_SEMICOLON itemProperty)|itemProperty)*] TYPE_FLEX_CLOSE_SQUARE_BRACKET {
    pin(".*") = 1
}
itemProperty ::= TYPE_FLEX_WORD TYPE_FLEX_EQUALS? itemPropertyValue? (TYPE_FLEX_EQUALS prv_swallowNextPropertyToPreventSyntaxErrors)?
private prv_swallowNextPropertyToPreventSyntaxErrors ::= TYPE_FLEX_WORD
itemPropertyValue ::= TYPE_FLEX_WORD
itemBody ::= TYPE_FLEX_OPEN_CURLY_BRACKET item* TYPE_FLEX_CLOSE_CURLY_BRACKET
它并不完美;例如,它允许使用空格(不仅仅是分号)分隔项目属性,但它似乎解决了更重要的问题


这可能也很有趣:

你找到答案了吗?@IrinaRapoport有点。。。我能绕过它。我不记得所有的细节,因为这已经有一段时间了,但我发布了一个基于我现在的最终代码的答案。。。希望有帮助!
myLangFile ::= (item|COMMENT|CRLF)
item ::=
    itemName
    (TYPE_FLEX_OPEN_SQUARE_BRACKET itemProperty? TYPE_FLEX_CLOSE_SQUARE_BRACKET?)?
    itemBody?
itemName ::= TYPE_FLEX_WORD
itemProperty ::= TYPE_FLEX_WORD
itemBody ::= TYPE_FLEX_OPEN_CURLY_BRACKET item* TYPE_FLEX_CLOSE_CURLY_BRACKET
myLangFile ::= (item|COMMENT|CRLF)
item ::=
    itemName
    itemProperties
    itemBody?
itemName ::= TYPE_FLEX_WORD
itemProperties ::= TYPE_FLEX_OPEN_SQUARE_BRACKET [!TYPE_FLEX_CLOSE_SQUARE_BRACKET itemProperty ((TYPE_FLEX_SEMICOLON itemProperty)|itemProperty)*] TYPE_FLEX_CLOSE_SQUARE_BRACKET {
    pin(".*") = 1
}
itemProperty ::= TYPE_FLEX_WORD TYPE_FLEX_EQUALS? itemPropertyValue? (TYPE_FLEX_EQUALS prv_swallowNextPropertyToPreventSyntaxErrors)?
private prv_swallowNextPropertyToPreventSyntaxErrors ::= TYPE_FLEX_WORD
itemPropertyValue ::= TYPE_FLEX_WORD
itemBody ::= TYPE_FLEX_OPEN_CURLY_BRACKET item* TYPE_FLEX_CLOSE_CURLY_BRACKET