2

私はscalaで単純なパーサーを書き込もうとしていますが、繰り返しトークンを追加すると、Scalaは無限ループでスタックしているようです...

object RewriteRuleParsers extends RegexParsers {
  private def space = regex(new Regex("[ \\n]+"))
  private def number = regex(new Regex("[0-9]+")) 
  private def equals = (space?)~"="~(space?)
  private def word   = regex(new Regex("[a-zA-Z][a-zA-Z0-9-]*")) 
  private def string = regex(new Regex("[0-9]+")) >> { len => ":" ~> regex(new Regex(".{" + len + "}")) }  

  private def matchTokenPartContent: Parser[Any] = (space?)~word~equals~word<~ space?  
  private def matchTokenPart: Parser[Any] = ((space?) ~> "{" ~> matchTokenPartContent <~ "}"<~ space?)  
  private def matchTokenParts = (matchTokenPart *)  
  private def matchToken: Parser[Any] = ("[" ~> matchTokenParts ~ "]")

  def parseMatchToken(str: String): ParseResult[Any] = parse(matchToken, str)
}

そしてそれを呼び出すためのコード

val parseResult = RewriteRuleParsers.parseMatchToken("[{tag=hello}]")

感謝の気持ちを込めて受け取ったアドバイス

4

1 に答える 1

1

問題はの優先順位です?。たとえば、次のようにします。

object simpleParser extends RegexParsers {
  val a = literal("a")
  val b = literal("b")
  def apply(s: String) = this.parseAll(a <~ b?, s)
}

hereは、a <~ b?として解釈されるため、または(a <~ b)?を受け入れますが、は受け入れません。を受け入れたい場合は、書く必要があります。"ab""""a"a <~ (b?)"a"

あなたの場合、とspace?の最後に括弧を付けるだけで、期待どおりに機能します。matchTokenPartContentmatchTokenPart

于 2012-07-27T13:35:55.070 に答える