haskell - 解析一个列表,其分隔符也可能出现在末尾

标签 haskell parsec

我正在尝试解析一些文本,但我无法理解如何解析由某些分隔符分隔的符号列表,这可能会也可能不会出现在列表的末尾。

示例(数字以空格分隔):

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/

相关文章:

haskell - 为什么 Hoogle 和 :t? 显示的 Text.Parsec.Token.natural 类型不同

parsing - Parsec 或 happy (与 alex) 或 uu-parsinglib

parsing - 解析器组合器和 Packrat 算法之间的实现差异

haskell - "Unexpected end of input - expecting end of input"(秒差距)

haskell - 很难让 Parsec 解析器正确跳过空格

haskell - 为类型匹配定义 Storable 的受限子集

haskell - take 2 $ [1..] 如何在 haskell 中工作?

haskell - 格式化长模式匹配

list - Haskell - 将列表分成两个总和最接近的子列表

haskell - 为什么 Haskell 可以在这个函数中推导出 [] 类型