2011-05-21 64 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,它會工作。

相關問題