Lex & YACC 3
上で最後に書いた実際の場合について。
実際に使う場合は上の場合よりも複雑になっていき、上記の様な方法だけでは不可能。
ちょっと調べたら、方法は大きく分けて2通りの方法があるみたい(調べた限りではだけど)。
1つはコマンド(BNF)の部分、「heat_switch : TOKHEAT STATE」とか書いている部分でreturnでint値を返す方法。
各値はdefineしておけばいい。
こうするとyyparse()から値が戻るのでこれで判断する。
単純な場合だったらこっちで問題ないはず。
自前で設定ファイルを解析するとか。例えばUnixの/etc以下の設定ファイルだとこれでいけそう。
main部分だけ書けば以下のようなイメージ。
int main(void) { while(1){ ret = yyparse(); if(ret != 0){ fprintf(stderr, "yyparse() error\n"); return 1; } switch(ret){ //ここで解析を行っていく } } return 0; }
もう1つは構文木を一気に作ってしまう方法。
BNFの部分で各コマンド毎にデータをどこかに貯めておく。
普通はmalloc()して動的にデータを作っていけばいい。Lisp見たいにlistを作成していくのがイメージしやすいかな。
実際GCCとかは「RTL」というLisp風の言語に一旦変換している。
C言語とかの本格的な言語とかRubyみたいなインタープリンターを作るんだったらこの方法かな。
取りあえず簡単なのでいいから何かサンプルでも作らないと。
作っていって始めて分かる事もあるしね。