0

我正在开发一个 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)

即使有这些调试日志,我仍然不明白出了什么问题。我试过用谷歌搜索,我什至无法弄清楚“标记”在这种情况下是什么意思......

这是 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
4

1 回答 1

0

我弄清楚了这个问题。这与我的 BNF 无关。问题是在我的 jflex 文件中,我yybegin(YYINITIAL)已经在该YYINITIAL状态下调用了。

于 2018-08-05T04:03:29.613 回答