2011-02-06 6 views
4

私は現在ANTLRとClojureを貼り合わせており、ANTLRが返す抽象構文ツリー上にClojureジッパーを作成しようとしています。Javaオブジェクトツリー上に作成されたClojureジッパーをzip-filterで使用できますか?

ASTは非常にJava風味のオブジェクトセットで、CommonTreeオブジェクトを使用して階層を表します。

次のように私はCommonTree以上のジッパーを作った:

(defn branch? [tn] (not (zero? (.getChildCount tn)))) 
(defn children [tn] (.getChildren tn)) 
(defn make [tn children] (doto (CommonTree. tn) 
          (.addChildren children))) 

(defn zip-parse [f] (z/zipper branch? children make (parse f))) 

(私はCommonTreeがそのようにノード作りが機能することを100%わからないんだけど、私はまだそれを確認する十分もらっていません。 ...)

私はこのように、これらの関数を使用します。

(def zip-ast (parse testfile)) 

これまでのところ、とても良いです。これは実際に動作します。私は、 "下"、 "右"、 "左"、 "上"の機能でナビゲートすることができます。私は特定のトークンを見つけるためにジップフィルタライブラリを使用しようとすると問題が発生:

(defn token [loc] (-> loc z/node .getToken .getText)) 

(defn token= [tokenname] 
    (fn [loc] 
    (filter #(and (z/branch? %) (= tokenname (token %))) 
      (if (zf/auto? loc) 
       (zf/children-auto loc) 
       (list (zf/auto true loc)))))) 

(defn java-> 
    [loc & preds] 
    (zf/mapcat-chain loc preds #(cond (string? %) (token= %)))) 

これは露骨Chouserの素敵なXML->関数からコピーされます。残念ながら、それはうまくいきません。 zip-filterの内部で、関数 "auto"はオブジェクトにメタデータを追加または削除します。例外的に、の一般的な古いJavaオブジェクトは、メタデータを持つことができません。

私は間違った木を吠えますか?または、(もっと可能性が高い)、私はそれをコピーするのに十分なくらいのフィルタを理解していないのですか?

答えて

2

Zippersは、ノードをラップするlocにmetaとしてメタデータを格納しますが、autoはオブジェクト自体ではなくオブジェクトの周りのラッパー(ベクトル)にメタを追加または削除しているようです。だから、それは問題ではないと私は思う。

"ちょうどうまくいかない"ことについてもっと説明できますか?

フィッシュ・ルックに見える1つの場所は、branch?ファンクションです(カスタムジッパーで私を引きつけました)。最初のandの条件がtoken=であるとチェックするとbranch? - トークンに子がない場合、それはtoken=に一致しません。これは驚くかもしれません。ブランチ?実際にはそれがの可能性があるかどうかを示します。ノードに子があるため、実際に子を持たない場合でもtrueを返すことがあります。これ以外に、私は何も明白ではありません。

注:java->では、1つのオプションしかないので、無名関数を単純化できます。常に文字列であれば、無名関数全体をちょうどtoken=に置き換えることができます。または、文字列以外の場合を処理してnilを返す必要がある場合は、(when (string? %) (token= %))が必要です。

私は実際には、これとは別のルートに沿って過去にほぼ同じ問題を攻撃しました。これはまったく助けてくれるのではないでしょうか。

Clojureでツリーとしてトラバースして修正したい出力を生成するAntlr文法を作成しました。私は最終的にヒットソリューションでした:

  • ANTLR文法 - >
  • ANTLR木文法(不可知論マッサージ、言語) - >
  • (Clojureは固有)ANTLRの文字列テンプレートを生成するために - >
  • 文字列としてClojureのデータ構造 - >
  • ネストされたツリーに(私たちのためにレコードを、しかし何でもすることができる)Clojureのデータ構造を読ん

つの利点これは、Antlr JavaコードがClojureコードに直接依存しない(渡された文字列の形式でのみ)ため、Clojureコードは生成されたJavaコードにのみ依存するということでした。これは、プロジェクトをコンパイルするときに、依存構造を少し簡略化しました(私もこれを達成したと思います)。別の利点は、文法と木文法が言語に依存しないため、ClojureやJavaや他のターゲットを同じ文法から作成できることです(私が実際にやっているわけではありません)。

+0

トークン=の最初の条件の良いキャッチ。それは私が完全に理解していなかったコードをコピーする私のエラーでした。 java->関数は最終的に他の条件をサポートするためのものですが、この問題を理解するために他の述語を取り除いたため、無名関数の縮退した形があります。 全体的に、「うまくいけない」というのは、自動でCommonTreeオブジェクトでwith-metaを実行しようとすると、ClassCastExceptionが発生するということです。 with-metaはIObjのインプリメンタ(Clojureオブジェクト)に対してのみ機能します。 – mtnygard

+0

Antlrを使用して、Clojureデータ構造を表す文字列に "コンパイル"することもできます。クール。おもう。 AntlrのASTオブジェクトとClojure関数の間のインピーダンスの不一致をどのように減少させるかが分かります。どういうわけか、シカゴ経由でサンフランシスコからシアトルへ飛んでいるような気がします。 – mtnygard

+0

エラー.hmmm。スタックトレースの関連部分を投稿できますか?私はオートの上の呼び出しが '子供たちからのものかもしれないと思いますか? –

関連する問題