2013-06-07 21 views
5

sonunda ortaya çıkabilen bir listeyi ayrıştırıyorum Bazı metni ayrıştırmaya çalışıyorum, ancak sonunda da oluşabilecek veya oluşmayabilecek bir ayırıcı tarafından ayrılan semboller listesinin nasıl ayrılacağını anlayamıyorum listeninAyırıcı da

Örnek (boşlukla ayrılmış numaralar): ben listesinden sonra da many whitespace okumaya çalışın bile, başka rakamı beklediğini çünkü

set A = 1 2 3 4 5; 
set B =6 7 8 9; 
set C = 10 11 12 ; 

Ben sepBy kullanırsanız

, son uzay sonra bir hata aldım. endBy kullanırsam, boşluk eksik olduğunda bir hatayla karşılaştım.

import Text.ParserCombinators.Parsec 

main :: IO() 
main = do 
    let input = "set A = 1 2 3 4 5;\n" ++ 
       "set B =6 7 8 9;\n" ++ 
       "set C = 10 11 12 ;\n" 
    case parse parseInput "(unknown)" input of 
    Left msg -> 
     print msg 
    Right rss -> 
     mapM_ (\(n, vs) -> putStrLn (n ++ " = " ++ show vs)) rss 

whitespace :: GenParser Char st Char 
whitespace = oneOf " \t" 

parseInput :: GenParser Char st [(String, [Int])] 
parseInput = parseRow `endBy` newline 

parseRow :: GenParser Char st (String, [Int]) 
parseRow = do 
    string "set" 
    many1 whitespace 
    name <- many1 alphaNum 
    many whitespace 
    string "=" 
    many whitespace 
    values <- many1 digit `sepBy` many1 whitespace 
    many whitespace 
    string ";" 
    return (name, map read values) 
+0

Bu önceki soru http://stackoverflow.com/questions/3921559/haskell-parsec-optional-question bazı kullanım olabilir verir. – rickythesk8r

cevap

8

İstediğinizi düşündüğüm birleştirici sepEndBy'dur. Bunu kullanmak size

-- I'm using the type synonym 
-- type Parser = GenParser Char() 
-- from Text.ParseCombinator.Parsec.Prim 
parseRow :: Parser (String, [Int]) 
parseRow = do 
    string "set" >> many1 whitespace 
    name <- many1 alphaNum 
    spaces >> char '=' >> spaces 
    values <- many1 digit `sepEndBy` many1 whitespace 
    char ';' 
    return (name, map read values) 
    where spaces = many whitespace