英語フランス語スペイン語

OnWorksファビコン

gpp - クラウド上のオンライン

Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、または MAC OS オンライン エミュレーター上の OnWorks 無料ホスティング プロバイダーで gpp を実行します。

これは、Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、または MAC OS オンライン エミュレーターなどの複数の無料オンライン ワークステーションの XNUMX つを使用して、OnWorks 無料ホスティング プロバイダーで実行できるコマンド gpp です。

プログラム:

NAME


GPP - 汎用プリプロセッサ

SYNOPSIS


gpp [-{o|O} アウトファイル] [-私/インクルード/パス] [-NS名前=val ...]
[-z|+z] [-x] [-m] [-C|-T|-H|-X|-P|-U ... [-M ...]]
[-n|+n] [+c str1 str2] [+s str1 str2 c]
[-NS str1] [--nostdinc] [--nocurinc]
[--curdirinclast] [--warninglevel n]
[--インクルードマーカー STR] [ - 含む file]
[ファイル内]

gpp --ヘルプ

gpp --バージョン

DESCRIPTION


GPP は、カスタマイズ可能な構文を備えた汎用プリプロセッサであり、幅広い用途に適しています。
前処理タスクの。 プログラミング言語から独立しているため、さらに優れた機能が得られます。
cpp よりも多用途であり、その構文は m4 よりも軽量で柔軟です。

GPP は、cpp が適さない、または cpp が適さないすべての一般的な前処理タスクを対象としています。
非常に高度な機能が必要となります。 同等に効率的に処理できるようにするために
さまざまな言語のテキスト ファイルやソース コードに対応し、GPP で使用される構文は完全に
カスタマイズ可能。 コメントと文字列の処理は特に高度です。

当初、GPP は、と呼ばれる最小限の組み込みマクロ セットのみを理解します。 メタマクロ.
これらのメタマクロにより、次の定義が可能になります。 user マクロ いくつかの基本的な操作と同様に
条件付きテスト、算術演算など、前処理システムの中核を形成します。
評価、ワイルドカード マッチング (グロビング)、および構文の仕様。 全ユーザーマクロ
定義はグローバルです -- すなわち、明示的に削除されるまで有効です。 メタマクロ
再定義することはできません。 各ユーザー マクロ定義について、GPP は対応するマクロ定義を追跡します。
構文の仕様を変更することで、後続の設定に関係なくマクロを安全に呼び出すことができます。
動作モードの変更。

マクロに加えて、GPP はコメントと文字列を理解します。その構文と動作は次のとおりです。
特定の目的に合わせて幅広くカスタマイズできます。 内部的にはコメントと文字列は
同じ構造なので、コメントに適用されるものはすべて文字列にも適用されます。

OPTIONS


GPP は、次のコマンドライン スイッチとオプションを認識します。 -nostdinc、
バージョン 2.1 以降の -nocurinc、-curdirinclast、-warninglevel、および -includemark オプション
それ以前のバージョンは非推奨であるため、使用しないでください。 代わりに「長いオプション」のバリアントを使用してください
(--ノストディンク、 等々).

-h - 助けて
短いヘルプ メッセージを印刷します。

- バージョン
バージョン情報を印刷します。

-o アウトファイル
すべての出力を送信するファイルを指定します (デフォルトでは、すべてが送信されます)
標準出力に)。

-O アウトファイル
すべての出力を送信するファイルを指定します。 出力は同時に送信されます
stdout。

-I/インクルード/パス
パスを指定します。 #include メタマクロは、インクルードファイルが存在する場合、インクルードファイルを探します。
現在のディレクトリには存在しません。 デフォルトは / usr / include いいえの場合 -I
オプションが指定されています。 複数の -I オプションを指定して、複数の項目を調べることができます。
ディレクトリ。

-D名前=val
ユーザーマクロを定義する 等しいとして ヴァル。 これは厳密に次の使用と同等です。
  #定義する メタマクロですが、コマンドからマクロを定義できるようになります。
ライン。 もし ヴァル 引数または他のマクロを参照する場合、以下に準拠する必要があります。
コマンドラインで指定されたモードの構文。 バージョン 2.1 以降、
マクロ引数の命名はコマンドラインで許可されます。 構文は次のとおりです。
-Dマクロ(arg1、...)=定義。 引数は C スタイルの構文で指定されます。
空白は含まれませんが、定義は引き続き次の構文に準拠する必要があります。
コマンドラインで指定されたモード。

+z テキスト モードを Unix モード (LF ターミネータ) に設定します。 入力内の CR 文字はすべて
組織的に廃棄される。 これは Unix システムのデフォルトです。

-z テキストモードをDOSモード(CR-LFターミネータ)に設定します。 このモードでは、すべての CR 文字が
入力から削除され、すべての出力 LF 文字が CR-LF に変換されます。 これ
GPP が WIN_NT オプションを使用してコンパイルされている場合のデフォルトです。

-x の使用を有効にします。 #exec メタマクロ。 以来 #exec の出力が含まれます
任意のシェル コマンド ラインを使用すると、潜在的なセキュリティ上の脅威を引き起こす可能性があるため、
このオプションが指定されない限り無効になります。

-m 名前が指定されている場合、cpp 互換モードへの自動モード切り替えを有効にします。
インクルードされたファイルは `.h' または `.c' で終わります。 これにより、C ヘッダーをインクルードできるようになります。
わずかな変更のみを加えたファイル。

-n 次の場合に、改行文字または空白文字が入力から削除されないようにします。
これらはマクロ呼び出しまたはコメントの終わりとして発生します。 デフォルトでは、改行の場合、
または空白文字はマクロまたはコメントの終わりを形成し、一部として解析されます
マクロ呼び出しまたはコメントであるため、出力から削除されます。 -n オプションを使用する
入力ストリームの最後の文字が空白または改行の場合、それを保持します。
これは、cpp モードと Prolog モードで有効になります。

+n -n の反対。 これは、cpp と Prolog を除くすべてのモードのデフォルトです。 注記
+n を配置する必要があること After 何らかの効果を発揮するには、-C または -P を使用します。

-U arg1 ... arg9
ユーザー定義モード。 次の XNUMX つのコマンドライン引数は次のように解釈されます。
それぞれ、マクロ開始シーケンス、マクロ終了シーケンス、
引数、引数の開始シーケンス、引数の区切り記号、引数の終了
シーケンス、引数のバランスをとるためにスタックする文字のリスト、
スタックを解除する文字、引数を参照するために使用される文字列
数値、最後に引用符文字 (何もない場合は空の文字列にする必要があります)
提供された)。 これらの設定は、ユーザー マクロとメタ マクロの両方に適用されます。
-M オプションは、メタマクロの他の設定を定義するために使用されます。 のセクションを参照してください。
詳細については、構文の仕様を参照してください。

