使用 Haskell / Parsec 将 \" 转换为 "

Transforming \" into " using Haskell / Parsec

我正在学习 Write Yourself A Scheme 教程,但有一个练习我无法解决。

Our strings aren't quite R5RS compliant, because they don't support escaping of internal quotes within the string. Change parseString so that \" gives a literal quote character instead of terminating the string. You may want to replace noneOf "\"" with a new parser action that accepts either a non-quote character or a backslash followed by a quote mark.

实际的ParseString代码函数为:

parseString :: Parser LispVal
parseString = do
        char '"'
        x <- many (noneOf "\"")
        char '"'
        return $ String x

我尝试过很多方法来做到这一点。我尝试的解决方案是:

parseString :: Parser LispVal
parseString = do
        char '"'
        x <- many (satisfy (/= '"') <|> (string "\"" >> return '"'))
        char '"'
        return $ String x

我的理由是 (string "\"" >> return '"') 将消耗一个由 \" 和 return 组成的字符串,一个双引号字符,但它没有按预期工作。我也在互联网上进行了研究,但没有找不到解决方案。

在 Haskell 中写入 "\"" 会生成一个只有一个元素的字符串。那是因为 Haskell 解析器正在使用反斜杠,它永远不会到达您的程序。您需要对其进行双重转义,以便 Haskell 和您的解析器都满意。

noneOf "\"\" <|> (string "\\"" >> return '"')