私の質問はタイトルと同じです。アクションをパーサーに埋め込むことに依存しない中間コードを取得するための他の変換手法があるかどうかを知りたいだけです (つまり、パーサーは厳密に抽象構文ツリーを作成し、コードを生成しません)。 . 回答ありがとうございます。
2 に答える
パーサーがある場合、パーサーは、入力ストリームを言語の有効なインスタンスとして「認識する」以上のことを行う必要があります。コンパイラに何かを生成させたい場合は、言語フラグメントが一致するアクティビティに何らかのアクションを関連付ける必要があります。ある意味では、それは「構文指示」以外の何物でもありません。解析段階では、構文しかありません。
基本的に、解析アクションは、「よりコンパイルしやすい」プログラムの表現を構築する必要があります。私はいくつかの基本的な方法しか知りません:
- 仮想マシン命令のセットを生成する
- コンパイラの残りの部分に渡される抽象構文ツリーを構築する
- コードのある種の制御/データ フロー表現を構築します (たとえば、「トリプル」)。
パーサーによって生成された表現には、要素が何らかの直接的な意味解釈を持つリンクされた構造が含まれているという点で、これらはすべて抽象的にはほとんど同じです。暗黙のセマンティクスを持つ構造のこれらのビットは、コンパイラの残りの部分がオフにするものです。
さて、テキストはプログラムの表現です。コンパイラーを Post システム (文字列に対する一連の書き換え規則) として実装することを決定した場合、「解析」プロセス (一種) を完全に回避できます。これらは、「この文字列が表示されたら、この別の文字列に置き換えてください」という形式です。Post システムは確実にチューリングに対応しているため、技術的には、十分に巧妙な一連の文字列書き換え規則を使用して、ソース コードをターゲット プログラムを表す文字列に変換できます。私が知っている誰も、この方法で実際のコンパイラを構築していません。十分に掘り下げれば、これを行うあいまいな技術論文を見つけることができると確信しています。
Post システムで必要とされる文字列の照合は、一種の解析 (たとえば、興味深い構造の認識) であり、元の質問に戻ると合理的に主張することができます。
プログラム変換システム (私はこれらのうちの 1 つを商用で構築しています) は通常、コンパイラ フロント エンドを使用して AST を構築し、AST ツリーからツリーへの書き換えを適用して目的を達成します。それらがこのように構築されている理由は、それらが実際には変装した Post システムだからです。プログラムの任意の AST は文字列 (たとえば、S 式) に自明に変換でき、ツリーの書き換えは同等の文字列の書き換えに変換できます。つまり、ツリー書き換えシステムは単なる Post システムですが、それが非常に強力なのです。もちろん、この機能を他の従来のコンパイラ方法と組み合わせることができます。これは、私たちの製品で行っていることです。これにより、より便利になります。ポストシステムとしてすべてを行う必要はありません。
あなたが説明しているのは、実際には標準のコンパイラ設計です。解析中にオブジェクト コードを生成するワンパス コンパイラを作成することは可能であり、実際に私はそうしましたが、通常は、パーサーが AST を生成し、その後の AST のトラバーサルが出力または多くの場合、トリプル、RTL などのさらなる中間形式。