2013-04-24 18 views
1
parse' :: Parser a -> String -> [(a,String)] 
parse' p inp = p `with` inp 

parse :: Parser a -> String -> [a] 
parse p inp = [ v | (v,[]) <- parse' p inp ] 

mkMany1 :: (Parser a -> Parser [a]) -> Parser a -> Parser [a] 
mkMany1 many p = do x <- p 
        xs <- many p 
        return (x:xs) 

many1L :: Parser a -> Parser [a] 
many1L = mkMany1 manyL 

manyL :: Parser a -> Parser [a] 
manyL p = (many1L p) ||| (success []) 

我試圖解析爲多個子的不包含字符'<''>'' '(空間),但我沒有按分析器」的String t似乎終止。有人能給我一些關於我失蹤的指示嗎?哈斯克爾「解析」並無終止對特定類型的字符串

textValid :: Char -> Bool 
textValid c = c /= '<' && c /= '>' && not (isSpace c)  

text :: Parser String 
text = manyL (sat textValid) 

當我嘗試運行以下命令時,它永遠不會終止。

parse (manyL text) "abc def <" 
+0

'many'和'manyL'是如何定義的?我懷疑'manyL'卡在這個空間。 – 2013-04-24 18:58:47

+0

對不起,它只是'manyL',我已經添加了'manyL'的定義。 – rlhh 2013-04-24 19:06:26

+0

將'textValid'定義爲_not_ something是一個經典的解析錯誤。您允許絕對__any__字符不在「< >」中,而您應該準確指定您允許的內容 - 可能只是字母數字值,以字母開頭?任何事情都不好解析。錯誤地匹配包含在字符串或類似錯誤中的分隔符太容易。 – AndrewC 2013-04-24 20:46:11

回答

6

問題是manyL parser可以成功,而不消耗輸入(返回一個空列表)。

而且人們不應通過一個解析器,因爲在這種情況下,你正是這樣一個無限循環,你是,在不消耗輸入爲manyL參數成功。

第一text消耗的後​​輸入的前綴,您將以" def <" a String開頭並留有空格。因此,嘗試text就可以了,它會消耗個字符,就像在String開始時那樣 - 即0 - 並返回它們 - []。這留下了相同的投入。現在manyL text嘗試text其他時間,看看是否能成功,太...

你或許應該定義

text = many1L (sat textValid) 

使text不成功不消耗輸入,大概是要消耗一個好主意從每個成功的解析後的剩餘輸入的開頭空間,像

text = do 
    result <- many1L (sat textValid) 
    skipSpaces 
    return result 

skipSpaces留下來實施)。