JavaCCを使用して、さまざまな式を処理できる単純なコマンドライン計算機を構築しようとしています。文法の書き方についてはたくさんのチュートリアルがありますが、これまでに見たもののどれも、その後に何が起こるかを説明していません。
私が今理解しているのは、文字列がパーサーに渡された後、それはトークンに分割され、解析ツリーに変換されるということです。次は何が起こる?各ノードのコンテンツに対して一連のif-else文字列比較を実行して解析ツリーをトラバースし、適切な機能を実行しますか?
JavaCCを使用して、さまざまな式を処理できる単純なコマンドライン計算機を構築しようとしています。文法の書き方についてはたくさんのチュートリアルがありますが、これまでに見たもののどれも、その後に何が起こるかを説明していません。
私が今理解しているのは、文字列がパーサーに渡された後、それはトークンに分割され、解析ツリーに変換されるということです。次は何が起こる?各ノードのコンテンツに対して一連のif-else文字列比較を実行して解析ツリーをトラバースし、適切な機能を実行しますか?
ScottStanchfieldのANTLR3.xチュートリアルをご覧になることを強くお勧めします。ANTLRを使用することにならない場合でも、プロジェクトにとってはやり過ぎかもしれませんが、私はそれを疑っています。彼が思考プロセスを経るのを見ると、多くのことを学ぶことができます。
一般的に、プロセスは...
一部のパーサジェネレーター(YACCなど)では、アクションを文法内に配置できるため、特定のプロダクションを適用するときに、そのプロダクション中に定義されたアクションを適用することもできます。
例:YACC:
E: NUM + NUM {$$ = $1.value + $2.value};
NUMの値を追加し、結果を非終端記号Eに返します。
JavaCCで何ができるかわからない。
あなたは実際にあなたが必要とするものに従ってそれをコンパイルまたは解釈する必要があります。
電卓の場合は、ツリーに再帰的にアクセスして解析されたツリーを評価する必要がありますが、より複雑な言語では、アセンブリのような中間言語に変換する必要がありますが、基盤となるアーキテクチャからの抽象化は維持されます。
もちろん、言語をコンパイルする一連の命令を実行できる独自の単純なVMを開発することもできますが、その場合はやり過ぎになります。解析ツリーにアクセスするだけです。何かのようなもの:
enum Operation {
PLUS, MINUS
}
interface TreeNode {
float eval();
}
class TreeFloat implements TreeNode {
float val;
float eval() { return val; }
}
class TreeBinaryOp implements TreeNode {
TreeNode first;
TreeNode second;
Operation op;
float eval() {
if (op == PLUS)
return first.eval()+second.eval();
}
次に、ツリーのルートでeval関数を呼び出すだけです。セマンティックチェックが必要になる可能性があります(変数などを計画している場合は、シンボルテーブルの構築も必要です)。
各ノードのコンテンツに対して一連のif-else文字列比較を実行して解析ツリーをトラバースし、適切な機能を実行しますか?
いいえ、計算機を実装するために解析ツリーを構築する必要はありません。新しいノードオブジェクトを作成するコードの部分で、計算を実行して数値を返すだけです。
JavaCCでは、プロダクションのリターンタイプを選択できるため、リターン番号だけを用意してください。