我正在尝试解析一些文本,但我无法理解如何解析由某些分隔符分隔的符号列表,这可能会也可能不会出现在列表的末尾。
示例(数字以空格分隔):
set A = 1 2 3 4 5;
set B =6 7 8 9;
set C = 10 11 12 ;
如果我使用 sepBy
,在最后一个空格之后我会收到错误,因为它需要另一个数字,即使我尝试在列表后面读取许多空格
。如果我使用 endBy
,则当缺少空格时会出现错误。
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)
最佳答案
我认为你想要的组合器是 sepEndBy
。使用它可以给你
-- 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
关于haskell - 解析一个列表,其分隔符也可能出现在末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16989916/