Search code examples
scalaparser-combinators

Why is this code throwing a null pointer exception


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


Solution

  • 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.

    See also FAQ: Why is my abstract or overridden val null?