parse' :: Parser a -> String -> [(a,String)]
parse' p inp = p `with` inp
parse :: Parser a -> String -> [a]
parse p inp = [ v | (v,[]) <- parse' p inp ]
mkMany1 :: (Parser a -> Parser [a]) -> Parser a -> Parser [a]
mkMany1 many p = do x <- p
xs <- many p
return (x:xs)
many1L :: Parser a -> Parser [a]
many1L = mkMany1 manyL
manyL :: Parser a -> Parser [a]
manyL p = (many1L p) ||| (success [])
我正在尝试为不包含字符'<'
,'>'
或' '
(空格)的多个子字符串解析字符串,但我的解析器看起来不像终止。有人可以给我一些关于我缺少的东西吗?
textValid :: Char -> Bool
textValid c = c /= '<' && c /= '>' && not (isSpace c)
text :: Parser String
text = manyL (sat textValid)
当我尝试运行以下命令时,它永远不会终止。
parse (manyL text) "abc def <"
答案 0 :(得分:6)
问题是manyL parser
可以成功而不消耗输入(返回空列表)。
一个人不能传递一个可以成功的解析器,而不会消耗输入作为manyL
的参数,因为在这种情况下,你会得到你所处的无限循环。
在第一个text
消费输入的"abc"
前缀后,您将留下" def <"
一个以String
开头的空格。因此,尝试使用text
时,它会消耗尽可能多的textValid
字符,而不是String
的开头 - 即0 - 并返回它们 - []
。留下相同的输入。现在manyL text
再次尝试text
,看看是否也成功了......
你应该定义
text = many1L (sat textValid)
这样text
在没有消耗输入的情况下不会成功,并且在每次成功解析后从剩余输入的开头消耗空格可能是个好主意,比如
text = do
result <- many1L (sat textValid)
skipSpaces
return result
(skipSpaces
离开实施)。