43

Cおよび Objective-C のソース コードを前処理するために、 Cプリプロセッサ以外のものを使用することに興味があります。良い代替手段はありますか?

例としては、Cコードの途中で python や perl のスニペットにエスケープできるようにし、そのスニペットがCを吐き出し、それが通常どおりコンパイルされるようなものです。

4

13 に答える 13

63

PHPを C プリプロセッサとして使用できます。利点は次のとおりです。

  • 非常に類似した構文であるため、構文の強調表示が機能します。
  • <?標準 C では使用され?>ません (非標準 C では、壊れる唯一のものは、最小/最大を返す古い GCC 拡張演算子です)。
  • ライブラリが豊富です。
  • チューリング完了です。
  • マクロの使用法は非常に明示的です。(卑劣な C プリプロセッサ マクロと比較して)

ただし、真剣に使用する場合は、前処理されたコードをデバッグするために PHP に #line ディレクティブを出力させる必要があります。

<?php include_once "stdio.h"; ?>

int main()
{
    <?php
        for($i = 0; $i < 20; $i++)
            echo 'printf("%d\n", '.$i.');';
    ?>
}
于 2013-04-27T19:28:03.723 に答える
10

m4 を検討することをお勧めします。
http://www.gnu.org/software/m4/

于 2008-12-28T20:34:16.907 に答える
10

Cogは正確にはプリプロセッサではありませんが、コード内でインライン化され、オンザフライで生成されます。

于 2008-12-28T20:55:03.573 に答える
9

コードを実行し、その結果をスプライスするという考え方は、準引用と呼ばれます。実行するコードは引用符で囲まれていません。

私はLuaを使用してこの問題を解決する方法を知っています。自分で書いた引用防止関数を使用string.gsubしました。引用符の引用にはシェル構文を使用しました。シェルの場合と同様に、引用符で囲まれていないコードは文字列を返し、それがコードにスプライスされます。

以下progは、引用符で囲まれていないテキストを含むCコードであり、引用符で囲まれantiquoteていない関数です。二重角かっこを引用するLuaの特別な文字列を最大限に活用しました。 実際には、これは行いません。別のファイルに入れprogます。

names = { 'John', 'Paul', 'George', 'Ringo' }

local prog = [===[
#include <stdio.h>

main() {
  $(local out = { }
    for _, n in ipairs(names) do
      table.insert(out, string.format([[  printf("The name is %%s\n", %q);]], n))
    end
    return table.concat(out, '\n  ')
   )
}
]===]


local function antiquote(s)
  local body = s:match '^%$%((.*)%)$'
  return assert(loadstring(body))()
end

prog = prog:gsub('%$%b()', antiquote)
io.stdout:write(prog)

使用中のプログラムは次のようになります。

: nr@curlycoat 1181 ; lua /home/nr/tmp/emit-c.lua
#include <stdio.h>

main() {
    printf("The name is %s\n", "John");
    printf("The name is %s\n", "Paul");
    printf("The name is %s\n", "George");
    printf("The name is %s\n", "Ringo");
}
于 2008-12-29T02:23:01.540 に答える
6

確かに、標準の C プリプロセッサは非常に限られています。
最近、このようなツールを作成しました: https://github.com/d-ash/perlpp

たとえば、これ

<?
    my @types = ('char', 'int', 'long'); 
    foreach (@types) {
?>
        <?= $_ ?> read_<?= uc($_) ?>(<?= $_ ?>* v);
<?  } ?>

これになる

char read_CHAR(char* v);
int read_INT(int* v);
long read_LONG(long* v);

構文は PHP に似ていますが、代わりに Perl を使用し、テキストを Perl 文字列に取り込むことができます。

cxwによる編集— @d-ash の承認を得て、私は perlpp のメンテナーでもあります。ご不明な点がございましたら、お気軽にお問い合わせください。

于 2013-02-22T15:24:26.853 に答える
5

問題を少し抽象化すると、実際にはコードのテンプレート エンジンを探していることになります。ほとんどの Web サイトが動的に生成されたコンテンツを静的テンプレートに挿入するように、動的に生成されたコードをプログラムに挿入したいと考えています。

私は現在、ほとんどのテンプレート作業にJinja2 (Python) を使用しています。あらゆる点で非常に構成可能であることがわかりました。

于 2009-07-28T16:50:06.067 に答える
5

C++ で手を汚す準備ができている場合は、Spirit 再帰降下パーサーを使用して構築された Boost の Wave パーサーがあります。これは完全な C プリプロセッサであり、C および C++ のすべての最新仕様 (さらには、Objective C、AFAICS) に準拠しています。

高度にモジュール化されているため、必要な追加機能を実行できる独自のドライバーを切り替えることができます。

http://www.boost.org/libs/wave/doc/introduction.html

于 2008-12-28T20:58:54.453 に答える
3

私は過去にこの同じ問題について考えました。あなたのコードをコンパイルしたい人は誰でも新しい前処理ツールを必要とするという事実に問題がないことを確認してください. あなただけがそれに取り組む場合は問題ありませんが、他の人がコードを利用できるようにしたい場合は、ツール要件を追加することをお勧めします。

于 2008-12-28T20:53:56.650 に答える
3

短い答えは「いいえ」です。プリプロセッサは C のセマンティクスと密接に結びついているため、実際にはそれを削除することはできません。実際、一部のコンパイラでは、昔のように独立したフェーズでさえありません。 Mac は、Objective C 構文を解析するだけです。したがって、m4 などの別のマクロ プロセッサを使用して、ソース テキストを C に渡す前に処理することはできますが、C プリプロセッサを削除するのではなく、前処理の別のステップを追加することになります。

しかし、ここにはもっと深い疑問があります。CPP フェーズをなくすことで何をたいのでしょうか?

于 2008-12-28T20:56:20.200 に答える
3

CPP は、おそらく再実装する必要のない C コードの多くの重要なことを行います。代わりに探しているように見えるのは、C コードを発行するテンプレート プロセスである可能性があります。

Cheetahは、Python を使用できるようにする多くのツールの 1 つにすぎません。Python を使用するものもあれば、他の言語でさらに多くのものを使用するものもありますが、Cheetah は出力に依存しないことで知られており、一部のテンプレート エンジンは HTML/XML を非常に重視しています。あなたの研究をしてください。

于 2008-12-29T15:20:26.463 に答える
2

お気に入りのプログラミング言語を使用してスクリプト/ツールを構築し、ソース ファイル (.c/.cpp または .h など) を生成できます。それらを単純#includeにするか、プロジェクトにコンパイルします。の近くにコメントを付けて#include、ツールがどこにあるのか、何が生成されたのかを識別するのに役立つ場合があります。

これは、「実際の」プリプロセッサを使用するほど便利 (またはクリーン) ではないかもしれませんが、機能します。繰り返しますが、それは本当にあなたのケースに依存します。

于 2008-12-28T21:14:44.610 に答える
1

人々が何を考え出すのか興味があります。私は、Perl で書かれたプリプロセッサを使って小さなカスタム作業を行う傾向がありました。プリプロセッサを呼び出す Makefile を作成するのは簡単です。たとえば、「meta」という名前のプログラムを呼び出して、「file.c.meta」から「file.c」を生成するルールは次のとおりです。

% :: %.meta
    meta $< > $@

カスタムフィットのCデータ構造を生成するなど、「メタ」を使って楽しいことをしています。それは間違いなく私が探求することをお勧めする方向です. 私の希望は、最終的には C++ テンプレートとほぼ同等のメタ ライブラリを思いつくことです。

于 2008-12-29T06:28:43.790 に答える
1

Python のようなプリプロセッサhttp://ray.cg.tuwien.ac.at/rft/Papers/PYM/pym.htmlを紹介する 2001 年の論文を見ました。誰かが使っているかどうかは明らかではありません..

于 2008-12-28T20:36:16.217 に答える