我正在尝试使用 uu_parsinglib 创建一个 Monadic 解析器。我以为我已经涵盖了,但我在测试中得到了一些意想不到的结果
我的解析器的一个精简示例是:
pType :: Parser ASTType
pType = addLength 0 $
do (Amb n_list) <- pName
let r_list = filter attributeFilter n_list
case r_list of
(ASTName_IdName a : [] ) -> return (ASTType a)
(ASTName_TypeName a : [] ) -> return (ASTType a)
_ -> pFail
where nameFilter :: ASTName' -> Bool
nameFilter a =
case a of
(ASTName_IDName _) -> True
(ASTName_TypeName _) -> True
_ -> False
data ASTType = ASTType ASTName
data ASTName = Amb [ASTName']
data ASTName' =
ASTName_IDName ASTName
ASTName_TypeName ASTName
ASTName_OtherName ASTName
ASTName_Simple String
pName 是一个模棱两可的解析器。我想要类型解析器做的是应用一个后过滤器,并返回所有满足 nameFilter 的替代方案,包装为 ASTType。
如果没有,它应该会失败。
(我意识到如果列表中有多个有效匹配项,我给出的示例将失败,但该示例服务于它的目的)
现在,据我所知,这一切都有效。问题在于当您在更复杂的语法中使用它时,似乎会出现奇怪的匹配。我怀疑问题是 addLength 0 部分
我想做的是将单子和应用部分分开。使用过滤组件创建一元解析器,然后使用 <**> 运算符应用 pName。
或者
对于 addLength 正在做什么,我会接受一个非常好的解释。