parsing - 理解 Text.ParserCombinators.ReadP.sepBy1
问题描述
以下代码在 ghci 中运行
λ> import Text.ParserCombinators.ReadP
λ> import Data.Char
λ> readP_to_S ((munch1 isAlpha) `sepBy1` (char '-')) "dish-dash-dosh"
[(["dish"],"-dash-dosh"),(["dish","dash"],"-dosh"),["dish","dash","dosh"],"")]
- 为什么输出不是这种情况
[(["dish","dash","dosh"],"")]
?
以下doctest
只是失败的一个。
-- |
-- >>> readP_to_S readValues "dish-dash-dosh"
-- [(V ["dish","dash","dosh"],"")
readValues :: ReadP Value
readValues = do
xs <- (munch isAlpha) `sepBy1` (char '-')
pure $ V xs
Main.hs:64: failure in expression `readP_to_S readValues "dish-dash-dosh"'
expected: [(V ["dish","dash","dosh"],"")
but got: [(V ["dish"],"-dash-dosh"),(V ["dish","dash"],"-dosh"),(V ["dish","dash","dosh"],"")]
我正在使用我的数据ReadP
。Read
例如,代码Read
正在运行,但我很困惑。
没有做过复杂的解析,我一直认为运行ReadP
会以单元素列表的形式返回输出[(result,"")]
,显然不是这样。
data Value = V [String]
deriving Show
-- |
-- >>> read "dish-dash-dosh" :: Value
-- V ["dish","dash","dosh"]
--
instance Read Value where
readPrec = readP_to_Prec (const readValues)
- 是否
read
只有在snd
last中没有任何内容时才会成功[(Value,String)]
,此列表中的其他元素在任何地方都未使用?
我知道这样做的替代方法。这个问题完全是关于理解sepBy
输出和它的使用。
解决方案
运行ReadP
将返回所有可能的解析。您可以通过指定解析后应该发生的事情来限制有效解析的数量sepBy1
,例如输入结束或其他一些句法元素。
例如,尝试类似:
readValues = do
xs <- (munch isAlpha) `sepBy1` (char '-')
eof
pure $ V xs
附录...
该ReadS
类型遵循经典 Hutton 和 Meijer 论文Monadic Parsing in Haskell中介绍的 monadic parsing 的发展。从那里的小文档中,我收集到ReadP
实现所有替代方案的并行探索。ReadP
对创建动作有很多支持,而不是ReadS
对. 当我使用该模块时,我刚刚进行了该操作的第一个匹配项(如果它是空列表,则返回一个解析错误。)ReadP
readP_to_S
ReadS
ReadPrec
monad 用于支持优先级,它基本上是——ReaderT Int ReadP
这里Int
是当前的优先级。同样,看起来您从ReadP
解析器开始,然后使用or将其转换为ReadPrec
操作。要运行它,您可以像在案例中一样使用它。lift
readP_to_Prec
readPrec_to_S
ReadP
推荐阅读
- php - 使用 ajax 损坏的二进制下载
- flutter - Flutter - 如何为 TextField 的初始值提供来自 FutureBuilder 的动态值?
- python - discord.ext.commands.errors.CommandInvokeError:命令引发异常:AttributeError:'str'对象没有属性'name'
- electron - Electron.NET:自定义标题栏
- machine-learning - xgboost 回归树的叶值与预测有何关系
- laravel - laravel livewire 删除记录仅在页面刷新后呈现
- javascript - 如何在 JavaScript 中验证 HMAC SHA256?
- vue.js - 为什么内容是空的,但组件中的 JS 可以工作?离子
- java - 在词法分析器规则 Antlr4 中匹配 EOF 标记
- vue.js - Elasticsearch 不接受大小