Parsec:如何消除有关空格的解析器错误
Parsec: How to silence parser errors about white spaces
我有以下解析器来解析包含重定向的 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
它似乎工作得很好,但我想关闭任何出现的 "expecting space" 或 "expecting whitespace"。
例如:
> P.parseTest lineRedirect " > target"
parse error at (line 1, column 4):
unexpected ">"
expecting space or command
我只想 "expecting command" 这里。
> P.parseTest lineRedirect "invalid! > target"
parse error at (line 1, column 8):
unexpected "!"
expecting letter or digit, white space or ">"
此处相同,但没有 "white space"。
这似乎有效
lineRedirect = do
lcmd <- P.try (P.spaces *> P.many1 command) P.<?> "command"
...
不过我不喜欢 try
。
意识到 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.<?> "")
我有以下解析器来解析包含重定向的 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
它似乎工作得很好,但我想关闭任何出现的 "expecting space" 或 "expecting whitespace"。
例如:
> P.parseTest lineRedirect " > target"
parse error at (line 1, column 4):
unexpected ">"
expecting space or command
我只想 "expecting command" 这里。
> P.parseTest lineRedirect "invalid! > target"
parse error at (line 1, column 8):
unexpected "!"
expecting letter or digit, white space or ">"
此处相同,但没有 "white space"。
这似乎有效
lineRedirect = do
lcmd <- P.try (P.spaces *> P.many1 command) P.<?> "command"
...
不过我不喜欢 try
。
意识到 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.<?> "")