たぷつきません

おなかがでてきた。もうたぷついてるやん。

はじめてTree作成できた

 Lexer/Parserは作成できてたのに、Treeだけは中々できなかったところ、はじめて出力できた(変換ができた…というだけで実際に動くかどうか分からないけど)。
なぜできなかったか理由を列挙しておく。

  • まずLexerの定義*1は全て消す。Lexerのコメント宣言(@lexer::header)も消す。
    • これを先にしておかないとヌルポの嵐
  • (Lexer/Parser).g をジェネレートした結果に含まれる、(Lexer/Parser).tokens が tree.g と同じ場所にいないといけない
    • 結局、.g も geneate先もソースも全て同じディレクトリじゃないとダメ。javaとresourcesを分けたいのになー。
  • (Lexer/Parser)のチェックとジェネレートでは、リライトのチェックが不十分で、ミスがあっても作成できてしまう。しかしtreeではアウト。
    • これにはまった。ミスがあっても(Lexer/Parser)でASTツリーがちゃんと作れる(リライトがちゃんと適用される)ので気付きにくい。

例えば以下のようなことになる。

// for Parser: ジェネレートOK
binding :       '='     -> ^('=')
        |       'in'    -> ^('in')
        ;
// for Tree: ジェネレートNG
binding :       ^('=')
        |       ^('in')
        ;
// for Tree: ジェネレートOK
binding :       ^('binding' '=')
        |       ^('binding' 'in')
        ;


Parsarの場合は中間のbindingという要素を省略して一足飛びができるが、Treeだと許されないということらしい。
…それより、はてなシンタックスハイライト、antlrにまで対応しているとは。まにあっくだな。

追記

 というか、^(...) は、「先頭の文字列をラベルにもつ親ノードとして、そこに以降を属させる」の意味だから当たり前だった。bindingノードを作りたくない場合は、以下で良いんじゃない。

// for Tree: ジェネレートOK
binding :       '='
        |       'in'
        ;

*1:頭文字が大文字の識別子