-M arg1 ... arg7
メタマクロのユーザー定義モード仕様。 このオプションはのみ使用できます
-Mと一緒に。 次の XNUMX つのコマンドライン引数は次のように解釈されます。
それぞれ、マクロ開始シーケンス、マクロ終了シーケンス、
引数、引数の開始シーケンス、引数の区切り記号、引数の終了
シーケンス、引数のバランスをとるためにスタックする文字のリスト、および
スタックを解除する文字。 詳細については、以下を参照してください。

(デフォルト モード)
デフォルトのモードは漠然と cpp に似たモードですが、コメントは処理されません。
cpp とのさまざまな非互換性が存在します。 典型的なメタマクロとユーザーマクロ
このように見えます。

#xy を定義する
マクロ(引数,...)

このモードは以下と同等です

-U "" "" "(" "," ")" "(" ")" "#" "\\"
-M "#" "\n" " " " " "\n" "(" ")"

-C cpp互換モード。 これは GPP の動作が最も近いモードです。
cppのこと。 デフォルト モードとは異なり、メタ マクロ展開は、
行頭、C のコメントと文字列は理解されます。 このモードは
に相当

-n -U "" "" "(" "," ")" "(" ")" "#" ""
-M "\n#\w" "\n" " " " " "\n" "" ""
+c "/*" "*/" +c "//" "\n" +c "\\\n" ""
+s "\"" "\"" "\\" +s "'" "'" "\\"

-T TeX 風のモード。 このモードでは、一般的なメタ マクロとユーザー マクロは次のようになります。

\define{x}{y}
\マクロ{引数}{...}

コメントは理解されません。 このモードは以下と同等です

-U "\\" "" "{" "}{" "}" "{" "}" "#" "@"

-H HTML に似たモード。 このモードでは、一般的なメタ マクロとユーザー マクロは次のようになります。

<#define x|y>
<#マクロ引数|...>

コメントは理解されません。 このモードは以下と同等です

-U "<#" ">" "\B" "|" 「">」「<」「>」「#」「\\」

-X XHTML に似たモード。 このモードでは、一般的なメタ マクロとユーザー マクロは次のようになります。

<#define x|y/>
<#マクロ引数|.../>

コメントは理解されません。 このモードは以下と同等です

-U "<#" "/>" "\B" "|" "/>" "<" ">" #" "\\"

-P Prolog 互換の cpp のようなモード。 このモードは cpp 互換モードとは異なります
コメントの処理により、次と同等です

-n -U "" "" "(" "," ")" "(" ")" "#" ""
-M "\n#\w" "\n" " " " " "\n" "" ""
+ccss "\!o/*" "*/" +ccss "%" "\n" +ccii "\\\n" ""
+s "\"" "\"" "" +s "\!#'" "'" ""

+c str1 str2
コメントを指定します。 引用符で囲まれていないもの str1 として解釈されます
コメントの始まり。 次の最初の出現までのすべての入力 str2 意志
捨てられる。 このオプションは、さまざまなタイプを指定するために複数回使用できます。
コメント区切り文字。 オプションのパラメータ を変更するために指定できます。
コメントの動作と、 マシン情報の記入> という構文でなければなりません。例えば、、それを文字列に変換するか、以下で無視します。
特定の状況については、以下を参照してください。

-c str1
コメントまたは文字列の指定を解除します。 開始するコメント/文字列仕様
シーケンスは str1 が削除されます。 これは、組み込みのコメントを変更するのに役立ちます
標準モードの仕様 -- マシン情報の記入> という構文でなければなりません。例えば、、cpp互換モード。

+s str1 str2 c
文字列を指定します。 引用符で囲まれていないものは、 str1 として解釈されます
文字列の先頭。 次の最初の出現までのすべての入力 str2 意志
評価せずにそのまま出力します。 区切り文字自体が出力されます。 もし c
空ではない場合、その最初の文字は 文字列引用符 文字 -- すなわち
が発生する直前に存在する文字 str2 それを防ぐ
文字列を終了します。 オプションのパラメータ を変更するために指定できます。
文字列の動作と、 マシン情報の記入> という構文でなければなりません。例えば、、コメントに変換し、マクロ評価を有効にします
文字列内で指定するか、特定の条件下で文字列指定を無視するようにします。
状況。 以下を参照してください。

-s str1
コメントまたは文字列の指定を解除します。 -c と同じ。

- 含む file
プロセス file ファイル内

--nostdinc
標準ディレクトリ /usr/include でインクルード ファイルを検索しないでください。

--ノクリン
現在のディレクトリでインクルード ファイルを検索しないでください。

--カーディリンクラスト
現在のディレクトリでインクルード ファイルを探します After で指定されたディレクトリ
-I 彼らの前ではなく。

--警告レベル n
警告レベルをに設定します n (0、1、または 2)。 デフォルトは 2 (最も冗長) です。

--インクルードマーカー STR
追跡しておく #include 出力ストリームにマーカーを挿入してディレクティブを実行します。 の
マーカーの形式は次によって決まります。 STR、これには次の XNUMX つの出現が含まれている必要があります。
キャラクター % (または同等の ?)。 最初に出現した部分は次の行に置き換えられます。
番号、1 番目はファイル名、2 番目は XNUMX、XNUMX、または空白です。 こうなると
オプションがデフォルト、cpp または Prolog モードで指定されている場合、GPP は次のことを保証するために最善を尽くします。
空白を挿入することで、出力でも入力でも行番号が同じになるようにする
定義またはコメントの代わりに行を追加します。

ファイル内 GPP が入力を読み取る入力ファイルを指定します。 入力ファイルがない場合は、
指定された場合、入力は標準入力から読み取られます。

構文 仕様


マクロ呼び出しの構文は次のとおりです。マクロ呼び出しは一連の文字で始まる必要があります。
に一致する マクロ start シーケンス 現在のモードで指定されているとおりに、すぐに続きます
マクロの名前で指定します。マクロ名は有効でなければなりません。 識別子 -- すなわち、一連の文字、
数字、またはアンダースコア (「_」)。 マクロ名の後には 短い マクロ end
シーケンス マクロに引数がない場合、またはマクロによって開始される一連の引数によって
引数 start シーケンス。 さまざまな引数は、 引数
セパレーター、マクロは次で終わります。 長い マクロ end シーケンス.

すべての場合において、現在のコンテキストのパラメータ -- すなわち、に渡される引数
評価中の本体 -- を使用して参照できます。 引数 参照 シーケンス
その後に 1 ~ 9 の数字が続きます。または、マクロ パラメータに名前を付けることもできます (「
下に)。 さらに、GPP 構文とその内容の間の干渉を避けるため、
入力ファイル、 文字 供給される。 引用符文字を使用すると、
マクロ呼び出し、コメント、文字列をプレーン テキスト以外のものとして解釈すること。 引用
文字は後続の文字を「保護」し、評価中に常に削除されます。
XNUMX つの連続した引用符は単一引用符として評価されます。

