And*_*son 8 c implementation encode objective-c
@encode指令返回一个const char*,它是传入的数据类型的各种元素的编码类型描述符.示例如下:
struct test
{ int ti ;
char tc ;
} ;
printf( "%s", @encode(struct test) ) ;
// returns "{test=ic}"
Run Code Online (Sandbox Code Playgroud)
我可以看到使用sizeof()来确定原始类型 - 如果它是一个完整的对象,我可以使用类方法进行内省.
但是,它如何确定不透明结构的每个元素?
joh*_*hne 15
@Lothars的答案可能是"玩世不恭",但不幸的是,它非常接近标记.为了实现类似的东西@encode(),你需要一个完整的解析器来提取类型信息.好吧,至少除了"琐碎"的@encode()陈述之外的任何事情(即@encode(char *)).现代编译器通常有两个或三个主要组件:
前端必须解析所有源代码,并基本上将源代码文本转换为内部的"机器可用"形式.
后端将内部的"机器可用"表单转换为可执行代码.
具有"中间端"的编译器通常会因为某些需要而这样做:它们支持多个"前端",可能由完全不同的语言组成.另一个原因是简化优化:所有优化过程都在相同的中间表示上工作.所述gcc编译器套件是一个"三个阶段"的编译器的一个例子. llvm可以被认为是"中间和后端"阶段编译器:"低级虚拟机"是中间表示,所有优化都以这种形式进行. llvm也能够将它保持在这个中间表示中直到最后一秒 - 这允许"链接时间优化".所述clang编译器是一个真正的"前端"的是(有效地)输出llvm的中间表示.
因此,如果要向@encode()"现有"编译器添加功能,则可能必须将其作为"源到源""编译器/预处理器".这就是原始Objective-C和C++编译器的编写方式 - 他们解析了输入源文本并将其转换为"plain C",然后将其输入到标准C编译器中.有几种方法可以做到这一点:
yacc和lex组合ANSI-C解析器.你需要一个语法 - ANSI C语法(Yacc)是一个好的开始.实际上,要说清楚,当我说yacc,我真的是指 野牛和flex.而且,松散的,其他各种yacc与lex像基于C语言的工具:柠檬,的DParser,等...perl与亚普或EYapp,这是假yacc的克隆perl.对比起基于C语言的快速原型设计的想法可能是更好的yacc和lex它的- perl正则表达式,关联数组,没有内存管理等:毕竟注意:我没有使用任何这些工具做任何添加的个人经验@encode(),但我怀疑它们会有很大的帮助.
@Lothar在他的评论中提出了一个很好的观点.我实际上打算包括lcc,但看起来它在途中迷路了.
lccC编译器.这是一个特别小的C编译器,至少在源代码大小方面.它还有一本书,我强烈推荐.tccC编译器.不像教学那样lcc,但绝对值得一看.pocObjective-C编译器.这是一个"源到源"Objective-C编译器.它解析Objective-C源代码并发出C源代码,然后传递给它gcc(通常gcc).有许多不可用的Objective-C扩展/功能gcc.绝对值得一看.