@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++ 编译器的编写方式——它们解析输入源文本并将其转换为“纯 C”,然后将其输入到标准 C 编译器。有几种方法可以做到这一点:
自己滚动
- Use
yacc
and lex
组装一个 ANSI-C 解析器。你需要语法——ANSI C 语法 (Yacc) http://www.lysator.liu.se/c/ANSI-C-grammar-y.html是一个好的开始。事实上,要明确的是,当我说yacc
,我真的是说bison http://www.gnu.org/software/bison/ and flex
。而且,松散地,其他各种yacc
and lex
比如基于 C 的工具:lemon http://www.hwaci.com/sw/lemon/, dparser http://dparser.sourceforge.net/, etc...
- Use
perl
with Yapp http://search.cpan.org/~fdesar/Parse-Yapp-1.05/lib/Parse/Yapp.pm or EYapp http://search.cpan.org/~casiano/Parse-Eyapp-1.157/lib/Parse/Eyapp.pod,它们是伪yacc
克隆于perl
。与基于 C 的相比,可能更适合快速构建想法原型yacc
and lex
- it's perl
毕竟:正则表达式、关联数组、无内存管理等。
- 构建你的解析器Antlr http://www.antlr.org/。我对这个工具链没有任何经验,但它是另一个“编译器编译器”工具,(似乎)更适合java开发人员。似乎有免费的 C 和 Objective-C 语法可供使用。
破解另一个工具
Note:我没有使用任何这些工具执行诸如添加之类的个人经验@encode()
,但我怀疑它们会很有帮助。
-
CIL http://hal.cs.berkeley.edu/cil/- 没有使用此工具的个人经验,但设计用于解析 C 源代码,然后用它“做事”。根据我从文档中收集到的信息,该工具应该允许您提取所需的类型信息。
-
Sparse http://sparse.wiki.kernel.org/index.php/Main_Page- 值得一看,但不确定。
-
clang http://clang.llvm.org/- 尚未将其用于此目的,但据称目标之一是使其“易于破解”以用于此类内容。特别是(再次强调,没有个人经验)在进行所有解析的“繁重工作”时,让您专注于“有趣”的部分,在这种情况下将提取上下文和语法敏感的类型信息,然后将其转换为到一个普通的 C 字符串。
-
海湾合作委员会插件 http://gcc.gnu.org/onlinedocs/gccint/Plugins.html#Plugins- 插件是 gcc 4.5(编译器当前的 alpha/beta 版本)功能,“可能”允许您轻松连接到编译器以提取您需要的类型信息。不知道插件架构是否允许这种事情。
Others
-
科奇内勒 http://Coccinelle.lip6.fr/- 最近将此添加为书签以“稍后查看”。这个“也许”能够做到你想要的,并且“也许”不费吹灰之力就能做到。
-
MetaC http://www.rcs.ei.tum.de/research/MetaC/index_html- 最近也为这个添加了书签。不知道这会有多大用处。
-
mygcc http://mygcc.free.fr/- “可能”做你想做的事。这是一个有趣的想法,但它并不直接适用于你想要的。来自网页:“Mygcc 允许程序员添加自己的检查,考虑语法、控制流和数据流信息。”
Links.
-
CocoaDev Objective-C 解析 http://www.cocoadev.com/index.pl?ObjectiveCParser- 值得一看。有一些词法分析器和语法的链接。
编辑#1,奖励链接。
@Lothar 在他的评论中提出了一个很好的观点。我实际上本来打算包括lcc
,不过看起来好像迷路了。
-
lcc http://sites.google.com/site/lccretargetablecompiler/ - The
lcc
C 编译器。这是一个特别小的C编译器,至少在源代码大小方面是这样。它也是有书 https://rads.stackoverflow.com/amzn/click/com/0805316701,我强烈推荐。
-
tcc http://bellard.org/tcc/ - The
tcc
C 编译器。不太有教学意义lcc
,但绝对还是值得一看的。
-
poc http://www.ibiblio.org/pub/Linux/devel/lang/objc/ - The
poc
Objective-C 编译器。这是一个“源到源”的 Objective-C 编译器。它解析 Objective-C 源代码并生成 C 源代码,然后将其传递给gcc
(嗯,通常gcc
)。具有许多 Objective-C 扩展/功能,这些扩展/功能在gcc
。绝对值得一看。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)