最後に、適切な引数の区切りを容易にするために、特定の文字を「積み重ね」ることができます。
マクロ引数内に出現する場合、引数の区切り文字またはマクロ終了シーケンスが
引数本体のバランスが取れていない場合、解析されません。 これにより、マクロ呼び出しをネストできるようになります
引用符を使用せずに。 不適切なバランスの引数が必要な場合は、文字を引用符で囲みます
バランスをとるために、いくつかの積み重ねられた文字の前に追加する必要があります。

上で説明したマクロ構築シーケンスは、メタマクロとマクロでは異なる場合があります。
ユーザー マクロ: これは、たとえば cpp モードの場合に当てはまります。 メタマクロは次のことができるので注意してください。
引数は XNUMX つまでしかありません。XNUMX 番目の引数の区切り規則は若干異なります。
よりずさんで、引用符で囲まれていない引数区切り文字シーケンスが の XNUMX 番目の引数で許可されます。
メタマクロ。

標準動作モードのいずれかが選択されていない限り、上記の構文シーケンスは次のようになります。
コマンドラインで、meta- に対してそれぞれ -M および -U オプションを使用して指定します。
マクロとユーザー マクロ、または入力ファイル内で #モード メタ#モード user メタ
マクロ呼び出し。 どちらの場合も、モードの説明はユーザー用の XNUMX つのパラメータで構成されます。
マクロ仕様、つまりマクロ開始シーケンス、短いマクロ終了シーケンス、
引数開始シーケンス、引数セパレータ、長いマクロ終了シーケンス、文字列
スタックする文字のリスト、スタックを解除する文字のリスト文字列、引数
参照シーケンス、そして最後に引用文字です。 以下で説明するように、これらのシーケンスは
C 文字列の構文を使用して指定する必要があります。 英数字以外の文字で始める必要があります
文字、および最初の XNUMX つの文字列では特別な一致シーケンスを使用できます (「
下に)。 引用符文字に対応する引数が空の文字列の場合、
引数の機能は無効になっています。 メタマクロ仕様の場合は XNUMX つしかありません
パラメータは、引数の参照シーケンスと引用符文字が共有されるため、
ユーザーマクロ構文。

コメント/文字列の構造は次のとおりです。コメント/文字列は、次のシーケンスで始まる必要があります。
指定された文字に一致する文字 コメント/文字列 start シーケンス、常に最初で終了します
の発生 コメント/文字列 end シーケンス、奇数の数字が前にない限り、
の発生 文字列引用符 文字 (そのような文字が指定されている場合)。 で
場合によっては、コメント/文字列を指定して、内部でのマクロ評価を有効にすることができます。
コメント/文字列; この場合、引用符文字がマクロに定義されていれば、次のようにすることができます。
コメント/文字列が終了しないようにするためにも使用されますが、マクロとは異なります。
引用符文字は常に出力から削除されますが、文字列引用符文字は常に出力から削除されます。
出力。 また、特定の状況下では、コメント/文字列の仕様が次のように指定される可能性があることにも注意してください。
無効この場合、コメント/文字列の開始シーケンスは単純に無視されます。 最後に、それは
を指定することが可能です string 警告 文字 コメント/文字列内にその存在が存在する
GPP が警告を出力します (これは、cpp で終了していない文字列を見つけるのに役立ちます)
モード)。 入力ファイルには、終了していないコメント/文字列を含めることはできないことに注意してください。

コメント/文字列仕様は、次のコマンドを使用して入力ファイル内から宣言できます。 #モード
コメント メタマクロ呼び出し (または同等の #モード string)、この場合、C の数は
コメント/文字列を説明する引数として指定する文字列は、次の範囲のどこにでも指定できます。
XNUMX と XNUMX: 最初の XNUMX つの引数 (必須) は開始シーケンスと終了シーケンスです。
シーケンスに加えて、特別な一致シーケンスを利用することもできます (以下を参照)。 そうではないかもしれない
英数字で始めてください。 XNUMX 番目の引数の最初の文字 (存在する場合)
XNUMX つは文字列引用符として使用されます (無効にするには空の文字列を使用します)。
機能)、XNUMX 番目の引数の最初の文字 (存在する場合) が使用されます。
文字列警告文字として。 コマンドラインから仕様を指定することもできます。
この場合、+c オプションを使用する場合は XNUMX つの引数が必要で、+s オプションを使用する場合は XNUMX つの引数が必要です。
オプションを選択します。

コメント/文字列の動作は、XNUMX 文字の修飾文字列によって指定されます。
オプションの引数として +c/+s コマンドライン オプションまたは
#モード コメント/#モード string メタマクロ。 修飾文字列が指定されていない場合、デフォルトの
値はコメントの場合は「ccc」、文字列の場合は「sss」です。 最初の文字は、
メタマクロ呼び出し内の動作 (これらは内部にあるため、ユーザーマクロ定義を含む)
a #定義する メタマクロ呼び出し)、XNUMX 番目の文字はユーザー内部の動作に対応します。
マクロパラメータ。XNUMX 番目の文字はマクロの外部の動作に対応します。
電話。 これらの各文字は次の値を取ることができます。

i コメント/文字列の指定を無効にします。

c コメント (評価も出力もされません)。

s 文字列 (文字列とその区切り文字シーケンスはそのまま出力されます)。

q 引用符で囲まれた文字列 (文字列は区切り文字シーケンスなしでそのまま出力されます)。

C 評価されたコメント (マクロは評価されますが、出力は破棄されます)。

S 評価された文字列 (マクロが評価され、区切り文字が出力されます)。

Q 評価された引用符付き文字列 (マクロは評価され、区切り文字は出力されません)。

重要な注意事項: コメント/文字列開始シーケンスが別の内部に出現した場合
コメント/文字列は、マクロ評価が有効になっている場合でも常に無視されます。 言い換えると、
コメント/文字列はネストできません。 特に、「Q」修飾子は便利な方法です。
すべてのコメントと文字列の仕様を一時的に無効にするための構文を定義します。

構文仕様文字列は、C 文字列であるかどうかに関係なく、常に C 文字列として提供する必要があります。
への引数として与えられる #モード メタマクロ呼び出しまたは Unix シェルのコマンドラインで。 もし
コマンドライン引数は、標準の Unix シェルとは別の方法で指定されます。
シェルの動作をエミュレートする必要がある -- すなわち、周囲の "" 引用符はすべて削除する必要があります。
「\\」の出現は単一のバックスラッシュで置き換える必要があり、同様に「\"」も次のように置き換える必要があります。
「\n」のようなシーケンスは GPP によって認識されるため、そのままにしておく必要があります。

文字セットの特定のサブセットに一致する特別なシーケンスを使用できます。 彼らは
形式 `\x'、 どこ x の一つであります:

b XNUMX つ以上のスペースまたはタブ文字の任意のシーケンスに一致します (「\b」は
` ')。

