パーサジェネレーターのアイデア
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などは還元の時に呼ばれるコードなども自分で書かないといけませんしね。ずぼら向けパーサジェネレーターということで。