コンパイルプロセス中の字句解析と構文解析は何ですか。前処理は、字句および構文解析の後に行われますか?
5 に答える
このコードを考えてみましょう:
int a = 10;
if (a < 4)
{
printf("%d", a);
}
字句解析フェーズ:各単語/トークンを識別し、それに意味を割り当てます。上記のコードでは、i 、 n、tの順に識別し、次にスペースが単語intであり、それが言語キーワードであることを識別することから始めます。1の後に0が続き、スペースは数字の10などになります。
構文解析フェーズ:コードが言語構文(文法規則)に従っているかどうかを確認します。たとえば、演算子(言語Cを考慮)のLHSに変数が1つしかないかどうか、各ステートメントが;で終了しているかどうかを確認します。、ifの後に条件付き/ブール式などが続きます。
他の人が述べたように、通常、前処理は字句解析または構文解析の前に行われます。
字句解析は、構文解析の前に行われます。マクロを呼び出す必要がある場合は、最初に識別子の境界を識別する必要があるため、これは論理的です。これは字句解析で行われます。その後、構文解析が開始されます。コンパイラは通常、構文解析を開始する前に完全な前処理済みソースを生成していないことに注意してください。彼らは、一度に1つのレキシマを選択してソースを読み取り、必要に応じて前処理を実行し、その結果を構文解析に送ります。
あるケースでは、字句解析は2回行われます。これがペーストバッファリングです。コードを見てください:
#define En(x) Abcd ## x ## x
enum En(5)
{
a, b = 20, c, d
};
このコードは、名前で列挙型を定義しますAbcd55
。マクロ展開中に##
が処理されると、データは内部バッファに配置されます。その後、このバッファは小さな#includeのようにスキャンされます。スキャン中、コンパイラはバッファの内容をレクセマに分割します。スキャンされたレクセマの境界が、バッファに配置された元のレクセマの境界と一致しない場合があります。上記の例では、3つのレクセマがバッファーに配置されていますが、取得されるのは1つだけです。
前処理は、字句解析iircコメントがフィルターで除外される前に行われます。#define、...その後、コンパイラーはスキャナー/字句解析でトークンを生成します(字句解析)。その後、コンパイラーは構文解析用の解析ツリーを生成します
例外はありますが、通常は次のように発生します。
- 前処理-プログラムテキストをプログラムテキストに変換します
- 字句解析-プログラムテキストを「トークン」に変換します。トークンは、基本的に属性が付加された小さな整数です。
- 構文解析-プログラムテキストを抽象構文に変換します
「抽象構文」の定義はさまざまです。ワンパスコンパイラでは、抽象構文はtartgetコードに相当します。しかし、最近では、プログラムの構造を論理的に表すのは通常、ツリーまたはDAGです。
Cプログラミング言語について話しているときは、その言語にISO(ANSI)規格があることに注意する必要があります。これがC99の最後の公開ドラフト(ISO / IEC 9899:1999)です:www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
「5.1.1.2変換フェーズ」のセクションがあり、Cプログラムをどのように解析する必要があるかを示しています。ステージがあります:
...マルチバイト、トリグラフ、およびバックスラッシュ処理のいくつかの手順...
3)。ソースファイルは、前処理トークンと空白文字のシーケンス(コメントを含む)に分解されます。
これは前処理の字句解析です。ここでは、プリプロセッサディレクティブ、句読点、文字列定数、識別子、コメントのみが使用されます。
4)。前処理ディレクティブが実行され、マクロ呼び出しが展開されます
これはそれ自体を前処理しています。このフェーズには、からのファイルも含まれ#include
、その後、前処理ディレクティブ(#define
または#ifdef
その他)が削除されます。
...文字列リテラルの処理..。
7)。トークンを区切る空白文字は重要ではなくなりました。各前処理トークンはトークンに変換されます。結果のトークンは、構文的および意味的に分析され、変換単位として変換されます。
トークンへの変換は、言語キーワードの検出と定数の検出を意味します。これは、最終的な字句解析のステップです。構文的および意味論的分析。
だから、あなたの質問は:
前処理は、字句および構文解析の後に行われますか?
前処理を行うにはいくつかの字句解析が必要なので、順序はlexical_for_preprocessor、preprocessing、true_lexical、other_analysisです。
PS:Real Cコンパイラは少し異なる方法で構成されている場合がありますが、標準で記述されているのと同じように動作する必要があります。