w XNUMX 個以上のスペースまたはタブ文字の任意のシーケンスに一致します。

B XNUMX つ以上のスペース、タブ、または改行文字の任意のシーケンスと一致します。

W XNUMX 個以上のスペース、タブ、または改行文字の任意のシーケンスと一致します。

a アルファベット文字 (「a」から「z」および「A」から「Z」)。

A 英字、スペース、タブ、改行。

# 数字 (「0」から「9」)。

i 識別子文字。 一致した文字のセットは、
#モード 文字セット id 指示。 デフォルト設定は英数字と一致します。
アンダースコア (「a」から「z」、「A」から「Z」、「0」から「9」、および「_」)。

t タブ文字。

n 改行文字。

o 演算子文字。 一致した文字のセットは、
#モード 文字セット op 指示。 デフォルト設定は、次のすべての文字に一致します。
「+-*/\^<>=`~:.?@#&!%|」。ただし、プロローグ モードでは `!'、`%'、および `|' が使用されます。 ではありません
一致した。

O 演算子文字または括弧文字。 追加の一致セット
`\o' と比較した文字は、 #モード 文字セット パー
指示。 デフォルト設定では、「()[]{}」内の文字が括弧として表示されます。

さらに、「\w」と「\W」を除くこれらの一致するサブセットはすべて、
「!」 -- すなわち、「\!」と書くことでx`\ の代わりに 'x'.

の重要な特徴に注目してください。 start シーケンス: a の最初の文字のとき
マクロまたはコメント/文字列の開始シーケンスは ' '、または上記の特殊なシーケンスのいずれかです。
シーケンス自体の一部とはみなされませんが、代わりにコンテキスト チェックとして使用されます。
たとえば、「\n」で始まる開始シーケンスは行の先頭でのみ一致しますが、
一致する改行文字はシーケンスの一部とみなされません。 同じくスタート
「 」で始まるシーケンスは、空白が存在する場合にのみ一致しますが、一致するものは
空白は開始シーケンスの一部とみなされないため、
出力。 コンテキスト チェックがファイルの先頭 (より一般的には、
評価される任意の本文の一致)、結果は改行文字との一致と同じです
(これにより、cpp-mode ファイルがメタマクロ呼び出しで開始できるようになります)。

バージョン 2.1 では、XNUMX つの特別な構文ルールが追加されました。 まず、引数の参照 (#n)いいえ
マクロの呼び出しと定義の外にある場合は評価が長くなります。 しかし、彼らは、
への呼び出し内に (引用符で保護されていない限り) 表示することはできなくなりました。
定義されたユーザーマクロ。 現在の動作 (下位互換性) は、サイレントに削除することです。
その場合は入力から。

次に、終了シーケンス (マクロまたはコメントのいずれか) が単一の改行で構成されている場合
文字、および区切りルールが最終的なコンテキストでの評価につながるかどうか
改行文字が存在しない場合、GPP は欠落している改行を生成する代わりに黙って無視します。
エラー。 主な結果は、メタマクロ呼び出しを簡単な方法でネストできるようになったということです。
標準、cpp、および Prolog モードで。

評価 RULES


入力は順番に読み取られ、現在のモードのルールに従って解釈されます。 全て
入力テキストは、最初に、指定されたコメント/文字列の開始シーケンスと照合されます。
現在のモード (「i」修飾子で無効になっているモードを除く)。
評価されたは、その修飾子がマクロ評価を有効にするコメント/文字列の内容です。
最後に定義されたコメント/文字列仕様が最初にチェックされます。 重要
注: マクロの名前とその引数の間にコメントを含めることはできません (そうすることで
未定義の動作が発生します)。

コメント/文字列ではないものはすべて、メタマクロ呼び出しの可能性と照合されます。
それも失敗した場合は、ユーザー マクロの呼び出しが行われる可能性があります。 残りのテキストはすべて処理されます
関連する引数テキストによる引数参照シーケンスの置換 (そうでない場合は空)
評価される本文はユーザー マクロの定義です) と引用符の削除
キャラクターがあれば。

メタマクロ引数は評価の前にメタマクロに渡されることに注意してください。
(ただし、メタ マクロがそれらを評価することを選択する場合もあります。以下のメタ マクロの説明を参照してください)。
の場合 #モード メタマクロ、GPP は一時的にコメント/文字列仕様を追加します
C 文字列 (「...」) の認識を有効にし、文字列内での評価を防止するため、
C の文字列引数に含まれる文字の干渉 #モード
現在の構文は懸念されるべきです。

一方、ユーザー マクロの引数は体系的に評価され、
コンテキストパラメータとしてマクロ定義本体に渡され、それによって評価されます。
環境。 唯一の例外は、マクロ定義が空の場合です。その場合、
引数は評価されません。 GPP は一時的に次のモードに戻ることに注意してください。
マクロは評価するために定義されているため、マクロを変更しても完全に安全です。
マクロが定義されてから呼び出されるまでの動作モード。
逆に、ユーザー マクロが現在のモードではなく現在のモードで動作したい場合は、
定義するために使用されました。で始まる必要があります #モード リストア を呼び出して終了します #モード
保存 コール。

ユーザー マクロは名前付き引数を使用して定義できます (「 #定義する 以下説明)。 その中で
この場合、マクロ定義が評価されるときに、名前付きパラメータごとに
作成される一時的な仮想ユーザー マクロ定義。 このようなマクロはのみ呼び出すことができます
引数なしで、対応する引数のテキストを返すだけです。

マクロはマクロが呼び出されたときではなく、呼び出されたときに評価されることに注意してください。
定義されている場合、再帰マクロを呼び出そうとすると、次の場合を除いて未定義の動作が発生します。
マクロが使用する非常に特殊なケース #undef 有限回ループした後に自分自身を消去する
反復。

最後に、定義に何も関与しないユーザー マクロの場合、特殊なケースが発生します。
引数 (名前付き引数も引数参照シーケンスもなし) は、
短いユーザー マクロ終了シーケンスが空のモード (マシン情報の記入> という構文でなければなりません。例えば、、cpp または TeX モード)。 その中で
であると想定される場合 alias マクロ: その引数は現在のメソッドで最初に評価されます。
通常どおりモードですが、パラメータとしてマクロ定義に渡されるのではなく(
それらは破棄されます) それらは実際にはマクロ定義に追加されます。
マクロが定義されたモードの構文規則とその結果のテキストを使用します。
再度評価されます。 したがって、マクロ エイリアスの場合、次のことに注意することが重要です。
引数は実際には XNUMX つの異なるモードで XNUMX 回評価されます。

メタマクロ


これらのマクロは常に事前定義されています。 実際の呼び出しシーケンスは現在の状況によって異なります。
モード; ここでは cpp のような表記法を使用します。

#定義する x y
これはユーザーマクロを定義します x as y. y 任意の有効な GPP 入力を指定できます。
例は他のマクロを参照してください。 x 識別子である必要があります (すなわち、一連の
名前付き引数が指定されていない限り、英数字と「_」)。 もし x is
すでに定義されている場合は、以前の定義が上書きされます。 XNUMX 番目の引数がない場合は、
与えられた、 x 何も出力しないマクロとして定義されます。 どちらでもない x また y  
評価される。 マクロ定義は、マクロ定義が呼び出されたときのみ評価され、マクロ定義は実行されたときでは評価されません。
宣言された。

マクロ定義で引数に名前を付けることもできます。その場合、
引数 x 引数がすべて識別子であるユーザー マクロ呼び出しである必要があります。 これら
識別子は、マクロ定義内のユーザー マクロとして使用できるようになります。 これら
仮想マクロは引数なしで呼び出し、対応するマクロを評価する必要があります。
マクロパラメータ。

#deveval x y
これは次と同様に機能します。 #定義する、しかし、XNUMX番目の引数 y 評価されます
すぐに。 ユーザーマクロ定義も毎回評価されるため、
と呼ばれる、これはマクロを意味します y 受ける 2 連続した評価。 の
の有用性 #deveval それは何かを評価する唯一の方法であるため、重要です
メタの引数の評価を強制するために必要になる場合があります。
通常は評価を実行しないマクロ。 しかし、すべての議論以来
定義時に評価される参照は、本体の引数として理解されます。
マクロ自体の引数としてではなく、マクロが定義されているもの、
通常、すぐに評価されないようにするために引用符を使用する必要があります。
引数の参照。

#undef x
これにより、ユーザー マクロの既存の定義が削除されます。 x.

#ifdef x
これにより、条件付きブロックが始まります。 以下のすべては、次の場合にのみ評価されます。
識別子 x が定義され、次のいずれかが定義されるまで、 #その他 または #endif という声明に達しました。
ただし、コメントされたテキストは引き続き徹底的にスキャンされるため、その構文は
有効である必要があります。 特に、 #その他 or #endif ステートメント
条件付きブロックの終了は、ユーザーマクロ展開の結果としてのみ表示されます。
明示的に入力ではありません。

#ifndef x
これにより、条件付きブロックが始まります。 以下のすべては、次の場合にのみ評価されます。
識別子 x 定義されてない。

#ifeq x y
これにより、条件付きブロックが始まります。 以下のすべては、次の場合にのみ評価されます。
の評価結果 xy 文字列としては同一です。 どれでも
先頭または末尾の空白は比較の際に無視されます。 cppモードでは注意してください
引用符で囲まれていない空白文字は、最初の引数の終わりとして理解されます。
したがって注意が必要です。

#ifneq x y
これにより、条件付きブロックが始まります。 以下のすべては、次の場合にのみ評価されます。
の評価結果 xy は同一ではありません(先頭の または
末尾の空白)。

#その他 これにより、現在の条件付きブロックの論理値が切り替わります。 以下は
前の入力がコメントアウトされている場合にのみ評価されます。

#endif これにより、によって開始された条件付きブロックが終了します。 #もし... メタマクロ。

#include file
これにより、GPP は指定されたファイルを開いてその内容を評価し、
現在の出力の結果のテキスト。 定義済みのユーザー マクロはすべて引き続き使用できます
インクルードされたファイル内に定義されており、相互にインクルードされたファイル内で定義されているすべてのマクロが
以下のすべてで利用可能になります。 インクルード ファイルは最初に検索されます。
現在のディレクトリ、見つからない場合は指定されたディレクトリのいずれか
を通じて、タンピングされたコーヒーベッドの上から均一にフィルターバスケットの内の粉に浸透していきます。 -I コマンドライン オプション (または / usr / include ディレクトリが指定されていない場合)。
互換性上の理由から、ファイル名を前後に置くことができることに注意してください。
「」または<>。

さまざまなディレクトリでインクルード ファイルが検索される順序は次のとおりです。
の影響を受ける -ノストディンク, -ノキュリンク-カーディリンクラスト コマンドラインオプション。

ファイルをインクルードすると、GPP は現在の動作モードのコピーを直ちに保存します。
モード スタックに追加し、含まれているモジュールの最後に動作モードを復元します。
ファイル。 インクルードされたファイルは、 #モード リストア
で終わるコール #モード プッシュ 電話。 さらに、 -m コマンドライン
オプションが指定されている場合、GPP は自動的に cpp 互換モードに切り替わります。
名前が「.c」または「.h」で終わるファイルを含める場合。

#exec command
これにより、GPP は指定されたコマンド ラインを実行し、その標準をインクルードします。
現在の出力に出力されます。 セキュリティ上の理由から、このメタマクロは
以下の場合を除き、無効になります -x コマンドラインフラグが指定されました。 使用する場合 #exec ではありません
許可されている場合は、警告メッセージが出力され、出力は空白のままになります。 注意してください。
指定されたコマンドラインは実行前に評価されるため、
コマンドラインのマクロ。 ただし、コマンドの出力はそのまま含まれます。
そして評価されない。 出力を評価する必要がある場合は、次を使用する必要があります。 #deveval
(上記を参照) 二重評価が発生します。

#eval
この #eval メタマクロが評価を試みます まずマクロを展開します(通常の
GPP 評価)、その後算術評価および/またはワイルドカードを実行することによって
マッチング。 算術式の構文と演算子の優先順位は次のとおりです。
C と同じ。 欠落している演算子は、<<、>>、?:、および代入のみです。
演算子。

POSIX スタイルのワイルドカード マッチング (「グロビング」) は POSIX でのみ使用できます
実装されており、=~ 演算子を使用して呼び出すことができます。 簡単に言うと、「?」 マッチ
任意の XNUMX 文字、「*」は任意の文字列 (空の文字列を含む) に一致し、
'[...]' は、括弧で囲まれた文字のいずれかと一致します。 '[...]' クラスは
括弧内の最初の文字が「!」の場合は補完されます。 の文字
「[...]」クラスは、「-」文字を使用して範囲として指定することもできます。 マシン情報の記入> という構文でなければなりません。例えば、,
「[FN]」は「[FGHIJKLMN]」と同等です。

結果に数値を割り当てることができない場合、返されるテキストは単に次のとおりです。
算術評価を行わないマクロ展開の結果。 唯一の
このルールの例外は、比較演算子 ==、!=、<、>、<=、および >= です。
どちらかの辺が数値として評価されない場合、文字列比較が実行されます。
代わりに (末尾と先頭のスペースは無視されます)。 さらに、 長さ(...)
算術演算子は、評価された引数の文字数を返します。

算術式の内部では、 定義済み(...) 特別なユーザーマクロもあります
available: 引数を 1 つだけ取りますが、引数は評価されません。引数が引数に該当する場合は XNUMX を返します。
ユーザーマクロの名前、それ以外の場合は 0。

#もし
このメタマクロは、以下と同じ方法で算術/グロビング評価器を呼び出します。
#eval そして、評価結果を文字列「0」と比較して、評価を開始します。
条件付きブロック。 特に、次の論理値に注意してください。 常に真実です
数値として評価できない場合。

#エリフ
このメタマクロは、ネストを避けるために使用できます。 #もし 条件。 #もし ... #エリフ ...
#endif に相当します #もし ... #その他 #もし ... #endif #endif.

#モード キーワード ...
このメタ マクロは GPP の動作モードを制御します。 のリストについては以下を参照してください #モード
コマンド。

#ライン このメタ マクロは、現在の入力ファイルの行番号として評価されます。

#ファイル このメタ マクロは、表示されている現在の入力ファイルのファイル名として評価されます。
コマンドラインまたは引数で #include。 GPP が入力を読み取っている場合
標準入力から、その後 #ファイル `stdin' として評価されます。

