新しい関数定義を受け入れる機能を備えた電卓を書いています。フィボナッチなどの再帰関数を試す初心者の必要性を認識し、電卓でFlex + Bisonを使用して末尾再帰関数を認識し、コードを反復形式に変換できるようにしたいと思います。私はその仕事をするためにFlex&Bisonを使用しています。ヒントやアイデアがあれば、温かく歓迎します。ありがとう!
編集:
Flex&BisonからのCまたはC++出力について心配する必要はありません。主にアイデアやヒントが欲しいです。ありがとう。
新しい関数定義を受け入れる機能を備えた電卓を書いています。フィボナッチなどの再帰関数を試す初心者の必要性を認識し、電卓でFlex + Bisonを使用して末尾再帰関数を認識し、コードを反復形式に変換できるようにしたいと思います。私はその仕事をするためにFlex&Bisonを使用しています。ヒントやアイデアがあれば、温かく歓迎します。ありがとう!
Flex&BisonからのCまたはC++出力について心配する必要はありません。主にアイデアやヒントが欲しいです。ありがとう。
私のコメントで示唆したように、これはレクサーにとってはまったく問題ではなく、パーサーにとってはおそらくわずかに問題です。次のような関数がある場合:
func f( a )
if ( a == 0 )
return a
return f( a - 1 )
次に、一般的なCコンパイラの場合、その再帰呼び出しをループに変換するのはオプティマイザー/コードジェネレーター次第です。もちろん、解釈計算機では、はるかに柔軟にすることができますが、それでも、最初のプロセスではなく、末尾呼び出しの削除を実行する必要がある最後のプロセスの1つであることをお勧めします。
私がいつも聞いているアドバイスは次のとおりです。代わりに末尾呼び出しの検出を実装できる場合は、末尾再帰の検出を実装しないでください。多くのメソッドは、それ自体の呼び出しよりも別のメソッドの呼び出しで終了します。
コールスタックがエンドユーザー/開発者にとって重要でない場合(つまり、Javaで末尾呼び出しを削除すると、非常に巧妙に処理されない限り、スタックトレースの値の多くが無効になります)、代わりにこのルートを確認する必要があります。
あなたが関数を持っているとしましょう...
def func(args)
#stuff
return func(otherargs)
次に、ASTにはreturn-> func-> otherargsのようなものがあり、型などに関する注釈が付いていることに注意してください。それを歩いて、Fが現在の関数フレームであるリターンFが存在することに気付くと、スタックフレームなどを完全に形成する代わりに、それをPUSH ARGS、GOTOFに変換できます。戻り値を自分でいじる必要があります。
また、マルチパスシステムを使用する代わりに、ウォークアンド実行する場合は、これが大幅に難しくなることに注意してください。私の本能は、ウォークアンドエグゼキュートには先読みが必要であることを示唆しています。
そして、いいえ、私はバイソンがパーサーを連鎖させずにあなたのためにこれを行うとは思わない。コンテキスト依存の方法でセマンティクスを分析しています。