不平衡的树。很可能是由不平衡的标记引起的

时间:2018-08-03 20:46:49

标签: parsing intellij-idea bnf grammar-kit

我正在研究IntelliJ插件,它将增加对自定义语言的支持。目前,我仍在尝试习惯语法工具包以及插件开发的工作方式。

为此,我开始研究基本表达式的解析器:

(1.0 * 5 + (3.44 ^ -2))

根据JetBrains提供的文档,我尝试为上述示例编写BNF和JFlex语法。

为这些语法生成的代码可以编译,但是当插件运行时,它将崩溃:

  

java.lang.Throwable:不平衡树。极有可能是由不平衡的标记引起的。尝试针对传递的PsiBuilder调用setDebugMode(true)以确定问题的确切位置

启用调试模式会打印一长串痕迹:

java.lang.Throwable: Created at the following trace.
at com.intellij.lang.impl.MarkerOptionalData.notifyAllocated(MarkerOptionalData.java:83)
at com.intellij.lang.impl.PsiBuilderImpl.createMarker(PsiBuilderImpl.java:820)
at com.intellij.lang.impl.PsiBuilderImpl.precede(PsiBuilderImpl.java:457)
at com.intellij.lang.impl.PsiBuilderImpl.access$700(PsiBuilderImpl.java:51)
at com.intellij.lang.impl.PsiBuilderImpl$StartMarker.precede(PsiBuilderImpl.java:361)

java.lang.Throwable: Created at the following trace.
at com.intellij.lang.impl.MarkerOptionalData.notifyAllocated(MarkerOptionalData.java:83)
at com.intellij.lang.impl.PsiBuilderImpl.createMarker(PsiBuilderImpl.java:820)
at com.intellij.lang.impl.PsiBuilderImpl.mark(PsiBuilderImpl.java:810)
at com.intellij.lang.impl.PsiBuilderAdapter.mark(PsiBuilderAdapter.java:107)
at com.intellij.lang.parser.GeneratedParserUtilBase.enter_section_(GeneratedParserUtilBase.java:432)
at com.example.intellij.mylang.MyLangParser.exp_expr_0(MyLangParser.java:154)

java.lang.Throwable: Created at the following trace.
at com.intellij.lang.impl.MarkerOptionalData.notifyAllocated(MarkerOptionalData.java:83)
at com.intellij.lang.impl.PsiBuilderImpl.createMarker(PsiBuilderImpl.java:820)
at com.intellij.lang.impl.PsiBuilderImpl.precede(PsiBuilderImpl.java:457)
at com.intellij.lang.impl.PsiBuilderImpl.access$700(PsiBuilderImpl.java:51)
at com.intellij.lang.impl.PsiBuilderImpl$StartMarker.precede(PsiBuilderImpl.java:361)

即使有了这些调试日志,我仍然不明白出了什么问题。我已经尝试过使用Google搜索功能,但在这种情况下,我什至无法弄清楚“标记”的含义是什么。

这是BNF语法:

root ::= expr *

expr ::= add_expr

left add_expr ::= add_op mod_expr | mod_expr
private add_op ::= '+'|'-'

left mod_expr ::= mod_op int_div_expr | int_div_expr
private mod_op ::= 'mod'

left int_div_expr ::= int_div_op mult_expr | mult_expr
private int_div_op ::= '\'

left mult_expr ::= mult_op unary_expr | unary_expr
private mult_op ::= '*'|'/'

unary_expr ::= '-' unary_expr | '+' unary_expr | exp_expr

left exp_expr ::= exp_op exp_expr | value
private exp_op ::= '^'

// TODO: Add support for left_expr. Example: "someVar.x"
value ::= const_expr | '(' expr ')'

const_expr ::= bool_literal | integer_literal | FLOAT_LITERAL | STRING_LITERAL | invalid

bool_literal ::= 'true' | 'false'

integer_literal ::= INT_LITERAL | HEX_LITERAL

1 个答案:

答案 0 :(得分:0)

我发现了问题。这与我的BNF无关。问题是在我的jflex文件中,我已经处于yybegin(YYINITIAL)状态时正在调用YYINITIAL