#日付 FMT
このメタ マクロは、次の形式でフォーマットされた現在の日付と時刻を評価します。
指定されたフォーマット文字列 FMT。 セクションを参照してください DATE そして タイム 変換 指定子
を参照してください。

#エラー MSG
このメタ マクロにより、現在のファイル名と行番号を示すエラー メッセージが表示されます。
そしてテキストと一緒に MSG、標準エラーデバイスに出力されます。 その後
その後、処理は中止されます。

#警告 MSG
このメタマクロにより、現在のファイル名と行番号を含む警告メッセージが表示されます。
そしてテキストと一緒に MSG、標準エラーデバイスに出力されます。 その後
その後、処理が再開されます。

GPP の柔軟性の鍵となるのは、 #モード メタマクロ。 最初の引数は常に次のいずれかです。
使用可能なキーワードのリスト (以下を参照)。 XNUMX 番目の引数は常に次のシーケンスです。
空白で区切られた単語。 おそらく最初の単語を除いて、これらの単語のそれぞれは
は常に区切り文字または構文指定子であり、区切り文字で区切られた C 文字列として指定する必要があります。
二重引用符 (" ") で囲みます。 のセクションにリストされているさまざまな特殊な一致シーケンス
構文仕様が利用可能です。 どれでも #モード コマンドは、「...」が存在するモードで解析されます。
C スタイルの文字列として理解されるため、これらの中に任意の文字を入れても安全です
文字列。 また、次の最初の引数にも注意してください。 #モード (キーワード) は決して評価されません。
XNUMX 番目の引数が評価される間 (もちろん C 文字列の内容は除きます)、
マクロ評価の結果として構文仕様を取得できるようにします。

