Objective c C预处理器的替换

Objective c C预处理器的替换,objective-c,c,c-preprocessor,Objective C,C,C Preprocessor,我对使用C预处理器以外的东西来预处理我的C和Objective-C源代码感兴趣。有好的选择吗 一个例子,它允许一个在强> c>强>代码中间跳出Python或Perl代码段,其中代码段吐出 c>强>,然后编译为正常。 您可能需要考虑M4。 我看到一篇2001年的论文介绍了一种类似python的预处理器。不清楚是否有人在使用它。我过去也曾考虑过同样的问题。确保您同意这样一个事实,即任何想要编译您的代码的人都需要新的预处理工具。如果你是唯一一个在这上面工作的人,没问题,但是如果你想让代码对其他人有用,

我对使用C预处理器以外的东西来预处理我的C和Objective-C源代码感兴趣。有好的选择吗


一个例子,它允许一个在<>强> c>强>代码中间跳出Python或Perl代码段,其中代码段吐出<强> c>强>,然后编译为正常。

您可能需要考虑M4。
我看到一篇2001年的论文介绍了一种类似python的预处理器。不清楚是否有人在使用它。

我过去也曾考虑过同样的问题。确保您同意这样一个事实,即任何想要编译您的代码的人都需要新的预处理工具。如果你是唯一一个在这上面工作的人,没问题,但是如果你想让代码对其他人有用,那么你可能想考虑是否添加一个工具需求是个好主意。

不是一个预处理器,但是它确实在代码中运行,并在飞行中生成东西。预处理器与C的语义联系如此紧密,以至于您无法真正删除它,事实上,在某些编译器中,甚至不像过去那样是一个单独的阶段——在Mac上编译Objective C只是解析Objective C语法。因此,虽然您当然可以使用另一个宏处理器,如m4,在将源文本传递给C之前对其进行处理,但您不会消除C预处理器,而是添加了另一个预处理步骤


但是这里有一个更深层的问题:通过消除CPP阶段你想要获得什么?

< P>如果你准备用C++来弄脏你的手,在Boost中有一个波形分析器,它是使用精神递归下降分析器构建的。它是一个完整的C预处理器,符合C和C++的所有最新规范(以及扩展,目标C,AFAICS)。p> 它是高度模块化的,所以你可以切换你自己的驱动程序,可以做额外的你想要的


您可以使用自己喜欢的编程语言构建脚本/工具来生成源文件(.c/.cpp或.h,或其他任何文件)。只需
#将它们包括在内或编译到您的项目中。在
#include
附近添加注释可能有助于识别工具所在/位置以及生成的内容


这可能不像使用“真正的”预处理器那么方便(或干净),但它可以工作。同样,这取决于您的情况。

运行代码,然后将结果拼接到中的想法称为准旋转。您运行的代码是

我知道如何使用Lua解决这个问题。我使用了
string.gsub
和我自己编写的反旋转函数。我使用了反旋转的shell语法。与shell中一样,反编译代码返回一个字符串,然后将该字符串拼接到代码中

下面的
prog
是带有反转录文本的C代码,
antiNote
是反转录功能。我充分利用了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)
names={'John','Paul','George','Ringo'}
本地程序=[===[
#包括
main(){
$(本地输出={}
对于ipairs(名称)do中的n
table.insert(out,string.format([[printf(“名称是%%s\n”,%q);]],n))
结束
返回表.concat(out,“\n”)
)
}
]===]
本地功能
局部正文=s:匹配“^%$%”((.*))$”
返回断言(loadstring(body))()
结束
prog=prog:gsub(“%$%b()”,AntiNote)
io.stdout:写入(程序)
在使用中,程序如下所示:

: 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");
}
:nr@curlycoat 1181 ; lua/home/nr/tmp/emit-c.lua
#包括
main(){
printf(“名称为%s\n”,“John”);
printf(“名称为%s\n”,“Paul”);
printf(“名称为%s\n”,“乔治”);
printf(“名称为%s\n”,“Ringo”);
}

我很想看看人们的想法。我倾向于使用Perl编写的预处理器来完成一些小的定制工作。很容易装配一个调用预处理器的Makefile。例如,这里有一条规则,可以调用名为“meta”的程序从“file.c.meta”生成“file.c”

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

我正在用“meta”做一些有趣的事情,比如生成定制的FitC数据结构。这绝对是我建议探索的方向。我希望最终能得到一个与C++模板大致平行的元库。

CPP对C代码做了很多重要的事情,而这些代码可能不需要重新实现。您似乎在寻找的可能是一个发出C代码的模板化过程


它只是众多允许您使用python的工具之一。还有一些人使用python,还有更多的人使用其他语言,但Cheetah以输出不可知而闻名,其中一些模板引擎非常倾向于HTML/XML。做你的研究。

如果你稍微抽象一下你的问题,那么你实际上是在为你的代码寻找一个模板引擎。正如大多数网站在静态模板中插入动态生成的内容一样,您也希望在程序中插入动态生成的代码


我目前在大多数模板工作中使用Jinja2(Python)——我发现它在各个方面都非常可配置。

当然,标准C预处理器非常有限。
我最近做了这样一个工具:

比如这个

<?
    my @types = ('char', 'int', 'long'); 
    foreach (@types) {
?>
        <?= $_ ?> read_<?= uc($_) ?>(<?= $_ ?>* v);
<?  } ?>
语法类似于PHP,但它使用Perl,可以将文本捕获到Perl Sting中


Editby-经@d-ash批准,我也是perlpp的维护者。如果你有问题,请随时给我写信

您可以使用PHP作为C预处理器。优点是:

  • 非常相似的语法,因此语法高亮显示很有效
  • 不在st中使用
    char read_CHAR(char* v);
    int read_INT(int* v);
    long read_LONG(long* v);
    
    <?php include_once "stdio.h"; ?>
    
    int main()
    {
        <?php
            for($i = 0; $i < 20; $i++)
                echo 'printf("%d\n", '.$i.');';
        ?>
    }