Parsing scala解析器组合器堆栈溢出递归

Parsing scala解析器组合器堆栈溢出递归,parsing,scala,recursion,stack-overflow,Parsing,Scala,Recursion,Stack Overflow,下面的代码示例在解析深嵌套在括号中的表达式时由于堆栈溢出而崩溃 解析器组合器是标准库的一部分。有没有办法利用图书馆来避免这种情况 (我不是问它崩溃的原因,而是问如何正确处理标准库。) 解析: (()((()((()(()(()( 代码: 导入scala.util.parsing.combinator.syntactic.StandardTokenParser 对象算术分析器1扩展了StandardTokenParsers{ lexical.delimiters++=列表(“(“,”,“+”,“-

下面的代码示例在解析深嵌套在括号中的表达式时由于堆栈溢出而崩溃

解析器组合器是标准库的一部分。有没有办法利用图书馆来避免这种情况

(我不是问它崩溃的原因,而是问如何正确处理标准库。)

解析: (()((()((()(()(()(

代码:

导入scala.util.parsing.combinator.syntactic.StandardTokenParser
对象算术分析器1扩展了StandardTokenParsers{
lexical.delimiters++=列表(“(“,”,“+”,“-”,“*”,“/”)
val reduceList:Int~List[String~Int]=>Int={
案例一~ps=>(i/:ps)(减少)
}
def reduce(x:Int,r:String~Int)=(r:@unchecked)匹配{
大小写“+”~y=>x+y
大小写“-”~y=>x-y
大小写“*”~y=>x*y
大小写“/”~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我不确定如何使用scala解析器组合器处理它。我的第一个想法是蹦床[1]——但快速的谷歌搜索似乎表明默认库不支持这一点。因此我认为解决这一问题的主要方法是使用
-Xss
,这不太理想


但是,它支持蹦床,而且它似乎有一个与标准库类似的API。

我无法重现崩溃。有多少级别的嵌套括号使程序抛出异常?我也尝试过,并且(使用默认jvm堆栈大小)必须上升到3500级(=括号对数)在我遇到堆栈溢出之前!这为真实世界的表达式留下了相当大的空间…@buerger:我很想知道您是否有更合理级别的堆栈溢出,以及哪个用例需要如此多的嵌套。改进解析器库的一种方法是使用显式堆栈。任何级别的嵌套都是如此可以。但是,任何修改库的假设方法都不合理。理论上,是的,可以解析的表达式的复杂性不应该有限制。在实践中,任何东西在计算中都是有限制的,要么是时间(在某一点上,某件东西太长,无法计算,无法实际使用)要么是内存(肯定是有限制的)。更清楚的是,如果您试图让scala编译器编译表达式
(((((((((((…1+1…))))))),它本身将出现堆栈溢出
嵌套级别为3500。试试看。使用显式堆栈肯定会大有帮助,但有一点你的堆栈会占用整个内存,你会撞到墙。我知道我可能看起来很迂腐,但我想说的是,你一定需要限制。所以真正的问题是:l3500的水平是一个不可接受的极限?
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))
  }
}