利用可能な #モード コマンドは次のとおりです。

#モード 保存 / #モード プッシュ
現在のモード仕様をモード スタックにプッシュします。

#モード リストア / #モード ポップ
モードスタックからモード指定をポップします。

#モード 標準
標準モードのいずれかを選択します。 唯一の引数は次のいずれかである必要があります。
(デフォルトモード); cpp、C (cpp モード); テックス、TeX (テックスモード); html、HTML (html モード);
xhtml、XHTML (xhtml モード); プロローグ、プロローグ (プロローグ モード)。 モード名は次のようにする必要があります
C 文字列としてではなく、直接与えられます。

#モード user "s1" ... "s9"
ユーザーマクロ構文を指定します。 9 つの引数はすべて C 文字列であり、モードです。
ユーザー マクロの仕様 (-U コマンドライン オプションと「」のセクションを参照)
構文仕様)。 メタマクロの仕様には影響しません。

#モード メタ {ユーザー | "s1" ... "s7"}
メタマクロ構文を指定します。 唯一の引数は次のいずれかです user (文字列としてではなく)、そして
ユーザーマクロモードの仕様はメタマクロモードにコピーされます。
そうでない場合は XNUMX つの文字列引数が必要です。その重要性は
-M コマンドライン オプションと同じです (構文仕様のセクションを参照)。

#モード ["c"]
引数なし、または引数として "" を指定すると、引用符文字の指定が削除され、
引用機能を無効にします。 文字列引数が XNUMX つある場合、最初の文字は
文字列の は新しい引用符文字とみなされます。 引用文字は次のとおりです
英数字でも「_」でも、特殊な一致シーケンスの XNUMX つでもありません。

#モード コメント [xxx] "始める" "終わり" [「c」 ["c"]]
コメント仕様を追加します。 オプションで XNUMX つの値からなる最初の引数
「」で囲まれていない文字をコメント/文字列修飾子の指定に使用できます
(構文仕様に関するセクションを参照してください)。 デフォルトの修飾子は次のとおりです CCC。 最初
XNUMX つの文字列引数は、それぞれコメントの開始シーケンスと終了シーケンスとして使用されます。 の
XNUMX 番目の文字列引数はオプションであり、文字列引用符の指定に使用できます。
キャラクター。 (""の場合は機能が無効になります。) XNUMX番目の文字列
引数はオプションであり、文字列区切り警告を指定するために使用できます。
キャラクター。 (「」の場合は機能が無効になります。)

#モード string [xxx] "始める" "終わり" [「c」 ["c"]]
文字列指定を追加します。 と同じ #モード コメント デフォルトを除いて
修飾子は SSS.

#モード コメント無し / #モード ひもがない ["始める"]
引数を指定しないと、すべてのコメント/文字列の指定が削除されます。 弦XNUMX本で
引数の場合、開始シーケンスが
引数。

#モード 保存 { on | OFF | 1 | 0 }
に相当 -n コマンドラインスイッチ。 引数が次の場合 on or 1、任意の改行
マクロ呼び出しを終了する空白文字、またはコメント/文字列が
さらに処理するための入力ストリーム。 引数が次の場合 OFF or 0 この機能は
無効にする。

#モード 文字セット { id | op | パー } "ストリング"
\o、\O、および \i 特殊文字の一致に使用する文字セットを指定します。
シーケンス。 最初の引数は次のいずれかでなければなりません id (\i で一致するセット)、 op
\o で一致するセット) または パー (\O で一致したセットに加えて、\O で一致したセット
\o)。 "ストリング" は、セットに含めるすべての文字をリストする C 文字列です。 かもしれない
特殊な一致シーケンス \a、\A、\b、\B、および \# のみが含まれます (他のものは
シーケンスと否定されたシーケンスは許可されません)。 「-」が見つかった場合
XNUMX つの非特殊文字の間にある場合、その間にあるすべての文字が追加されます (例: "AZ")
すべての大文字に対応します)。 一致するセットに「-」を含めるには、次のいずれかを行います。
最初または最後の位置に置くか、\x シーケンスの隣に置きます。

DATE そして タイム 変換 指定子


フォーマット文字列内の通常の文字は、変換されずにコピーされます。
変換指定子は「%」文字で導入され、次のように置き換えられます。

%a 現在のロケールに応じた短縮された曜日名。

%A 現在のロケールに従った完全な曜日名。

