Parsec:如何消除有关空格的解析器错误

时间:2016-04-12 07:06:28

标签: haskell parsec

我有以下解析器用于解析包含重定向的类似BASH的行。

lineRedirect :: P.Parsec String () String
lineRedirect = do
  lcmd <- P.spaces *> (P.many1 command P.<?> "command")
  P.char '>'
  rcmd <- P.spaces *> (P.many1 command P.<?> "redirection target")
  return $ (intercalate ";" lcmd) ++ " ++ " ++ (intercalate ";" rcmd)   
  where
    command :: P.Parsec String () String
    command = P.many1 P.alphaNum <* P.spaces

它看起来工作得很好,但我想要沉默任何期待的空间&#34;或者&#34;期待空白&#34;出现了。

例如:

> P.parseTest lineRedirect "   > target"
parse error at (line 1, column 4):
unexpected ">"
expecting space or command

我想要&#34;期待命令&#34;这里。

> P.parseTest lineRedirect "invalid! > target"
parse error at (line 1, column 8):
unexpected "!"
expecting letter or digit, white space or ">"

此处相同,没有&#34;空格&#34;。

2 个答案:

答案 0 :(得分:2)

在意识到spaces已经是一个有自己错误信息的复合解析器后,一切都很简单......

以下是我提出的建议:

lineRedirect :: P.Parsec String () (String, String)
lineRedirect = do
  cmd <- spaces' *> command
  P.char '>'
  tgt <- spaces' *> target
  return (cmd, tgt)

  where
    command :: P.Parsec String () String
    command = (P.many1 (P.noneOf ">") P.<?> "command")  <* spaces'

    target :: P.Parsec String () String
    target = (P.many1 P.anyChar P.<?> "redirection target") <* spaces' <* P.eof

    spaces' = P.skipMany (P.space P.<?> "")

答案 1 :(得分:0)

这似乎有效

lineRedirect = do
  lcmd <- P.try (P.spaces *> P.many1 command) P.<?> "command"
  ...

我不喜欢try