プログラマーができることは、メタでできる *目次 [#w23afd46] #contents *趣旨 [#h2c82c7a] メタプログラミングに関する考察をメモする *情報にはレベルがある [#t4cc350d] 単語の羅列 ・ ・ ・ 知識 知恵 メタプログラミングは 知恵をアクセス可能な状態にすることを目標にしなければならない。 *インテンションプログラミング [#w842102a] *CiSE [#j5e6b0d9] C In S-Expression **本物のマクロ”でCのコード行数を半分に! [#y020f90e] テキスト形式 http://ll.jus.or.jp/2009/slide/beforeafter/lltv-beforeafter-shiro/slides/lltv.html プレゼンのリポート形式 http://www.atmarkit.co.jp/news/200909/07/lltv02.html ***考察 [#n37efef8] これは、数年前、研究段階だと発表された記事で、その後どうなっているかは不明。 でも、インテンショナルプログラミングをするためのヒントが書かれていると思う箇所があったのです。 それはなにかというと、インテンショナルプログラミングのwikiの説明 http://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%83%86%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0 のなかに、 「1 から 10 までの数を表示する」と意図を記述すると、下記のコードと同等のコードが得られると書いてある for (int i = 1; i <= 10; i++) { System.out.println("the number is " + i); } この記事と、本物のマクロ”でCのコード行数を半分に!で紹介されている問題点3の記事が似ているのだ。 抜粋すると int i; : for (i = 0; i < (int)clen; i++) putchar((unsigned char)s[i]); for (int i = [0..clen]) { putchar(...) } とか書けたらなあ である。これは、C言語の無駄な記述をとらえたものである。 ちなみに、シモニー氏の記述は <<print the numbers 1 to 10>> である。 forすらない、シンプルな記述だ。 チャールズシモニーは、意図をコードに展開するというアプローチでこの考えに達したのだろうとおもうが、この記事を書いている人は、もともとあるコードをみて、それを人間の理解しやすい形式にコンパクトにまとめるというアプローチで到達したものと考えられる。 そして、これはLisp系のマクロ(本物のマクロと称している)を使えば可能であるとしている。 なかなかいいアプローチだとおもう、1対1に対応する、S式の表現をほぼそのままの表現を保てば、lispのマクロを使って展開することができる。 問題はS式表現風に元のコードを解析し、逆にS式を対象とするC言語とかに変換する必要がある。 *Haskell [#y1894caa] 岡田さん(NTTデータ)からは、「Cobol meets Haskell」と題して、Cobolで書かれた大規模レガシーソフトウェアのリバースエンジニアリングツールの開発運用にHaskellを使った事例が報告された。 とういう記事があった。 http://www.infoq.com/jp/articles/FunctionalProgramming_20111005 Haskellは構文解析ツールStrafunskiの利用と相俟って言語処理に非常にパワーを発揮する。 これは、マクロを使う組み合わせだから、ちょっと調べてみたい。 *Strafunski [#ta75133f] ポルトガル語のページはあった http://www.slideshare.net/UlissesCosta/static-code-analyzer-part-iii **2013年11月22日に講演会があるみたい [#id74cb80] http://pop.msi.co.jp/userconf/2013/index.html ***すでに講演された記事を発見 [#q91d870a] http://d.hatena.ne.jp/hiratara/20110917/1316220155 ああ、TERASOLUNAでだすのか。。。 http://www.zipc.com/event/uc/18th_files2/01-tomiyasu.pdf *処理の流れ [#te027e65] 前処理 : コメントの削除など。 sglr : 構文解析。解析する言語ごとのSDFファイルを作る。 Strafunski : Haskell で扱えるようなデータにする。ただし、ここではまだ言語依存 抽象構文木変換 : 言語非依存の木にする 解析変換 : 成果物の形にする 解析変換では構文木をルールで変換 変数名を日本語台帳で日本語にする。 記述順から処理順に変換する 論理式や算術式を簡約にする Strafunski にて探索を行う **Parsing Lisp into C++ [#rd8b7611] ネットでも同様のことをしようとしたと思われる人が、ANTLRを使ってこころみてみようとしていたのを見つけた。 ***URL [#hc882cb7] http://antlr.1301665.n2.nabble.com/Parsing-Lisp-into-C-td3724626.html ***コード [#wff0acc4] Input: (defun foo (x y) (progn (+ x 1) (+ y 1))) Grammar: program: (sexpr)* -> ^(PROGRAM sexpr*); sexpr: QT?(list|atom) ; list: '(' ')' | '(' members ')' -> ^(LIST members); members: (sexpr)+; atom: OPERATOR | ID | num | STRING ; num : (n=INT|n=FLOAT) -> ^(NUM $n); AST Output: PROGRAM LIST defun foo LIST x y LIST progn LIST + x 1 LIST + y 1 Desired Output: PROGRAM FUNCTION foo ARGS x y BLOCK + x 1 + y 1