%b 現在のロケールに応じた短縮された月の名前。

%B 現在のロケールに従った完全な月の名前。

%c 現在のロケールで優先される日付と時刻の表現。

%d 01 進数で表した日付 (31 ~ XNUMX の範囲)。

%F %Y-%m-%d (ISO 8601 日付形式) と同等です。

%H 24 時間制を使用した 00 進数での時間 (範囲は 23 ~ XNUMX)。

%I 12 時間制を使用した 01 進数での時間 (範囲は 12 ~ XNUMX)。

%j 001 進数で表した通算日 (366 ~ XNUMX の範囲)。

%m 01 進数で表した月 (12 ~ XNUMX の範囲)。

%M 00 進数で表した分 (59 ~ XNUMX の範囲)。

%p 指定された時刻値に応じた「AM」または「PM」、または対応する
現在のロケールの文字列。 正午は「午後」として扱われ、午前零時は「午前」として扱われます。

%R 24 時間表記の時刻 (%H:%M)。

%S 00 番目は 61 進数 (XNUMX ~ XNUMX の範囲) で表されます。

%U 今年の週番号を 00 から 53 の範囲の XNUMX 進数で表します。
最初の日曜日を週 01 の最初の日として開始します。

%w 0 進数で表した曜日。範囲は 6 ~ 0、日曜日は XNUMX です。

%W 今年の週番号を 00 から 53 の範囲の XNUMX 進数で表します。
最初の月曜日を週 01 の最初の日として開始します。

%x 現在のロケールの時刻を含まない優先日付表現。

%X 現在のロケールの日付を含まない優先時刻表現。

%y 世紀を含まない 00 進数で表された年 (99 ~ XNUMX の範囲)。

%Y 世紀を含む XNUMX 進数で表した年。

%Z タイムゾーン、名前、または略語。

%% リテラルの「%」文字。

GPP のコンパイルに使用される C コンパイラとライブラリによっては、さらに多くの変換が必要になる場合があります。
指定子が利用可能です。 詳細については、コンパイラのドキュメントを参照してください。 strftime() 機能。
ただし、上記にリストされていない変換指定子は、複数の言語間で移植できない可能性があることに注意してください。
GPP のインストール。


標準モードまたは cpp モードでの基本的な例は次のとおりです。

#define FOO これは
#BAR メッセージを定義します。
#連結を定義します #1 #2
concat(FOO,BAR)
#ifeq (concat(foo,bar)) (foo バー)
これが出力です。
#その他
これは出力されません。
#endif

引数の命名を使用すると、 連結 マクロは次のように定義することもできます

#define concat(x,y) xy

TeX モードで引数の命名を使用すると、同じ例は次のようになります。

\define{FOO}{こ​​れは}
\define{BAR}{メッセージ。}
\define{\concat{x}{y}}{\x \y}
\concat{\FOO}{\BAR}
\ifeq{\concat{foo}{bar}}{foo bar}
これが出力です。
\それ以外
これは出力されません。
\endif

HTML モードで引数に名前を付けない場合は、同様の結果が得られます。

<#define FOO|これは>
<#define BAR|メッセージ。>
<#define concat|#1 #2>
<#concat <#FOO>|<#BAR>>
<#ifeq <#concat foo|bar>|foo bar>
これが出力です。
<#else>
これは出力されません。
<#endif>

次の例 (標準モード) は、引用符文字の使用を示しています。

#define FOO これは \
複数行の定義。
#define BLAH(x) 私の引数は x です
BLAH(ウルフ)
\BLAH(ウルフ)

複数行定義は、cpp および Prolog モードでも有効であることに注意してください。
引用符がない場合、「\」の後に改行が続くと解釈されるためです。
コメントして破棄しました。

cpp モードでは、C の文字列とコメントは、次のように理解されます。
次の例:

#BLAH foo を定義
何とか何とか何とか */
「それは /*string*/ です !」

Prolog モードと cpp モードの主な違いは、文字列と
コメント: プロローグでは、「...」文字列は数字の直後に始まらない可能性があり、/*...*/
コメントは演算子文字の直後に開始することはできません。 なお、コメントは、
#command で発生しない限り、出力から削除されません。

cpp モードとデフォルト モードの違いはさらに深いです: デフォルト モードでは #commands
どこからでも始められますが、cpp モードでは行の先頭になければなりません。 デフォルト
mode はコメントや文字列を認識しませんが、引用符 ('\') を持ちます。一方、cpp はコメントと文字列を認識しません。
このモードには広範なコメント/文字列仕様がありますが、引用符はありません。 さらに、
デフォルトモードではメタマクロの引数を正しく括弧で囲む必要がありますが、そのようなことはありません
チェックは cpp モードで実行されます。

これにより、cpp モードよりもデフォルト モードでメタマクロ呼び出しをネストすることが簡単になります。 のために
たとえば、次の HTML モード入力を考えてみましょう。これは、
#exec コマンド:

<#ifeq <#exec echo 何とか>|何とか
> #exec は許可されます <#else> #exec は許可されません <#endif>

cpp モードに相当するものはありませんが、デフォルト モードでは次のように簡単に変換できます。

#ifeq (#exec エコーなんとか
) (まあ
)
\#実行は許可されています
#その他
\#exec は許可されていません
#endif

cpp モードでメタマクロ呼び出しをネストするには、モードを変更する必要があります。
メタマクロ呼び出し構文を変更するか、よりエレガントに定義することによって説明を作成します。
サイレント文字列であり、評価された文字列の先頭のコンテキストが
string は改行文字です。

#mode string QQQ "$" "$"
#ifeq $#exec エコーなんとか
$ $まあ
$
\#実行は許可されています
#その他
\#exec は許可されていません
#endif

ただし、コメント/文字列はネストできないことに注意してください ($...$ 内の "..." は入れ子になります)
検出されない)ので、そのようなサイレントの中に何を含めるかについて注意する必要があります
評価された文字列。 この例では、バージョン 2.1 で導入された緩やかなメタマクロのネストが使用されています。
これにより、次のより単純なバージョンを使用できるようになります。

#ifeq 何とか #exec echo -n 何とか
\#実行は許可されています
#その他
\#exec は許可されていません
#endif

引数のないマクロは、実際にはエイリアスであると理解されることに注意してください。
次の例に示すように、引数を指定して呼び出されます (デフォルトまたは cpp モード)。

#define DUP(x) xx
#define FOO と私は言いました: DUP
ふー(まあ)

の有用性 #deveval メタマクロは、HTML モードでの次の例に示されています。

<#define APPLY|<#defefval TEMP|<\##1 \#1>><#TEMP #2>>
<#define <#foo x>|<#x> および <#x>>
<#APPLY foo|BLAH>

その理由 #deveval 必要なのは、すべてが単一パスで評価されるため、
目的のマクロ呼び出しとなる入力は、最初のマクロ呼び出しによって生成される必要があります。
APPLY に渡された引数を XNUMX 回目に評価される前に評価します。

