I am trying to write a recursive parser combinator class
import scala.util.parsing.combinator._
class MyParser extends RegexParsers {
override val skipWhitespace = true
val singleValue = "[\\p{L}][\\p{L}0-9_\\*]*".r
val expr : Parser[Any] = subExpr ~ rep("&" ~ subExpr | "|" ~ subExpr)
val subExpr : Parser[Any] = singleValue | "(" ~ expr ~ ")"
}
When I try to instantiate it. it throws a null pointer exception
val parser = new MyParser
java.lang.NullPointerException
ammonite.$sess.cmd8$MyParser.<init>(cmd8.sc:4)
ammonite.$sess.cmd9$.<init>(cmd9.sc:1)
ammonite.$sess.cmd9$.<clinit>(cmd9.sc)
I am really at a loss to understand why. There is absolutely nothing in the code which should result in a null pointer exception at the time of construction. Not sure what's going on
The two members of MyParser
, expr
and subExpr
, must be initialized every time MyParser
is created, but they reference each other. They are evaluated in order, and when evaluating expr
subExpr
is still set to null
. A simplified version of this problem is:
class Bad {
val one = two - 1
val two = one + 1
}
You might want to change expr
and subExpr
to be methods (using def
), so they aren't retrieved until needed.