ANTLRWorksが余りに凄いので、今日はANTLRWorks記念日。
ANTLRWorksの使い方がようやく分ったので、結局、ANTLRを使う事に。
コンパイラの知識らしい知識を全く持たずに、どこまでいけるか頑張ってみる。
目標は、2WaySQLのパーサを実装する事。
単独でどれだけの価値が、とか、需要が、とかそういう事は知らない。聞かない。
オレオレ言語を作る為の学習なのです。
実装の方針としては、
- SQL文としてパースする事は基本しない。*1
- 特にキチンと設計とか、あんま考えない。行き当りバッタリでやる。
- 最後に、「うぼぁぁっ!!無理じゃぁぁっ」ってなったら、やり直す。
- ANTLRでASTを構築
- Visitorを自前実装して、Walkする。
- tree grammarが上手く使えたらそれはそれでいいんだけどな…ポワワ
大体そんな風に考えていたり。
まずは、食わせた文字列を、コメント部分と、それ以外に分ける様なパーサ。
grammar Comment; options { language = Java; output = AST; ASTLabelType = CommonTree; } queries : query EOF ; query : (charactors | whitespaces | comment | LT)+ ; charactors : (CHAR)+ ; whitespaces : (WHITESPACE)+ ; comment : (blockcomment | linecomment) ; blockcomment : '/*' (charactors | whitespaces | LT)+ '*/' ; linecomment : '//' (charactors | whitespaces)+ (LT|EOF) ; CHAR : ('0'..'9'|'a'..'z'|'A'..'Z') ; LT : '\n' // Line feed. | '\r' // Carriage return. | '\u2028' // Line separator. | '\u2029' // Paragraph separator. ; WHITESPACE : '\t' | '\v' | '\f' | ' ' | '\u00A0' ;
ANTLRのv3系では、頭が大文字始まりだと、Lexerが食べて、小文字始まりだと、Parserが食べるらしい。
Parser用の定義の中に、テキトーにリテラルっぽく混ぜると、それはそれで自動的に無名のトークンにしてくれるらしい。
これはすごい。
こいつに、こんな文字を食わせてみる。
a /*aa hoge piro*/ fuga //moge
おお…スバラシ。何かツリーが出来た。これなら、ヘタレの僕でもオレオレ言語作れそう。多分。
今回のポイントは、色んなトコに出てくる、+かな。
気分的には、無くてもいいから、*にしてたら、パーザがスタックオーバーフローで死んだ。
前に何も無くて、*は、ダメな子がやる落とし穴って事らしい。
*1:難しくなり過ぎる為