65.9K
CodeProject 正在变化。 阅读更多。
Home

Python 中非常简单的 C++ 代码生成

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (16投票s)

2013 年 4 月 3 日

CPOL
viewsIcon

56138

downloadIcon

126

快速生成重复的 C++、C# 或 Java 代码,从 Python 可以读取的任何数据中生成。

引言

你对学习曲线过敏,并且想立即生成代码!这里有一个易于定制的 100 行 Python 模块,仅比 f.writeline 高一个等级。

使用代码

让我们从一个非常简单的例子开始(不要指出 main 返回 int,好吗!这只是一个例子)。

from CodeGen import *
 
cpp = CppFile("test.cpp")
 
cpp("#include <iostream>")
 
with cpp.block("void main()"):
    for i in range(5):
        cpp('std::cout << "' + str(i) + '" << std::endl;')
    
cpp.close()

输出

#include <iostream>
void main()
{
    std::cout << "0" << std::endl;
    std::cout << "1" << std::endl;
    std::cout << "2" << std::endl;
    std::cout << "3" << std::endl;
    std::cout << "4" << std::endl;
}

利用 Python 的 with 关键字,我们可以将语句封装在 {} 块中,这些块会自动关闭,并具有正确的缩进,以便输出保持可读。

替换

在生成更复杂的代码时,你很快就会意识到你的 Python 脚本变得越来越难以阅读,到处都是丑陋的字符串连接。 这时 subs 方法就派上用场了

from CodeGen import *
 
cpp = CppFile("test.cpp")
 
cpp("#include <iostream>")
 
with cpp.block("void main()"):
    for i in range(5):
        with cpp.subs(i=str(i), xi="x"+str(i+1)):
            cpp('int $xi$ = $i$;')
    
cpp.close()

这会在客户端生成

#include <iostream>

void main()
{
    int x1 = 0;
    int x2 = 1;
    int x3 = 2;
    int x4 = 3;
    int x5 = 4;
}

这些替换在 Python with 块内有效,并且可以嵌套。

差不多就是这样了

为了完成,这里有一个更复杂的例子,用于生成以下代码

class ClassX
{
protected:
    A a;
    B b;
    C c;
public:
    ClassX(A a, B b, C c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
    }
    A getA()
    {
        return this->a;
    }
    B getB()
    {
        return this->b;
    }
    C getC()
    {
        return this->c;
    }
};
class ClassY
{
protected:
    P p;
    Q q;
public:
    ClassY(P p, Q q)
    {
        this->p = p;
        this->q = q;
    }
    P getP()
    {
        return this->p;
    }
    Q getQ()
    {
        return this->q;
    }
};

请查看 CodeGen.py,了解 label 函数的实现方式,以了解如何通过语言特定功能扩展代码。

from CodeGen import *
 
cpp = CppFile("test.cpp")
 
CLASS_NAMES = ["ClassX", "ClassY"]
VAR_NAMES = { "ClassX": ["A", "B", "C"], 
                      "ClassY": ["P","Q"] }
 
for className in CLASS_NAMES:
    with cpp.subs(ClassName=className):
        with cpp.block("class $ClassName$", ";"):
            cpp.label("protected")
            for varName in VAR_NAMES[className]:
                with cpp.subs(A=varName, a=varName.lower()):
                    cpp("$A$ $a$;")
            cpp.label("public")
            with cpp.subs(**{"A a": ", ".join([x + " " + x.lower() for x in VAR_NAMES[className]])}):
                with cpp.block("$ClassName$($A a$)"):
                    for varName in VAR_NAMES[className]:
                        with cpp.subs(a=varName.lower()):
                            cpp("this->$a$ = $a$;")
            for varName in VAR_NAMES[className]:
                with cpp.subs(A=varName, a=varName.lower(), getA="get"+varName):
                    with cpp.block("$A$ $getA$()"):
                        cpp("return this->$a$;")
    
cpp.close()
© . All rights reserved.