1
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 <"
4

1 回答 1

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留待实施)。

于 2013-04-24T19:23:18.470 回答