monadic解析与uu-parsinglib

时间:2013-08-16 08:55:36

标签: parsing haskell monads uu-parsinglib

我正在尝试使用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部分

我想做的是分离出monadic和applicative部分。使用过滤组件创建一个monadic解析器,然后使用&lt; **&gt;应用pName。操作

替代地

我很乐意解释addLength正在做什么。

1 个答案:

答案 0 :(得分:1)

我已经整理了一个软糖/解决方法,用于使用uu-parsinglib进行monadic解析。我使用Monadic解析器的唯一方法是分析过于慷慨的初始解析器,并选择性地使其结果失败。

bind' :: Parser a -> (a -> Parser b) -> Parser b
bind' a@(P _ _ _ l') b = let (P t nep e _) = (a >>= b) in P t nep e l'

使用此解析器时要记住的重要事项是

a -> M b

必须不消耗任何输入。它必须返回a的转换版本,或者失败。

警告

目前对此的测试仅为最小,并且其行为不是按类型强制执行的。这是一种软糖。