2014-03-26 87 views
1

我有以下一段代碼:秒差距不解析換行符

import Text.ParserCombinators.Parsec 
import Control.Applicative hiding ((<|>)) 
import Control.Monad 

data Test = Test Integer Integer deriving Show 

integer :: Parser Integer 
integer = rd <$> many1 digit 
    where rd = read :: String -> Integer 

testParser :: Parser Test 
testParser = do 
    a <- integer 
    char ',' 
    b <- integer 
    eol 
    return $ Test a b 

eol :: Parser Char 
eol = char '\n' 

main = forever $ do putStrLn "Enter the value you need to parse: " 
        input <- getLine 
        parseTest testParser input 

但是當我真正嘗試在ghci解析自己的價值,這是行不通的。

ghci > main 
Enter the value you need to parse: 
34,343\n 
parse error at (line 1, column 7): 
unexpected "\\" 
expecting digit or "\n" 

關於我在這裏失蹤的任何想法?

+1

從'getLine'獲取輸入時不會有換行符,這可能是問題嗎? – bheklilr

+0

'getLine'爲你提供沒有行結束符的字符串,所以你不需要'eol'解析器。 – sergeyz

+1

你是在輸入一個換行符還是一個\後跟一個n?這就是錯誤信息似乎表明的。 –

回答

3

問題似乎是您期待換行符,但您的文本不包含換行符。將eol更改爲

eol :: Parser() 
eol = void (char '\n') <|> eof 

它會工作。

1

「\ n」是用於Haskell(和C等)字符串和字符文字以表示ASCII 0x0A的轉義碼,該字符用於指示UNIX和類UNIX平臺上的行尾。您不(通常)使用鍵盤上的< \>或< n>鍵將此字符放在文件中(例如),而不是使用< Enter>鍵。

在PC-DOS和類DOS系統上,ASCII 0x0D後跟ASCII 0x0A用於行尾,「\ r」是用於ASCII 0x0D的轉義碼。

getLine會一直讀取,直到找到行尾並返回一個包含除尾行字符之外的所有內容的字符串。所以,在你的例子中,你的解析器將無法匹配。您可以通過選擇性地匹配行尾來解決此問題。