2011-05-21 63 views
2

首先,代码一些简单的问题:有使用Scala组合子解析器

package com.digitaldoodles.markup 

import scala.util.parsing.combinator.{Parsers, RegexParsers} 
import com.digitaldoodles.rex._ 


class MarkupParser extends RegexParsers { 
    val stopTokens = (Lit("{{") | "}}" | ";;" | ",,").lookahead 
    val name: Parser[String] = """[@#!$]?[a-zA-Z][a-zA-Z0-9]*""".r 
    val content: Parser[String] = (patterns.CharAny ** 0 & stopTokens).regex 
    val function: Parser[Any] = name ~ repsep(content, "::") <~ ";;" 
    val block1: Parser[Any] = "{{" ~> function 
    val block2: Parser[Any] = "{{" ~> function <~ "}}" 
    val lst: Parser[Any] = repsep("[a-z]", ",") 
} 

object ParseExpr extends MarkupParser { 
    def main(args: Array[String]) { 
     println("Content regex is ", (patterns.CharAny ** 0 & stopTokens).regex) 
     println(parseAll(block1, "{{@name 3:4:foo;;")) 
     println(parseAll(block2, "{{@name 3:4:foo;; stuff}}")) 
     println(parseAll(lst, "a,b,c")) 
    } 
} 

然后,执行结果:

[info] == run == 
[info] Running com.digitaldoodles.markup.ParseExpr 
(Content regex is ,(?:[\s\S]{0,})(?=(?:(?:\{\{|\}\})|;;)|\,\,)) 
[1.18] parsed: (@name~List(3:4:foo)) 
[1.24] failure: `;;' expected but `}' found 

{{@name 3:4:foo;; stuff}} 
        ^

[1.1] failure: string matching regex `\z' expected but `a' found 

a,b,c 
^ 

我用一个自定义库组装我的一些正则表达式,所以我已经打印出“内容”正则表达式;它应该基本上是任何文本,但不包括某些令牌模式,使用积极的前瞻断言强制执行。

最后,问题:

1)关于“块1”成功,第一次运行,但不应该,因为在“repsep”功能,隔板为“::”,但“:”解析作为分隔符。

2)“block2”上的运行失败,可能是因为前瞻从句不起作用 - 但我无法弄清楚为什么应该这样。先行条款已经在“block1”上运行的“repsep”中运行,并且似乎在那里工作,那么它为什么在块2上失败呢?

3)“lst”的简单重新执行操作失败,因为内部解析器引擎似乎在寻找边界 - 这是我需要以某种方式解决的东西吗?

感谢, 肯

回答

2

1)没有, “::” 不被解析为分隔符。如果是这样,输出将是(@name~List(3, 4, foo))

2)这是因为“}}”也是一个分隔符,所以它需要最长的匹配 - 也包括“;;”。如果您使前面的表达式不渴望,它将在“stuff”上的“s”上失败,我认为这是您的预期。

3)你传递了一个文字,而不是正则表达式。修改"[a-z]""[a-z]".r,它会工作。

相关问题