考虑一种简单的语言,它是用空格分隔的命令的列表。每个命令均以单个字母作为命令名称,并使用一系列以空格分隔的数字作为其参数。例如,a 1 2 3 b 4 5 6 d 7 e f
将代表以下命令:
问题在于,它一直通过抓取项目sepBy
,并到达另一个数字,但是到达“ b”时失败。
但是,通过下面的代码传递时,会产生以下错误:
Left "error" (line 1, column 5):
unexpected "b"
expecting space
现在,我意识到这很可能是由于我在查看问题时遇到的错误而引起的,并希望有人指出如何解析此类内容。
module Main where
import Control.Applicative hiding (many, optional, (<|>))
import Text.ParserCombinators.Parsec
import Numeric (readSigned, readFloat)
commands = command `sepBy` spaces
command = do
l <- letter
ns <- number `sepBy` spaces
return (l, ns)
main :: IO ()
main = print $ show $ parse commands "error" "a 1 2 3 b 4 5 6 d 7 e f"
number :: CharParser () Double
number = do s <- getInput
case readSigned readFloat s of
[(n, s')] -> n <$ setInput s'
_ -> empty
尝试在每个非空格标记之后使用空格。例如
commands = many (command <* spaces)
command = do
l <- letter
spaces
ns <- many (number <* spaces)
return (l, ns)
或者
command = (,) <$> (letter <* spaces) <*> many (number <* spaces)
主要思想是:解析某些内容后,下一个字符应该是一个非空格,开始要解析的下一个项目。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句