Search code examples
scalaparser-combinators

Scala Parser Combinator


I am trying to write a Scala Parser combinator for the following input.

The input can be

  • 10
  • (10)
  • ((10)))
  • (((10)))

Here the number of brackets can keep on growing. but they should always match. So parsing should fail for ((((10)))

The result of parsing should always be the number at the center

I wrote the following parser

import scala.util.parsing.combinator._
class MyParser extends RegexParsers {
  def i = "[0-9]+".r ^^ (_.toInt)
  def n = "(" ~ i ~ ")" ^^ {case _ ~ b ~ _ => b.toInt}
  def expr = i | n
}
val parser = new MyParser
parser.parseAll(parser.expr, "10")
parser.parseAll(parser.expr, "(10)")

but now how do I handle the case where the number of brackets keep growing but matched?


Solution

  • Easy, just make the parser recursive:

    class MyParser extends RegexParsers {
      def i = "[0-9]+".r ^^ (_.toInt)
      def expr: Parser[Int] = i | "(" ~ expr ~ ")" ^^ {case _ ~ b ~ _ => b.toInt}
    }
    

    (but note that scala-parser-combinators has trouble with left-recursive definitions: Recursive definitions with scala-parser-combinators)