haskell - 带有 attoparsec 的切片
问题描述
我正在查看attoparsec 文档中的这个示例:
simpleComment = string "<!--" *> manyTill anyChar (string "-->")
这将构建一个[Char]
而不是ByteString
切片。这对大量评论不好,对吧?
另一种选择,takeWhile:
takeWhile :: (Word8 -> Bool) -> Parser ByteString
不能接受解析器(即不能匹配 a ByteString
,只能匹配 a Word8
)。
有没有办法ByteString
用 attoparsec 解析大块而不涉及[Char]
在过程中构建 a ?
解决方案
您可以使用scan
:
scan :: s -> (s -> Word8 -> Maybe s) -> Parser ByteString
有状态的扫描仪。谓词使用并转换一个状态参数,并且每个转换后的状态都被传递给对输入的每个字节的谓词的连续调用,直到一个返回 Nothing 或输入结束。
它看起来像这样:
transitions :: [((Int, Char), Int)]
transitions = [((0, '-'), 1), ((1, '-'), 2), ((2, '-'), 2), ((2, '>'), 3)]
dfa :: Int -> Word8 -> Maybe Int
dfa 3 w = Nothing
dfa s w = lookup (s, toEnum (fromEnum w)) transitions <|> Just 0
然后使用scan 0 dfa
将字节取到并包括最后一个"-->"
. "-->"
我在这里使用的状态告诉我们到目前为止我们已经看到了多少个字符。一旦我们看到它们,我们就会通知scan
是时候停下来了。这只是为了说明这个想法;为了提高效率,您可能希望使用比关联列表更有效的数据结构,将*Enum
调用移动到查找表中,甚至考虑直接编写函数。
推荐阅读
- php - 如何使用 laravel livewire 按类别显示帖子数据
- javascript - 如何通过 POST 请求获取和打印存储在 localStorage 中的变量?
- spring - 在 JPA @query 中按索引搜索集合
- html - 当文本大小超过输入宽度时,如何使输入类型文本显示字符串的最后一个字母?
- python - 如何在 Django 中为 InMemoryUploadedFile 对象使用 filecmp.cmp()?
- html - Bootstap 在没有 Saas 的情况下制作自己的容器
- php - 为什么找不到用户?
- schemacrawler - 想要生成具有弱关联的 ER 图。在哪里定义属性文件
- python - 为什么班级不从列表中获取信息?Python
- mysql - 在数据库中搜索单词