有人可以指导我如何使用Python(或Perl或其他Linux友好的脚本语言)编写脚本以从命令行生成C++代码或从XML或py文件生成代码吗?我想编写一些xml文件,然后运行一个shell命令来读取这些文件并生成带有完全内联函数的.h文件,例如流操作符、构造函数等等。
有人可以指导我如何使用Python(或Perl或其他Linux友好的脚本语言)编写脚本以从命令行生成C++代码或从XML或py文件生成代码吗?我想编写一些xml文件,然后运行一个shell命令来读取这些文件并生成带有完全内联函数的.h文件,例如流操作符、构造函数等等。
{className}::{className}()
{{
}}
{className}::~{className}()
{{
}}
{className}::{className}(const {className}& other)
{{
}}
{className}& {className}::operator=(const {className}& other)
{{
return *this;
}}
那么你的Python代码非常简单:
d = {}
d['className'] = 'MyCPlusPlusClassName'
with open(yourTemplateFile, 'r') as ftemp:
templateString = ftemp.read()
with open(generatedFile, 'w') as f:
f.write(templateString.format(**d))
当然,你可以使用相同的技巧添加许多其他字段作为“className”的附加项。如果你不需要像条件代码生成这样的东西,那么你可以通过使用这种简单方法实现很多功能。
看看猎豹。这是一个用Python编写的模板引擎。
printSelf()
方法,该方法迭代其内容并调用其包含的每个对象的printSelf()
。printSelf()
中添加缩进参数,并在每个级别上增加它。这使得生成的代码更容易阅读。根据我的经验,我可以推荐Jinja2(http://jinja.pocoo.org/docs/dev/)。尽管Jinja的主要目标语言是HTML,但它在C++方面也表现得非常出色。这不仅是我的观点,还有 https://www.chromium.org/developers/jinja :). 有一个独立的版本(https://github.com/filwaitman/jinja2-standalone-compiler),可能会很有用,因为Jinja2本身只是一个API。我正在使用独立版本来进行我的项目https://github.com/TomSmartBishop/avl,并进行了自定义环境设置,以使Jinja2的开放和关闭标签更符合C++风格。
import sys, string
import win32clipboard
import re
data = '''
enum FeedTypeT
{
AA,
BB,
DDD,
F
};
'''
def get_from_clippord():
# get clipboard data
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
return data
def enum_type(inenum):
inenum = inenum.replace('\r\n', '\n')
inenum = re.sub( r'\s', r'', inenum )
inenum = re.sub( r'^(.*)\{.*$', r'\1', inenum )
return inenum
def cleanup_enum(inenum):
inenum = inenum.replace('\r\n', '\n')
# inenum = inenum.replace('enum', '')
inenum = re.sub( r'\s', r'', inenum )
# inenum = re.sub( r'^.*\{(.+)[|,]\}.*$', r'\1', inenum )
inenum = re.sub( r'^.*\{(.+)\}.*$', r'\1', inenum )
inenum = inenum.split(',')
return inenum
def get_element(inlist):
for element in inlist:
[one, two] = element.split('=')
print('{0:20} ==> {1:>20}'.format(one, two)) # right align
# one = element.split('=')
# print('{0:20} ==> {1:10}'.format(one[0], one[1]))
def print_switch(typename):
retstr = 'const std::string toString( ' + typename + ' type )'
retstr += '\n{\n switch( type )\n {'
return retstr
def print_case_line(instr, w):
retstr = ' case ' + '{:{fw}}'.format(instr + ':', fw = w) + ' return "' + instr + '";'
return retstr
def print_switch_end(w):
retstr = ' default: ' + ' '*(w-4) + ' return "undef";\n }\n}\n'
return retstr
def main():
#data = get_from_clippord()
ll = cleanup_enum(data)
print ( ll )
print ("="*80 + "\n\n")
print ( print_switch( enum_type(data)) )
w = 25
# pick right with for formating, based on the lenght of elements of enum
for line in ll:
if w < len(line):
w = len(line) + 2
for line in ll:
print ( print_case_line(line, w) )
print ( print_switch_end(w) )
if __name__ == '__main__':
main()
输出:
['AA', 'BB', 'DDD', 'F']
================================================================================
const std::string toString( enumFeedTypeT type )
{
switch( type )
{
case AA: return "AA";
case BB: return "BB";
case DDD: return "DDD";
case F: return "F";
default: return "undef";
}
}
我实际上使用一种遗留的“4GL”开发环境进行一些工作,它们与此类似,并且旧的4GL范例中有很多模型将C和C++用作所输出生成代码的语言。
话虽如此,4GL几乎已经被放弃了。问题在于,当你机器生成C代码时,你会失去原本使用C所带来的性能提升,并且这些代码难以维护。最好一开始就用Python编写程序。