我有以下解析器用于解析包含重定向的类似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;。
答案 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
。