2014-09-01 62 views
1

我寫了與fail意圖-ing上的空白以下解析器:理解`not`在解析器組合

import scala.util.parsing.combinator._ 

object Foo extends JavaTokenParsers { 
    val wsTest = not(whiteSpace) // uses whitespace inherited from `RegexParsers` 
} 

爲什麼解析一堆空白的全成?

scala> Foo.parseAll(Foo.wsTest, "   ") 
res5: Foo.ParseResult[Unit] = [1.11] parsed:() 

scala> res5.successful 
res6: Boolean = true 

project望着Parsers#not,我會一直期待我的上述測試Failure

/** Wrap a parser so that its failures and errors become success and 
    * vice versa -- it never consumes any input. 
    */ 
    def not[T](p: => Parser[T]): Parser[Unit] = Parser { in => 
    p(in) match { 
     case Success(_, _) => Failure("Expected failure", in) 
     case _    => Success((), in) 
    } 
    } 
+0

'不'正常工作。我的猜測是解析器默認跳過空格,你必須禁用它。也許這有助於:http://stackoverflow.com/questions/3564094/parsing-a-blank-whitespace-with-regexparsers – Kigyo 2014-09-01 16:27:46

+0

'我的猜測是,解析器跳過默認空白' - 我已經觀察到這種行爲與類擴展'JavaTokenParsers'。但是,我不希望'Foo.parseAll(Foo.wsTest,「」)'成功。 – 2014-09-01 17:32:46

回答

4

JavaTokenParsers延伸RegexParsers,RegexParsers有:

protected val whiteSpace = """\s+""".r 

def skipWhitespace = whiteSpace.toString.length > 0 

implicit def regex(r: Regex): Parser[String] = new Parser[String] { 
    ... 
    val start = handleWhiteSpace(source, offset) 
    ... 
} 

protected def handleWhiteSpace(source: java.lang.CharSequence, offset: Int): Int = 
    if (skipWhitespace) 
    (whiteSpace findPrefixMatchOf (source.subSequence(offset, source.length))) match { 
     case Some(matched) => offset + matched.end 
     case None => offset 
    } 
    else 
    offset 

所以跳過空白

所以解析器" "等於 「」

(您可以通過高清覆蓋skipWhitespace = FALSE覆蓋此)

空格嘗試匹配「」但它失敗(「」「\ s +」「」至少需要一個空格)和不是轉換成功

+0

謝謝,@Siphor。實際上,我問這個問題是爲了實現這個[答案](http://stackoverflow.com/a/25294257/409976)的後續工作。爲了驗證我正在解析的「輸入」,即令牌,我添加了val nonWhitespaceRegex:Regex =「\\ S +」。r'和'guard(nonWhitespaceRegex)〜> ...'空白。否則,檢查一堆空格是EOF將返回false。 – 2014-09-02 00:42:56