Parsing 如何同时获取解析中读取的字符数?

Parsing 如何同时获取解析中读取的字符数?,parsing,haskell,Parsing,Haskell,我用Numeric.readDec解析数字,用reads解析字符串。但我还需要知道读了多少个字符 例如readDec“52 rest”返回[(52,“rest”)],并读取2个字符。但我找不到一个很好的方法知道它读两个字符 您可以检查show 52的字符串长度,但如果输入为052,则会给出错误的答案(此解决方案也不适用于包含转义字符的字符串解析)。您还可以使用从输入字符串长度中减去后解析字符串的长度。但对于具有许多解析的长字符串来说,这是非常低效的 如何正确有效地完成此操作(最好不编写自己的解析

我用
Numeric.readDec
解析数字,用
reads
解析字符串。但我还需要知道读了多少个字符

例如
readDec“52 rest”
返回
[(52,“rest”)]
,并读取2个字符。但我找不到一个很好的方法知道它读两个字符

您可以检查
show 52
的字符串长度,但如果输入为052,则会给出错误的答案(此解决方案也不适用于包含转义字符的字符串解析)。您还可以使用从输入字符串长度中减去后解析字符串的长度。但对于具有许多解析的长字符串来说,这是非常低效的


如何正确有效地完成此操作(最好不编写自己的解析)?

使用
base
,而不是
readDec
,您可以使用
Text.Read.Lex
中的
readDecP
,它使用
ReadP
解析器:

readDecP :: (Eq a, Num a) => ReadP a
Text.parsercompbinators.ReadP中的
gather
组合器返回解析结果以及解析的实际字符:

gather :: ReadP a -> ReadP (String, a)
您可以使用
readP\u to_S
运行解析器,该解析器返回
ReadS
解析器,该解析器是一个函数,它接受字符串并生成一个可能的解析列表,其中包含字符串的其余部分

readP_to_S :: ReadP a -> ReadS a

type ReadS a = String -> [(a, String)]
GHCi中的一个示例:

> import Text.ParserCombinators.ReadP (gather, readP_to_S)

> import Text.Read.Lex (readDecP)

> readP_to_S (gather readDecP) "52 rest"
[(("52",52)," rest")]

> readP_to_S (gather readDecP) "0644 permissions"
[(("0644",644)," permissions")]
如果希望结果明确无误,只需检查是否只有一个有效的解析,然后取第一个组件的长度来查找解析的
Char
代码点的数量


然而,这些解析器相当有限;如果您想要更易于使用、更快或能够生成更详细的错误消息,那么您应该查看功能更全面的解析包,例如(常规语法)或(上下文相关语法)。

read
仅适用于最简单的情况。如果你需要更多的控制,考虑使用一个合适的语法分析器,比如Parsec。谢谢,这是完美的。我想补充一点,通过这种方式解析字符串,我发现可以使用gather Text.Read.Lex.Lex