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 が何をしているかについての本当に良い説明に落ち着きます。