我如何实现类似于ANSI C中的Objective-C @encode()编译器指令的东西?

@encode指令返回一个const char *,它是传入的数据类型的各种元素的编码类型描述符.示例如下:

struct test
{ int ti ;
  char tc ;
} ;

printf( "%s", @encode(struct test) ) ;
// returns "{test=ic}"

我可以看到使用sizeof()来确定原始类型 – 如果它是一个完整的对象,我可以使用类方法进行内省.

但是,它如何确定不透明结构的每个元素?

@Lothars的回答可能是“愤世嫉俗”,但不幸的是,它非常接近标记.为了实现像@encode()这样的东西,你需要一个完整的解析器来提取类型信息.好吧,至少除了“琐碎的”@encode()语句之外的任何东西(即@encode(char *)).现代编译器通常有两个或三个主要组件:

>前端.
>中间端(对于某些编译器).
>后端.

前端必须解析所有源代码,并基本上将源代码文本转换为内部的“机器可用”形式.

后端将内部的“机器可用”表单转换为可执行代码.

具有“中间端”的编译器通常会因为某些需要而这样做:它们支持多个“前端”,可能由完全不同的语言组成.另一个原因是简化优化:所有优化过程都在相同的中间表示上工作. gcc编译器套件是“三阶段”编译器的一个例子. llvm可以被认为是“中间和后端”阶段编译器:“低级虚拟机”是中间表示,并且所有优化都以这种形式发生. llvm也能够将它保持在这个中间表示中直到最后一秒 – 这允许“链接时间优化”. clang编译器实际上是一个“前端”,它(有效地)输出llvm中间表示.

因此,如果您想将@encode()功能添加到“现有”编译器中,您可能必须将其作为“源到源”“编译器/预处理器”.这就是原始Objective-C和C编译器的编写方式 – 他们解析了输入源文本并将其转换为“plain C”,然后将其输入标准C编译器.有几种方法可以做到这一点:

滚动你自己

>使用yacc和lex组合ANSI-C解析器.你需要一个语法-ANSI C grammar (Yacc)是一个好的开始.实际上,要明确的是,当我说yacc时,我的意思是bison和flex.而且,松散地,其他各种yacc和lex像基于C的工具:lemon,dparser等……
>将perl与YappEYapp一起使用,它们是perl中的伪yacc克隆.与基于C的yacc和lex相比,对于快速原型构建一个想法可能更好:毕竟它是perl:正则表达式,关联数组,无内存管理等.
>使用Antlr构建解析器.我对此工具链没有任何经验,但它是另一个“编译器编译器”工具(似乎)更适合Java开发人员.似乎有免费提供的C和Objective-C语法.

破解另一个工具

注意:我没有使用任何这些工具做任何事情的个人经验,比如添加@encode(),但我怀疑它们会有很大的帮助.

> CIL – 没有使用此工具的个人经验,但设计用于解析C源代码,然后用它“做事”.从我可以从文档中收集到的内容,此工具应该允许您提取您需要的类型信息.
> Sparse – 值得一看,但不确定.
> clang – 没有将它用于此目的,但据称其中一个目标是使其“容易被黑客攻击”这种东西.特别是(再次,没有个人经验)在做所有解析的“繁重”,让你专注于“有趣”部分,在这种情况下将提取上下文和语法敏感类型信息,然后转换为到一个普通的C字符串.
> gcc Plugins – 插件是gcc 4.5(这是编译器的当前alpha / beta版本)功能,“可能”允许您轻松地连接到编译器以提取您需要的类型信息.不知道插件架构是否允许这种事情.

其他

> Coccinelle – 最近将此标记为“稍后再看”.这“可能”能够做你想做的事情,并且“可能”能够付出很多努力.
> MetaC – 最近也预订了这个.不知道这会有多大用处.
> mygcc – “可能”做你想做的事.这是一个有趣的想法,但它并不直接适用于你想要的东西.从网页:“Mygcc允许程序员添加自己的检查,考虑语法,控制流和数据流信息.”

链接.

> CocoaDev Objective-C Parsing – 值得一看.有一些词法和词法的链接.

编辑#1,奖金链接.

@Lothar在他的评论中提出了一个很好的观点.我实际上打算包括lcc,但看起来它在途中迷路了.

> lcc – lcc C编译器.这是一个特别小的C编译器,至少在源代码大小方面.它也是has a book,我强烈推荐.
> tcc – tcc C编译器.不像lcc那样教学,但绝对值得一看.
> poc – poc Objective-C编译器.这是一个“源到源”Objective-C编译器.它解析Objective-C源代码并发出C源代码,然后传递给gcc(好吧,通常是gcc).有许多在gcc中没有的Objective-C扩展/功能.绝对值得一看.

翻译自:https://stackoverflow.com/questions/2255637/how-would-i-implement-something-similar-to-the-objective-c-encode-compiler-di

转载注明原文:我如何实现类似于ANSI C中的Objective-C @encode()编译器指令的东西?