パーサジェネレーターのアイデア
http://d.hatena.ne.jp/ytqwerty/20050420#p2で何を作ろうとしていたか書いときます。
Adaでinterfaceがまだ使えませんのでinterfaceが使えてジェネレートが楽そうということでD。
program => | mainmethod "." mainmethod => | method' n:#label "method" "," "do" "(" s:statements ")" statements => | statement | order' s:statement ";" ss:statements -- right rec statement => | breakstatement' "break" label:expression | expression expression => | sum sum => | product | add' x:sum "+" y:product -- left rec | sub' x:sum "-" y:product -- left rec divide => | product | div' x:divide "/" y:clause -- left rec product => | clause | mul' x:product "*" y:clause -- left rec clause => | "(" statements ")" | empty' "(" ")" | nullclause' "null" | integer' n:#integer
↑から、↓のような宣言を生成した上で、
interface program { } interface mainmethod { } class method : mainmethod, program { token* n; statements s; } interface statements { } class order : statements, clause, product, sum, divide, expression, statement { statement s; statements ss; } interface statement { } class breakstatement : statement, statements, clause, product, sum, divide, expression { expression label; } interface expression { } interface sum { } class add : sum, expression, statement, statements, clause, product, divide { sum x; product y; } class sub : sum, expression, statement, statements, clause, product, divide { sum x; product y; } interface divide { } class div : divide { divide x; clause y; } interface product { } class mul : product, sum, divide, expression, statement, statements, clause { product x; clause y; } interface clause { } class empty : clause, product, sum, divide, expression, statement, statements { } class nullclause : clause, product, sum, divide, expression, statement, statements { } class integer : clause, product, sum, divide, expression, statement, statements { token* n; }
これらを使って構文木を作り上げるパーサーまで生成する、というもの。
必要に応じて各interfaceに仮想関数なんかの宣言も付け足せるようなの。
Yaccなどは還元の時に呼ばれるコードなども自分で書かないといけませんしね。ずぼら向けパーサジェネレーターということで。