プロジェクト用の単純なテキストテンプレート言語用のパーサーを作成しています。uu-parsinglibのコンビネータopt
(重要な場合はバージョン2.7.3.2)を完全に塞いでいます。どのように正しく使用するためのアイデアですか?uu-parsinglibで `opt`コンビネータを使用しています
ここに私の苦境を示す非常に単純化された例があります。
{-# LANGUAGE FlexibleContexts #-}
import Text.ParserCombinators.UU hiding (pEnd)
import Text.ParserCombinators.UU.Utils
import Text.ParserCombinators.UU.BasicInstances
pIdentifier :: Parser String
pIdentifier = pMany pLetter
pIfClause :: Parser ((String, String), String, Maybe (String, String), String)
pIfClause = (,,,) <$> pIf <*> pIdentifier <*> pOptionalElse <*> pEnd
pIf :: Parser (String, String)
pIf = pBraces ((,) <$> pToken "if " <*> pIdentifier)
pOptionalElse :: Parser (Maybe (String, String))
pOptionalElse = (((\x y -> Just (x, y)) <$> pElse <*> pIdentifier) `opt` Nothing)
pElse :: Parser String
pElse = pBraces (pToken "else")
pEnd :: Parser String
pEnd = pBraces (pToken "end")
main :: IO()
main = do
putStrLn $ show $ runParser "works" pIfClause "{if abc}def{else}ghi{end}"
putStrLn $ show $ runParser "doesn't work" pIfClause "{if abc}def{end}"
最初の文字列を正しく解析しますが、2番目はエラーで失敗します。opt
ため
main: Failed parsing 'doesn't work' :
Expected at position LineColPos 0 12 12 expecting one of [Whitespace, "else"] at LineColPos 0 12 12 :
v
{if abc}def{end}
^
ありがとう、私はそれを試みたと思ったが、明らかにそうではなかった。 "<|> pure Nothing"が動作します。 –