Haskell には、何かを解析する主な方法が 2 つあります。解析コンビネーターまたはパーサー ジェネレーターです。あなたはすでに BNF を持っているので、後者をお勧めします。
良いものはアレックスです。GHC のパーサー IIRC はこれを使って書かれているので、あなたは良い仲間になるでしょう。
次に、解析するデータ宣言の大きなクラクション スタックがあります。
data JavaClass = {
className :: Name,
interfaces :: [Name],
contents :: [ClassContents],
...
}
data ClassContents = M Method
| F Field
| IC InnerClass
式など、必要なものは何でも。最後に、これらを次のようなものに結合します
data TopLevel = JC JavaClass
| WhateverOtherForms
| YouWillParse
TopLevel
これを取得すると、解析するクラス/ファイルの数に応じて、AST全体が1つまたはそれらのリストとして表されます。
ここから先に進むには、何をしたいかによって異なります。syb
非常に簡潔なツリーのトラバーサルと変更を記述できる (ボイラープレートを破棄する)などのライブラリが多数あります。lens
もオプションです。少なくともチェックアウトしData.Traversable
てくださいData.Foldable
。
ツリーを変更するには、次のような簡単なことを行うことができます
ignoreInnerClasses :: JavaClass -> JavaClass
ignoreInnerContents c = c{contents = filter isClass $ contents c}
-- ^^^ that is called a record update
where isClass (IC _) = True
isClass _ = False
そして、次のようなものを潜在的に使用できsyb
ます
everywhere (mkT ignoreInnerClass) toplevel
これはすべてをトラバースし、ignoreInnerClass
allに適用されますJavaClasses
。これはlens
、他の多くのライブラリでも実行できますが、syb
非常に読みやすいです。