C:转换A? B : C 进入 if (A) B else C
我正在寻找一种工具,可以将以下形式的 C 代码表达式转换
a = (A) ? B : C;
为带有 if
/else
语句的“默认”语法:
if (A)
a = B
else
a = C
有人知道有一种工具能够做这样的改造吗?
我使用 GCC 4.4.2 并使用 -E
创建一个预处理文件,但不希望其中包含此类结构。
编辑: 以下代码也应该进行转换:
a = ((A) ? B : C)->b;
I was looking for a tool that can convert C code expressions for the form:
a = (A) ? B : C;
into the 'default' syntax with if
/else
statements:
if (A)
a = B
else
a = C
Does someone know a tool that's capable to do such a transformation?
I work with GCC 4.4.2 and create a preprocessed file with -E
but do not want such structures in it.
Edit:
Following code should be transformed, too:
a = ((A) ? B : C)->b;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我不知道三元运算符作为
if
逻辑的快捷方式内置在语言规范中......我能想到的唯一方法是手动查找这些行并将其重写为使用if
的形式...作为普遍共识,三元运算符的工作方式如下:如果表达式被评估为 true,则执行
? 之间的部分
和:
,否则执行:
和;
之间的最后一部分。如果表达式的计算结果为 false,则情况相反I am not aware of such a thing as the ternary operator is built-into the language specifications as a shortcut for the
if
logic... the only way I can think of doing this is to manually look for those lines and rewrite it into the form whereif
is used... as a general consensus, the ternary operator works like thisIf the expression is evaluated to be true, execute the part between
?
and:
, otherwise execute the last part between:
and;
. It would be the reverse if the expression is evaluated to be false如果这些语句像这样非常有规律,为什么不通过一个小的 Perl 脚本来运行您的文件呢?对于您的示例行来说,执行查找和转换的核心逻辑很简单。这是一种简单的方法:
您可以像这样运行它:
当然,如果文本模式不像您发布的那样规则,它会变得越来越难。但免费、快速且易于尝试。
If the statements are very regular like this why not run your files through a little Perl script? The core logic to do the find-and-transform is simple for your example line. Here's a bare bones approach:
You'd run it like so:
Of course it gets harder and harder if the text pattern isn't as regular as the one you posted. But free, quick and easy to try.
Coccinelle 可以很轻松地做到这一点。
编辑:
语义补丁的示例:
来自文档:
此处提供了一组很好的示例。
邮件列表非常活跃并且很有帮助。
Coccinelle can do this quite easily.
EDIT:
An example of semantic patch:
From the documentation:
You have a good set of examples here.
The mailing list is really active and helpful.
Coccinelle 的以下语义补丁将进行转换。
The following semantic patch for Coccinelle will do the transformation.
DMS 软件再工程工具包可以通过应用程序转换来做到这一点。
与您的特定示例相匹配的特定 DMS 转换:
您需要另一个规则来处理其他情况,但它同样容易表达。
转换对源代码结构而不是文本进行操作,因此布局和注释不会影响识别或应用。规则中的引号不是传统的字符串引号,而是元语言引号,它将规则语法语言与用于指定要更改的具体语法的模式语言分开。
如果您打算保留预处理指令,则会出现一些问题。由于您显然愿意使用预处理器扩展的代码,因此您可以要求 DMS 将预处理作为转换步骤的一部分;它内置了完整的 GCC4 和 GCC4 兼容预处理器。
正如其他人所观察到的,这是一个相当简单的情况,因为您指定它在完整语句的级别上工作。如果您想删除代码中与此语句类似的任何赋值,并且将此类赋值嵌入到各种上下文(初始化程序等)中,您可能需要一组更大的转换来处理各种特殊情况,并且您可能需要制造其他代码结构(例如,适当类型的临时变量)。像 DMS 这样的工具的好处是它可以显式计算任意表达式的符号类型(从而任何所需临时值的类型声明),并且您可以相当直接地编写这样一个更大的集合并应用所有它们。
尽管如此,我不确定执行三元条件表达式消除操作的真正价值。一旦编译器获得结果,您可能会获得类似的目标代码,就好像您根本没有进行转换一样。毕竟,编译器也可以应用保留等价的转换。
不过,总的来说,定期进行更改显然是有价值的。
(DMS 可以将源到源程序转换应用于许多语言,包括 C、C++、Java、C# 和 PHP)。
The DMS Software Reengineering Toolkit can do this, by applying program transformations.
A specific DMS transformation to match your specific example:
You'd need another rule to handle your other case, but it is equally easy to express.
The transformations operate on source code structures rather than text, so layout out and comments won't affect recognition or application. The quotation marks in the rule not traditional string quotes, but rather are metalinguistic quotes that separate the rule syntax language from the pattern langu age used to specify the concrete syntax to be changed.
There are some issues with preprocessing directives if you intend to retain them. Since you apparantly are willing to work with preprocessor-expanded code, you can ask DMS to do the preprocessing as part of the transformation step; it has full GCC4 and GCC4-compatible preprocessors built right in.
As others have observed, this is a rather easy case because you specified it work at the level of a full statement. If you want to rid the code of any assignment that looks similar to this statement, with such assignments embedded in various contexts (initializers, etc.) you may need a larger set of transforms to handle the various set of special cases, and you may need to manufacture other code structures (e.g., temp variables of appropriate type). The good thing about a tool like DMS is that it can explicitly compute a symbolic type for an arbitrary expression (thus the type declaration of any needed temps) and that you can write such a larger set rather straightforwardly and apply all of them.
All that said, I'm not sure of the real value of doing your ternary-conditional-expression elimination operation. Once the compiler gets hold of the result, you may get similar object code as if you had not done the transformations at all. After all, the compiler can apply equivalence-preserving transformations, too.
There is obviously value in making regular changes in general, though.
(DMS can apply source-to-source program transformations to many langauges, including C, C++, Java, C# and PHP).