Parsing IntelliJ:语法工具包/BNF:如何从错误中恢复?
我正在为IntelliJ编写一个自定义语言插件 下面是该语言的一个简化示例。请注意,该结构是递归的: 我已经成功地实现了FLEX和BNF文件,但我不确定如何添加错误恢复。我已经在语法工具包的HOWTO中读到了RecoverWhile和pin,但我不知道如何将它们应用到我的场景中 我将上面的棕色项目称为(“aaa”、“ccc”等…)项目 我把黄色的称为“bbb”、“ddd”和“properties” 每个项目都有一个项目名称(如“aaa”)、一个单一属性(如“bbb”),并且可以包含其他项目(如“aaa”包含“ccc”、“eeee”和“gg”) 目前,当一个项目的格式不正确时,插件的表现并不好。例如: 在本例中,我希望解析器“理解”一点,即“ccc”是缺少属性的项的名称(例如,通过检测右括号前的换行符) 我不希望被破坏的“ccc”项影响“eeee”的解析(但我确实希望PSI树具有文本中存在的“ccc”元素,在本例中为其名称) 以下是我使用的FLEX和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”),并且可以包含其他项目(如
我最终能够让它像这样工作:
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