scala parser combinator stackoverflow recursion

随声附和 提交于 2019-12-23 18:26:22

问题


The following code example crashes due to stack overflow when parsing an expression deeply nested in brackets.

Parser combinators are part of the standard library. Is there a way of making use of the library avoiding that?

(I'm not asking for the reason of why it crashes rather for the right way to deal with the standard library.)

parsing: ((((((((... 1 + 1 ...)))))))))

code:

import scala.util.parsing.combinator.syntactical.StandardTokenParsers

object ArithmeticParser1 extends StandardTokenParsers {   
  lexical.delimiters ++= List("(", ")", "+", "-", "*", "/")

  val reduceList: Int ~ List[String ~ Int] => Int = {
    case i ~ ps => (i /: ps)(reduce) 
  }

  def reduce(x: Int, r: String ~ Int) = (r: @unchecked) match {
    case "+" ~ y => x + y
    case "-" ~ y => x - y
    case "*" ~ y => x * y
    case "/" ~ y => x / y
  }

  def expr  : Parser[Int] = term ~ rep ("+" ~ term | "-" ~ term) ^^ reduceList
  def term  : Parser[Int] = factor ~ rep ("*" ~ factor | "/" ~ factor) ^^ reduceList
  def factor: Parser[Int] = "(" ~> expr <~ ")" | numericLit ^^ (_.toInt)

  def main(args: Array[String]) {
    val s = scala.io.Source.fromFile(args(0)).mkString
    val tokens = new lexical.Scanner(s)
    println(s)
    println(phrase(expr)(tokens))
  }
}

回答1:


I'm not sure how you would deal with it with scala parser combinators. My first thought was trampolining[1] - but a quick google search seems to say that the default library doesn't support this. Hence I think the main way around this would be to use -Xss which is less than ideal.

However https://github.com/djspiewak/gll-combinators supports trampolining, and it seems like it has a similar API to the standard library.



来源:https://stackoverflow.com/questions/12875829/scala-parser-combinator-stackoverflow-recursion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!