python中带嵌套if的智能自动C代码生成器 我从Python生成自动C++代码,特别是我需要为事件列表选择一些事件。我宣布一些选择: selectionA = Selection(name="selectionA", formula="A>10") selectionB = Selection(name="selectionB", formula="cobject->f()>50") selectionC = selectionA * selectionB # * means AND 生成C++代码: for(...) { // cicle on events event = GetEvent(i); bool selectionA = A>10; bool selectionB = cobject->f()>50; bool selectionC = (A>10) and (cobject->f()>50); if (selectionA) { histo_selectionA->Fill(event); } if (selectionB) { histo_selectionB->Fill(event); } if (selectionC) { histo_selectionC->Fill(event); } }

python中带嵌套if的智能自动C代码生成器 我从Python生成自动C++代码,特别是我需要为事件列表选择一些事件。我宣布一些选择: selectionA = Selection(name="selectionA", formula="A>10") selectionB = Selection(name="selectionB", formula="cobject->f()>50") selectionC = selectionA * selectionB # * means AND 生成C++代码: for(...) { // cicle on events event = GetEvent(i); bool selectionA = A>10; bool selectionB = cobject->f()>50; bool selectionC = (A>10) and (cobject->f()>50); if (selectionA) { histo_selectionA->Fill(event); } if (selectionB) { histo_selectionB->Fill(event); } if (selectionC) { histo_selectionC->Fill(event); } },c++,python,compiler-construction,code-generation,C++,Python,Compiler Construction,Code Generation,这不是很聪明,因为最聪明的代码是: bool selectionC = selectionA and selectionB 这个问题似乎很简单,但事实并非如此,因为我有100多个基本选择(如selectionA或selectionB)和300多个派生选择,当然派生选择可以从派生选择中派生。明显的派生选择不是使用规则模式从基本选择派生的 我知道很难回答,但有人能给我一些提示吗?例如:真的有必要编写智能代码吗?我的意思是,编译器无法优化此代码?编译器不太可能优化此代码。部分原因是cobject->

这不是很聪明,因为最聪明的代码是:

bool selectionC = selectionA and selectionB
这个问题似乎很简单,但事实并非如此,因为我有100多个基本选择(如
selectionA
selectionB
)和300多个派生选择,当然派生选择可以从派生选择中派生。明显的派生选择不是使用规则模式从基本选择派生的


我知道很难回答,但有人能给我一些提示吗?例如:真的有必要编写智能代码吗?我的意思是,编译器无法优化此代码?

编译器不太可能优化此代码。部分原因是
cobject->f()
可能有编译器看不到的副作用

您可以通过将布尔值声明为
const
来提供一些小的帮助

否则,看起来您已经在重载运算符来组合选择。因此,使用组合选项的名称而不是表达式进行组合选择应该不会太难。这会对您进行一些优化,并允许编译器在可能的情况下进一步优化,特别是如果您将选择布尔值声明为
const


您还必须小心地发出代码来初始化
bool
标志,其顺序与在Python中创建选择对象的顺序相同。这将确保在以后使用前始终声明并初始化
bool
。您可以通过在Python
Selection
类中创建一个列表,并使用
\uuuu init\uuuu
方法将新的
选择添加到该列表中来实现这一点。当然,如果您创建
选择
对象,然后将其丢弃,这可能是一个问题。但是如果你把它们都保留下来,它就可以工作。

编译器可能能够优化这段代码,但是如果你有数百个相互依赖的复杂表达式,我会怀疑它是否能工作得那么好

但一个更基本的问题是:你真的需要优化吗?计算机速度很快,如果您不经常运行该代码,那么无论是运行一次还是十次
cobject->f()>50

另一方面,如果
cobject->f()
有副作用(例如,它打印了一些东西),编译器将永远不会优化掉重复的调用,您必须确保只在生成的代码中调用它,只要您希望它打印一些东西


最好的解决方案是,如果您的
选择
类在用作派生定义的一部分时只输出
名称
,而不是
公式
。这有多困难或容易取决于生成代码。

作为对我评论的修正,我甚至不认为您需要我建议的跟踪变量。为什么不试试这个

import string

class Selection:
    selections = []
    letters = string.letters[26:] + string.letters[:26]

    def __init__(self, name, formula):
        self.name = name
        self.formula = formula
        Selection.selections.append(self)

    def __mul__(self, selection):
        name = 'selection' + letters[len(selections)]
        return Selection(name, self.name + ' and ' + selection.name)

    @classmethod
    def generate(c):
        code = []
        for selection in c.selections:
            code.append('bool ')
            code.append(selection.name)
            code.append(' = ')
            code.append(selection.formula)
            code.append(';\n')

        code.append('\n')

        for selection in c.selections:
            code.append('if (')
            code.append(selection.name)
            code.append(') { histo_')
            code.append(selection.name)
            code.append('->Fill(event); }\n')

        return ''.join(code)

当然,这只适用于假设您只有52个选择对象,但这种限制只存在,因为此类只生成表单选择[A-Za-z]的名称。因此,如果我正确理解了您的示例,您是否正在创建一组选择对象,然后使用它们生成代码

首先,为什么不直接在C++中编写代码呢?事实上,你将Python中的C++表达式嵌入字符串变量,并使用重载的数学运算符来构造布尔表达式(事实上,你觉得需要评论*意味着这是一个糟糕的选择)。那简直太难看了


也就是说,您已经拥有了所需的所有信息——在Python代码中,selectionA知道它的名称是“selectionA”,selectionB知道它的名称是“selectionB”。唯一的问题是,您没有提供足够的上下文来了解对象selectionC的类型。我假设它类似于AndExpression,并包含引用selectionA和selectionB(可能是param1和param2?)。只要有它的输出<代码>(“+ + Self.PARAM1.NAME+”& &“+ Self.PARAM2.NAME+”)“”/< P>我相信大多数C++编译器已经为你做了这件事。为什么你没有一个在第一代扩展到公式的变量,然后是布尔条件的名称?@blwy10:因为这并不容易,特别是你必须保证以正确的顺序声明布尔变量,并且没有重复,所以这并不容易。但考虑到选择对象只能通过其构造函数或*运算符创建,而该构造函数或*运算符已可用于跟踪函数中所有选择变量的顺序。除非我在这里漏掉了一些东西…我用Python生成C++代码,因为代码非常枯燥、简单、重复,但是很长(10000行)。python代码生成C++代码,编译它,执行程序中的一些参数,并使用它们的输出。在Python中,你不能过载和操作,因为它们很懒,所以你需要使用其他东西,它不是很好,但它不是那么简单。关键是您需要知道,您必须在
selectionC
之前声明
selectionA
selectionB
。我的例子是微不足道的,现实生活不是。嗯,也许有更好的方法来编写C++代码?真的,如果你发现自己写了10000多行“枯燥、简单、重复但很长”的代码,那么你就做错了。而且,我知道你不能用Python重写
。但关键是,如果你需要解释覆盖意味着什么,那么它可能不是一个合适的覆盖——用一个方法代替。