簡體   English   中英

Scala的解析器組合器在解析之前進行比較

[英]Scala's parser combinator compare before parse

我正在尋找一種使用Scala的解析器組合器與正則表達式進行匹配的方法。

例:

import scala.util.parsing.combinator.RegexParsers

object MetaCommandParser extends RegexParsers with App {

  def parseSub: Parser[Object] = (parseElement <~ "=>") ~ parseExpression.*

  def parseElement: Parser[Object] = """\w+""".r

  def parseOr: Parser[Object] = listElements

  def listElements: Parser[Object] = parseExpression ~ opt("|" ~ listElements)

  def parseExpression: Parser[Object] = parseElement | parseOr

  def parseMetaCommand(s: String) = {
    MetaCommandParser.parseAll(parseSub, s) match {
      case Success(result, _) => result
      case Failure(msg, _)    => throw new Exception("FAILURE: " + msg)
      case Error(msg, _)      => throw new Exception("ERROR: " + msg)
    }
  }

  println(parseMetaCommand("operation => test"));
}

類型:

sealed trait Command;
case class Sub(tag: Word, sub: List[Expression]) extends Command;
case class ReplaceBy(tag: Word, sub: List[Expression]) extends Command;

sealed trait Expression;
case class Or(elements: Set[Expression]) extends Expression;
case class Reference(tag: String) extends Expression;
case class Option(element: Expression) extends Expression;
case class Word(tag: String) extends Expression;
case object Empty extends Expression;

如果我使用以下表達式在parseSub上執行解析器:“ operation => test”

我有一個StackOverflow。 我的解析器很好地解析了Sub(Word(operation),Word(test)),但之后出現了錯誤。 我認為解析器試圖在parseExpression上計算一個空字符串以結束“ parseExpression。*”,但是在listElements中循環。 如果可以在調用parseExpression之前確保我的條目有效,那么我認為它可以解決我的問題(parseValidString函數)!

因此,我試圖驗證我的條目與該正則表達式匹配,以避免無限循環,但我不知道如何做到這一點:/

謝謝!

您的parseExpressionlistElements規則是相互左遞歸的(通過parseOr )。 在我的評論中,我建議這可能不會導致堆棧溢出,因為parseElementlistElements之前進行了listElements ,這意味着listElements將永遠無法到達(這本身就是另一個問題)。

但是,由於在*循環中使用parseExpression ,因此它將重復應用,直到失敗為止,這意味着最終將嘗試使用其所有替代方法。 因此,將達到listElements ,而左遞歸確實會導致堆棧溢出。 您也可以從以下事實中看到這一點:如果注釋掉| parseOr ,則堆棧溢出會消失| parseOr | parseOrparseExpression

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM