2012-07-27 66 views
2

我试图写在斯卡拉一个简单的解析器,但是当我添加重复令牌斯卡拉似乎陷入无限循环......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}]") 

任何意见gratefull收到

+1

请注意,例如'regex(new Regex(“[0-9] +”))''可以写成''[0-9] +“。r'(或者只是'”\\ d +“。r”')。 – 2012-07-27 13:44:27

回答

1

的问题是?的优先级。看看下面的,例如:

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

这里的a <~ b?被解释为(a <~ b)?,所以它会接受"ab""",但不"a"。如果我们想要接受"a",我们需要编写a <~ (b?)

在你的情况下,你可以在matchTokenPartContentmatchTokenPart末尾加上括号space?,它会按预期工作。

+0

,固定后的运营商现在被限制在2.10,这可以更清晰和容易地写成'a <〜b。?'。 – 2012-07-27 20:50:13