問題タブ [intermediate-code]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
compiler-construction - 優れたシンプルな中間コードはどれですか?
割り当ての目的が、C言語のサブセットで動作するコンパイラーを作成することであるとします(オブジェクトとして複雑なものを持たずに、基本的なスクリプト表現力をサポートするだけで、任意の言語のサブセットを想定できます)。
コンパイラの正しさを検証するために、どのような種類の中間コードを使用できますか?私は教授と話していましたが、彼は「コンパイルされたコード」に使用されるVMとして学生に何を与えるべきかわからなかったという事実について話しました。そのため、どちらが良い解決策になるのか疑問に思いました。
このコードは、バイナリ形式またはASCII形式(疑似asmなど)のいずれかである可能性があります。
この中間コードとVMを構造化する方法ではなく、コンパイル済みプログラムのテストに使用できる簡単でシンプルなものを探しています。
linux-kernel - Ubuntu-8.04 のコンパイル時に中間 .i ファイル (前処理済みファイル) を生成する
gcc 3.4 で ubuntu-8.04 をビルドしています。gcc プリプロセッサの出力である .i ファイルを生成する必要があります。--save-temps フラグを追加しようとしましたが、これは最上位ディレクトリ、つまりソースの .i ファイルのみを生成し、子ディレクトリに再帰的に渡されないようです。前処理されたファイルを出力してコンパイルを停止することになっている -E フラグも試しましたが、これもファイルを生成しませんでした。
具体的には、ソースの .i ファイルを net/core に生成しようとしています。
どんな助けでも大歓迎です。ありがとう!!
perl - スクリプトで事前に解析されたプロトコル定義を使用し、最新の状態に保つ
私の仕事では、バイナリ プロトコルのログ ファイルを処理しなければならないことがあります (ログ ファイルには、メッセージの 16 進ダンプが含まれています)。バイナリ データを解釈して、より使いやすい形式で内容を出力できる Perl スクリプトを作成したいと考えています。
独自の形式でプロトコルメッセージの(機械可読)説明があり、その形式を解析する方法を(ほとんど)理解しました(完全に理解できない部分は私の目標とは関係がないため、無視できますそれら)、スクリプトで使用するために、説明をデータ構造に変換できます。
プロトコルの説明はめったに変更されないため、ログファイルを分析するたびにプロトコルの説明を再解析するのは無駄に思えます。説明の再解析をスクリプトで自動的にトリガーしたいと考えています。
これを実現する最善の方法は何ですか?
parsing - コンパイラで中間コードを生成します。条件を処理する場合、ASTまたは解析ツリーは常に必要ですか?
私は(flexとbisonを使用して)独自のコンパイラーを実装する必要があるコンパイラー設計クラスを取っています。私は構文解析(EBNFと再帰下降パーサーの作成)の経験がありますが、コンパイラーを作成するのはこれが初めてです。
言語デザインはかなりオープンエンドです(教授はそれを私たちに任せました)。クラスでは、教授は中間コードの生成をやり直しました。彼は、構文解析中に抽象構文木や構文解析ツリーを構築する必要はなく、途中で中間コードを生成できると述べました。
私はこれを2つの理由で混乱させました:
定義する前に関数を呼び出している場合はどうなりますか?分岐先をどのように解決できますか?関数を使用する前に関数を定義するか、関数を事前に定義する必要があるというルールを作成する必要があると思います(Cのように?)
条件文をどのように扱いますか?
if-else
、または単にを持っている場合、条件が(進行中にコードを生成している場合)if
の場合の分岐ターゲットをどのように解決できますか?if
false
関数とブランチターゲットのアドレスを解決するために、ASTを生成し、作成後にツリーをウォークすることを計画しました。これは正しいですか、それとも何かが足りませんか?
c - 中間言語の選択
私は現在、プログラミング言語で遊んでいます。私は、高水準言語 (特に Haxe) でパーサーとインタープリターを作成することに時間を費やしてきました。
いくつかの結果が得られましたが、実際には非常に優れていると思いますが、今はそれらを高速化したいと考えています。
私のアイデアは、入力言語を C に翻訳することでした。
私の C の知識は、大学で学んだことだけです。いくつかの演習を除いて、実際の C プログラムを書いたことはありません。しかし、私はそれを機能させることができると確信しています。
もちろん、LLVM のフロントエンドを作成したり、MSIL または JVM バイトコードを生成したりすることもできます。しかし、私は今それを学ぶには多すぎると感じており、実際にはあまり利益が見られません.
また、C は完全に人間が読める言語なので、失敗したとしても、その理由を理解するのはずっと簡単です。そしてCはやはりハイレベル。頭を悩ませることなく、入力言語から概念を実際に翻訳できます。合理的な時間内に何かを稼働させて実行し、適切と思われるように最適化する必要があります。
では、C を使用することの欠点はありますか? 代替案をお勧めできますか?
あなたの洞察をありがとう:)
編集:いくつかの明確化
- 私がずっと下に行きたい理由は、OOPをサポートする言語を書いていて、非常に具体的なことを念頭に置いているので、実際に手でディスパッチするメソッドを実装したいからです。
- 主な使用分野は HTTP サービスの作成ですが、GUI ライブラリ (wxWidgets など) へのバインディングの追加なども想像できます。
parsing - 構文指向の変換を使用せずにコンパイラ フロント エンドを作成する方法はありますか?
私の質問はタイトルと同じです。アクションをパーサーに埋め込むことに依存しない中間コードを取得するための他の変換手法があるかどうかを知りたいだけです (つまり、パーサーは厳密に抽象構文ツリーを作成し、コードを生成しません)。 . 回答ありがとうございます。
c - 中間形式で作業する最も簡単な方法
私が取り組んでいるツールは、コンパイラによって生成された中間形式を取得し、それにいくつかのコードを追加してから、その変更された中間コードをコンパイラのバックエンドに渡して最終的なコードを生成する必要があります。
gcc について少し調べたところ、GIMPLE 形式は理解しやすいことがわかりましたが、GIMPLE コードを変更する複雑さについてはよくわかりません。また、プラグインを使用する以外に、そこからコンパイルを再開する方法もわかりません。独自のパスを追加します。また、ドキュメンテーションが不足しており、gcc での作業に行き詰まると大変なことになると警告されました。
別のオプションは、LLVM バイトコードを使用することです。しかし、私は LLVM を使ったことがないので、LLVM での作業がどれほど複雑になるかわかりません。私が気付いていないより良いオプションがあるかもしれません。したがって、私は最善の選択肢を知りたいだけです。私の好みは次のとおりです。
- プラットフォーム非依存
- 使いやすい
- 十分に文書化されています
- より多くの人が利用できるため、より多くのヘルプを利用できます
c - この LLVM IR コードの問題点
このような LLVM IR コードがあります。
arrayidx1が割り当てられている行では、すべて問題ありませんが、 OldFuncCounter7の場合、LLVM コンパイラは「関数ローカル名の無効な使用」と言って文句を言います。これは、私が使用している %8 が原因です。定数に置き換えると、正常に動作します。私の質問は、 %8 がarrayidx1 では正常に機能するのに、 OldFuncCounter7では機能しない理由です。ここで何が起こっているのですか?
このエラーが発生する基本ブロック全体を以下に示します
c - getelementptr 命令を挿入する
getelementpr
以下に示すように、コードに命令を挿入したいと思います。
どうすればそれを挿入できますか?LoadInst
とStoreInst
クラスのコンストラクターを使用してロードおよびストア命令を挿入できますが、 のコンストラクターGetElementPtrInst
はプライベートと宣言されているため、使用できません。したがって、私の質問は、LLVM パスのコードからこの命令を追加する方法です。
c++ - イテレータの等価性をチェックする方法は?
私のllvm
コードでは、次のコードを使用して、イテレータInsertPosが基本ブロックの最後の命令を指しているかどうかを確認しようとしています。
ただし、clang
次のエラーが表示されます。
これを行う正しい方法は何ですか?