Unbalanced tree. Most probably caused by unbalanced markers

173 views Asked by At

I'm working on an IntelliJ plugin which will add support for a custom language. Currently, I'm still just trying to get used to grammar kit and how plugin development works.

To that end, I've started working on a parser for basic expressions:

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

Following the documentation provided by JetBrains, I've attempted to write BNF and JFlex grammars for the above example.

The generated code for these grammars compiles, but when the plugin is run, it crashes with:

java.lang.Throwable: Unbalanced tree. Most probably caused by unbalanced markers. Try calling setDebugMode(true) against PsiBuilder passed to identify exact location of the problem

Enabling debug mode prints a long list of traces:

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)

Even with these debug logs, I still don't understand what's going wrong. I've tried googling around, and I can't even figure out what 'marker' means in this context...

Here's the BNF grammar:

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

There are 1 answers

0
Mike Fougere On

I figured out the issue. It had nothing to do with my BNF. The problem was that in my jflex file I was calling yybegin(YYINITIAL) while already in the YYINITIAL state.