この例をデフォルト モードで翻訳するには、次の順序で括弧で囲む必要があります。
APPLY の定義内で #defeval 呼び出しをネストしますが、ネストする必要はありません。
括弧を出力します。 最も簡単な解決策は、

#define BALANCE(x) x
#define APPLY(f,v) BALANCE(#defeval TEMP f
温度(v))
#define foo(x) x と x
適用(\foo,BLAH)

上で説明したように、cpp モードの最も単純なバージョンはサイレント評価の定義に依存しています。
BALANCE マクロの役割を果たす文字列。

次の例 (デフォルトまたは cpp モード) は、算術評価を示しています。

#定義×4
答えは:
#eval x*x + 2*(16-x) + 1998%x

#定義されている場合(x)&&!(3*x+5>17)
これが出力されるはずです。
#endif

最後に、モード切り替えに関する例をいくつか示します。 次の例は
一目瞭然 (デフォルト モードで開始):

#モードプッシュ
#f(x) xx を定義します
#mode標準テックス
\f{まあ}
\モード{文字列}{"$" "$"}
\mode{コメント}{"/*" "*/"}
$\f{urf}$ /* ああ */
\define{FOO}{bar/* など */}
\モード{ポップ}
f($FOO$)

ユーザー定義モードが役立つ良い例は、このドキュメントの GPP ソースです。
(GPP のソース コード配布で入手可能)。

もう XNUMX つの興味深いアプリケーションは、C 文字列内のマクロの評価を選択的に強制することです。
cppモード時。 たとえば、次の入力について考えてみましょう。

#define blah(x) "そして彼は言いました: x"
ああ(ふー)

明らかにパラメータが必要です x 文字列内で展開されます。 がある
この問題を回避するにはいくつかの方法があります。

#モードプッシュ
#mode nostring "\""
#define blah(x) "そして彼は言いました: x"
#モードポップ

#モード引用符「`」
#define blah(x) `"そして彼はこう言いました: x`"

#mode string QQQ "$$" "$$"
#define blah(x) $$"そして彼は言いました: x"$$

最初の方法は非常に自然ですが、時間がかかり、時間がかかるという不便な点があります。
文字列のセマンティクスを中和することで、「x」の未評価のインスタンスが
文字列、または '/*' の出現は、さらなる手段に頼らなければ不可能です。
ゆがみ。

XNUMX 番目の方法は、ローカルに引用符が存在するため、若干効率的です。
文字を使用すると、何が評価され、何が評価されないかを制御しやすくなりますが、
欠点は、適切な引用文字を見つけることができない場合があることです。
ソースファイルを大幅に変更するか、ソースファイルを #モード プッシュ/ポップ
構築する。 たとえば、文字列内に「/*」が出現する場合は引用符で囲む必要があります。

最後の方法は、次のコンテキストで評価された文字列の効率を示します。
選択的評価: コメント/文字列はネストできないため、「"」または
「$$」内の「/*」は、文字列内で予期されるとおり、プレーンテキストとして出力されます。
マクロ評価が有効になっています。 また、選択の自由度がはるかに高いことにも注意してください。
引用符文字の選択よりも文字列区切り文字が異なります。

バージョン 2.1 以降、メタマクロ呼び出しはデフォルトの cpp でより効率的にネストできるようになりました。
プロローグモード。 これにより、メタ マクロのユーザー バージョンを簡単に作成したり、
カウンタをインクリメントします。

#define myeval #eval #1

#定義×1
#defeval x #eval x+1

高度な


GPPを活用した先進的な施工例をいくつかご紹介します。 彼らはかなり厄介な傾向があります
これは GPP の限界の証拠として考慮されるべきです。

最初の例は再帰マクロです。 主な問題は (GPP が評価するため)
すべて) 再帰マクロは、再帰がどのように行われるかについて細心の注意を払う必要があります。
未定義の動作を避けるために終了されます (ほとんどの場合、GPP は単純にクラッシュします)。
特に、 #if/#else/#endif 再帰を終了するための構築は不可能です
GPP はユーザー マクロ呼び出しをスキャンするため、無限ループが発生します。
条件付きブロックの未評価分岐。 安全に続行する方法は、たとえば次のとおりです
以下に示します (例は TeX モードで示します)。

\define{カウントダウン}{
\if{#1}
#1...
\define{ループ}{\カウントダウン}
\それ以外
完了しました。
\define{ループ}{}
\endif
\loop{\eval{#1-1}}
}
\カウントダウン{10}

cpp モードの別の例:

#mode string QQQ "$" "$"
#define 三角形(x,y) y \
$#if 長さ(y)
$#define iter$ $#endif
$ iter(x,*y)
三角形(20)

以下は、関数を実装するための (残念ながら非常に弱い) 試みです。
GPP での抽象化 (標準モード)。 この例とそれが作成できない理由を理解する
もっと簡単なのは、好奇心旺盛な読者に任せる演習です。

#モード文字列 "`" "`" "\\"
#define ASIS(x) x
#define SILENT(x) ASIS()
#define EVAL(x,f,v) SILENT(
#mode string QQQ "`" "`" "\\"
#defefval TEMP0 x
#defefval TEMP1 (
\#define \TEMP2(TEMP0) f
)
温度1
)TEMP2(v)
#define LAMBDA(x,f,v) SILENT(
#ifneq (v) ()
#define TEMP3(a,b,c) EVAL(a,b,c)
#その他
#define TEMP3(a,b,c) \LAMBDA(a,b)
#endif
)TEMP3(x,f,v)
#define EVALAMBDA(x,y) SILENT(
#defefval TEMP4 x
#defefval TEMP5 y
)
#define APPLY(f,v) SILENT(
#defefval TEMP6 ASIS(\EVA)f
温度6
)EVAL(TEMP4,TEMP5,v)

これにより、次の結果が得られます。

ラムダ(z,z+z)
=> ラムダ(z,z+z)

ラムダ(z,z+z,2)
=> 2+2

#define f LAMBDA(y,y*y)
f
=> ラムダ(y,y*y)

適用(f、まあ)
=> なんとか*なんとか

APPLY(LAMBDA(t,tt),(tt))
=> (tt) (tt)

LAMBDA(x,APPLY(f,(x+x)),urf)
=> (urf+urf)*(urf+urf)

APPLY(APPLY(LAMBDA(x,LAMBDA(y,x*y)),foo),bar)
=> foo*bar

#define test LAMBDA(y,`#ifeq y urf
y は urf#else
y は urf#endif ではありません
`)
APPLY(テスト、URF)
=> ウルフはウルフです

APPLY(テスト,foo)
=> foo は urf ではありません

onworks.net サービスを使用してオンラインで gpp を使用する


無料のサーバーとワークステーション

Windows と Linux のアプリをダウンロード

Linuxコマンド

Ad