C でおもちゃのプログラミング言語のデモ コンパイラを書いています。
プログラムの読み取りと字句解析の間の別のフェーズでマクロ処理を行うと、どのような問題が発生する可能性がありますか?
C でおもちゃのプログラミング言語のデモ コンパイラを書いています。
プログラムの読み取りと字句解析の間の別のフェーズでマクロ処理を行うと、どのような問題が発生する可能性がありますか?
前述のように、C プリプロセッサは、その言語の制限により、基本的なテキスト変換のみを実行するため、かなり制限されています。一方、Common Lisp のマクロ システムを見ると、メイン言語にマクロ システムを統合することの利点がわかります。これにより、マクロで主要な言語機能を使用できるようになるからです。
簡単な例
(defmacro ntimes (data n)
`(loop for i from 1 to ,n collecting ,data))
(print (ntimes 'a 10))
Result : (A A A A A A A A A A)
この変換はコンパイル時に行われます (独自の AST であるソースの優れた点の 1 つです)。これは、別のプリプロセッサでは実行できませんでした (プリプロセッサにコンパイラのコピーが含まれていない限り!)
「プリプロセッサ」とは、一般に、メイン コンパイラがコードを取得する前にコードを変換するツールを意味します。
つまり、プリプロセッサはそのルールに従ってソースを字句解析 (および場合によっては解析) し、何らかの変換を実行して結果を出力します。メイン コンパイラは、その規則 (プリプロセッサが使用するものとは異なる場合があります)に従って、プリプロセッサの作業の結果を lex し、解析します。
そのため、プリプロセッサがプログラム テキストに重要な変更を加えた場合、最終結果を一目で予測するのは困難になる可能性があります。これは、c プリプロセッサを使用した c にも当てはまりますが、(またはおそらく) 慣習により、かなり予測可能な結果が得られるいくつかの方法でのみプリプロセッサを使用する必要があります。(私は、c プリプロセッサーは完全にチューリングされていると信じています。したがって、デバッグしようとして気が狂わなければ、達成できることに制限はありません。Pavel のコメントを考えると、ループも再帰もスタックもないと認めます。それはそれを殺すようです. ありがとう. あなたはまだ十分に進歩したマクロの山をデバッグしようとして狂気に行くことができます.)