相互递归的scala解析器中的堆栈溢出

时间:2015-05-25 00:41:12

标签: scala parsing

所以,我在scala中研究这个东西,试图解析算术表达式。我在下面有一个expr可以是add的两个exprs或integer常量,但它会陷入无限循环的add调用expr调用add calling expr ..我对scala很新,但不是解析。我知道我做错了什么,但真正的问题是,它有点简单吗?

import scala.util.parsing.combinator._

abstract class Expr

case class Add(x: Expr, y: Expr) extends Expr
case class Constant(con: String) extends Expr

class Comp extends RegexParsers {

  def integer:Parser[Expr] = """-?\d+""".r ^^ {
    s => Constant(s)
  }

  def add: Parser[Expr] = expr ~ "+" ~ expr ^^ {
    case(a ~ "+" ~ b) => Add(a, b)
  }

  def expr: Parser[Expr] = (add | integer)

}

object Compiler extends Comp {

  def main(args: Array[String]) = parse(expr, "5+ -3"))//println("5+ -3")
}

1 个答案:

答案 0 :(得分:4)

基本RegexParsers无法解析左递归语法。要使其正常工作,您可以修改add的规则以删除左递归:

def add: Parser[Expr] = integer ~ "+" ~ expr ^^ {
  case(a ~ "+" ~ b) => Add(a, b)
}

或使用PackratParsers解析此类语法:

class Comp extends RegexParsers with PackratParsers {

  lazy val integer:PackratParser[Expr] = """-?\d+""".r ^^ {
    s => Constant(s)
  }

  lazy val add: PackratParser[Expr] = expr ~ "+" ~ expr ^^ {
    case(a ~ "+" ~ b) => Add(a, b)
  }

  lazy val expr: PackratParser[Expr] = (add | integer)

}

object Compiler extends Comp {
  def main(args: Array[String]) = parseAll(expr, "5+ -3") 
}