2

私は非常に簡単な方法でデッドコードリムーバーの刺激を行っています。

そのために私の考えは、

ステップ1:入力Cプログラムを1行ずつ読み取り、二重リンクリストまたは配列に格納します(ファイル操作よりも削除と挿入が簡単になるため)。

疑い:私のアプローチは正しいですか?もしそうなら、毎回リンクリストのトラバースを最小限に抑える方法。

ステップ2:読み取られた文字列の分析は並行して実行され、変数名とその詳細、関数とその呼び出しなどを維持するためにテーブルが作成されます。

ステップ3:変数テーブルの各エントリに対して検索が実行され、変数はその時点の値に置き換えられます(現在の値)。(例えば)

i=0;
if(i==3) will be replaced by if(0==3).

しかし、次のような状況で..

get(a);
i=a;
if(i){} 

ここで、「i」は別の変数に依存するため、置き換えられません。「a」はユーザー入力に依存するため、置き換えられません。

疑い:ユーザー入力がif(5 * 5 + 6){print hello;}の場合、それは確かに不要なチェックになります。この式を解いてコードを単純化するにはどうすればよいですか{printhello; }

ステップ4:文字列はif(0)、while(0)などで検索され、スタックを使用してアクションブロックが削除されます。if(0){//これは削除されます* /}

ステップ5:(例)function foo(){/ ** /} ... if(0)foo(); ...、すべてのデッドコードが削除されると、関数テーブルのfoo()のエントリがチェックされ、コードで参照される回数が取得されます。0の場合、同じスタック方式を使用してその関数を削除する必要があります。

ステップ6:残りの関数では、returnステートメントの下の行(存在する場合)は、「}」を除いて削除されます。この削除は、関数が終了するまで行われます。関数の終わりは、スタックを使用して識別されます。

ステップ7:そして、デッドフリーコードの準備ができたと仮定します。リンクリストまたは配列を出力ファイルに保存します。

私の質問は..1.私の考えが意味があるかどうか?またはそれは実装可能ですか?このアルゴリズムをどのように改善できますか?

2.このアイデアを実装しようとしている間、デッドコードを削除するのではなく、文字列の操作にもっと対処する必要があります。このアルゴリズムで文字列操作を減らす方法はありますか。

4

1 に答える 1

7

このようにしないでください。Cは自由形式の言語であり、行ごとに処理しようとすると、名前に値しないほど途方もなく制限されているCのサブセットをサポートすることになります。

あなたがする必要があるのは、適切なパーサーを書くことです。そこにはそれについてのたくさんの文献があります。あなたの学校がコンパイラ構築コースに使用している教科書を見つけて、それを実行してください-または単にコースを受講してください!パーサーを停止したときにのみ、セマンティクスを検討し始める必要があります。次に、文字列ではなく抽象構文木で作業を行います。または、再利用できるC用に作成およびテスト済みのパーサーを見つけます(ただし、独自の処理と統合するには、かなりの学習が必要です)。

パーサーを自分で作成することになり、それが自分自身の啓蒙のためだけである場合は、主題としてCより​​も単純な言語を使用することを検討してください。C atコアは言語が進むにつれてかなりコンパクトですが、宣言構文のすべての詳細を正しく取得することは驚くほどトリッキーであり、おそらく実際に興味のあるものからあなたを損なうでしょう。そしてプリプロセッサの存在自体が問題です。これにより、意味のあるソースからソースへの変換を設計することが非常に困難になる可能性があります。

ちなみに、スケッチした変換は、業界では「定数伝播」、または(定数入力が異なる場合に関数とループ本体を複製する、より野心的なバリアントでは)「部分評価」として知られています。それらの用語をグーグルで検索するのは興味深いかもしれません。

于 2011-08-27T19:22:23.703 に答える