简体   繁体   English

scala解析器组合器stackoverflow递归

[英]scala parser combinator stackoverflow recursion

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 ...))))))))) 解析:((((((((((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))
  }
}

I'm not sure how you would deal with it with scala parser combinators. 我不确定如何使用scala解析器组合器处理它。 My first thought was trampolining[1] - but a quick google search seems to say that the default library doesn't support this. 我的第一个想法是蹦床[1] - 但快速谷歌搜索似乎说默认库不支持这个。 Hence I think the main way around this would be to use -Xss which is less than ideal. 因此我认为围绕这​​个的主要方法是使用-Xss ,这不是理想的。

However https://github.com/djspiewak/gll-combinators supports trampolining, and it seems like it has a similar API to the standard library. 但是, https://github.com/djspiewak/gll-combinators支持trampolining,它似乎与标准库有类似的API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM