我有兴趣使用 C 预处理器之外的其他东西来预处理我的 C 和Objective-C源代码。有没有好的选择?
一个例子是允许一个人在 C 代码中间逃出一个python或perl片段,并且片段吐出 C ,这是然后正常编译。
答案 0 :(得分:53)
您可以使用 PHP 作为C预处理器。优点是:
<?
和?>
未在标准C中使用(使用非标准C,唯一被破坏的是返回最小/最大值的旧GCC扩展运算符)为了认真使用,调试预处理代码需要PHP打印#line指令。
<?php include_once "stdio.h"; ?>
int main()
{
<?php
for($i = 0; $i < 20; $i++)
echo 'printf("%d\n", '.$i.');';
?>
}
答案 1 :(得分:10)
Cog并不是一个预处理器,但它确实在代码中内嵌,并在运行中生成内容。
答案 2 :(得分:9)
您运行代码,然后将其结果拼接在中的想法称为 quasiquotation 。您运行的代码是反引用。
我知道如何使用Lua解决这个问题。我使用了string.gsub
我自己写的反引号功能。我已经使用shell语法进行反引号。与在shell中一样,反引号代码返回一个字符串,然后将其拼接到代码中。
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");
}
答案 3 :(得分:7)
您可能需要考虑m4 http://www.gnu.org/software/m4/
答案 4 :(得分:5)
如果您准备好接受一些C ++,那么Boost中的Wave解析器就是使用Spirit递归下降解析器构建的。它是一个完整的C预处理器,符合C和C ++的所有最新规范(以及扩展,Objective C,AFAICS)。
它是高度模块化的,所以你可以切换自己的驱动程序,这可以做你想要的额外功能。
答案 5 :(得分:5)
如果您稍微抽象出问题,那么您实际上正在为您的代码寻找模板引擎。正如大多数网站在静态模板中插入动态生成的内容一样,您希望将动态生成的代码插入到程序中。
我目前使用 Jinja2 (Python)进行大多数模板工作 - 我发现它可以以各种方式进行非常配置。
答案 6 :(得分:5)
当然,标准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 stings中。
cxw编辑 - 在@ d-ash的批准下,我也是perlpp的维护者。如果您有任何疑问,请随时给我留言!
答案 7 :(得分:3)
我过去曾想过同样的问题。确保任何想要编译代码的人都需要新的预处理工具。如果你是唯一一个会参与其中的人,没问题,但是如果你想让其他人可以使用这些代码,那么你可能想要考虑是否添加工具要求是一个好主意。
答案 8 :(得分:3)
简短的回答是“不”。预处理器与C的语义密切相关,你无法真正删除它,实际上在某些编译器中甚至不像过去那样单独的阶段---编译目标C Mac只是解析Objective C语法。因此,虽然您可以使用其他宏处理器(如m4)来处理源文本,然后再将其传递给C,但您不会消除 C预处理器,您将添加预处理的另一个步骤。
但是这里有一个更深层次的问题:你想通过消除CPP阶段获得是什么?
答案 9 :(得分:3)
CPP为C代码做了很多重要的事情,你可能不需要重新实现它们。你似乎在寻找的东西可能是一个发出C代码的模板化过程。
Cheetah只是允许您使用python的众多功能之一。还有其他人使用python,还有更多其他语言,但Cheetah因输出不可知而闻名,其中一些模板引擎非常注重HTML / XML。做你的研究。
答案 10 :(得分:1)
我看到2001年的一篇论文介绍了类似python的预处理器http://ray.cg.tuwien.ac.at/rft/Papers/PYM/pym.html。目前尚不清楚是否有人在使用它..
答案 11 :(得分:1)
您可以使用自己喜欢的编程语言来构建脚本/工具来生成源文件(.c / .cpp或.h,或其他)。只需#include
他们或将它们编译到您的项目中。在#include
附近发表评论可能有助于确定工具的位置和位置以及生成的内容。
这可能不像使用“真正的”预处理器那样方便(或干净),但它可以工作。然后,这真的取决于你的情况。
答案 12 :(得分:1)
我有兴趣看看人们想出了什么。我倾向于用Perl编写的预处理器来做小的自定义事情。装配调用预处理器的Makefile很容易。例如,这里有一个规则来调用名为'meta'的程序从'file.c.meta'生成'file.c'。
% :: %.meta
meta $< > $@
我正在使用'meta'做有趣的事情,比如生成自定义适合的C数据结构。这绝对是我建议探索的方向。我希望最终能够提出一个与C ++模板大致平行的元库。