私はハスケルで解析するのが本当に新しいですが、ほとんど意味があります。Parsec:オーバーラッピングパーサーの扱い
私は主に、より良い解析を学ぶためにテンプレートプログラムを構築しています。テンプレートは{{ value }}
表記で値を補間できます。
{{ value }}
This is normal Text
{{ expression }}
私はtemplateFromFile "./template.txt"
を使用して、これを実行すると、私はエラーを取得する:
Left "./template.txt" (line 5, column 17):
unexpected Directive " expression "
ここ
は私の現在のパーサは、その後、私は、このようなファイルの何かにそれを実行し、
data Template a = Template [Either String a]
data Directive = Directive String
templateFromFile :: FilePath -> IO (Either ParseError (Template Directive))
templateFromFile = parseFromFile templateParser
templateParser :: Parser (Template Directive)
templateParser = do
tmp <- template
eof
return tmp
template :: Parser (Template Directive)
template = Template <$> many (dir <|> txt)
where
dir = Right <$> directive
txt = Left <$> many1 (anyChar <* notFollowedBy directive)
directive :: Parser Directive
directive = do
_ <- string "{{"
txt <- manyTill anyChar (string "}}")
return $ Directive txt
です
どうしてこのようなことが起こり、どうすれば修正できますか?
私の基本的な理解は、many1 (anyChar <* notFollowedBy directive)
は、次のディレクティブの開始まですべての文字を取得し、失敗してそのポイントまでの文字リストを返す必要があります。 これは前のmany
に戻り、dir
の解析を再試行して成功する必要があります。明らかに何かが起こっている。私は 問題を解析する方法を考えているの間に他の場合 パーザーはほとんど重複しています。
私はこれをもっともっと慣用的に構造化する方法についていくつかのヒントをお伝えしたいと思います。私が愚かなやり方で何かをしているかどうか教えてください。乾杯!御時間ありがとうございます!
意味があります。私はそれを私が期待していることをするために最善に修正することができますか? –
'txt = many1(notFollowedByディレクティブ*> anyChar)'は、ディレクティブごとに 'ディレクティブ'を2回実行しますが、最も簡単な修正です。 –