分类: Python/Ruby
2012-05-15 09:05:15
一. target 目录是最顶层,通过/magpidl4.py -p platform(default:generic) -i interface
(v4nicta_n2) -g generator() TARGET_MAP 查表
获得['idl4/generic_l4v4'] target 目录下最终使用那个target, 比如-i v4, -p generic
=>idl4/generic_l4v4_target.py
TARGET_MAP 中某一项:
generator ,platform , interface, mapping : target
('idl4', 'generic', 'v4', 'c'): ['idl4/generic_l4v4'],
通过命令行参数或者default 参数,将使targets/shared/options.py 下所有option 都设置
完成以待后用:
点击(此处)折叠或打开
二. 开始targets/shared/target.py class Target的run method 开始运行
其中 Class Target init 时设置下面数据:
点击(此处)折叠或打开
inputparser_construct
=> inputparser.py 的 construct
target_data: 通过get_target_data('nicta/generic_n2')
去获得default interface => targets/nicta/generic_n2_target.py
或者 get_target_data('idl4/generic_l4v4') 去获得 -i v4 (interface=v4)
targets/nicta/generic_l4v4_target.py
然后执行这个xxxxx_xxxx_target.py 去获得target_opts =>
execfile('generic_n2_target.py',target_opts)
target_opts = {'Templates': None, 'Generator': None,'DataStorage':None}
对于执行generic_l4v4_target.py , target_opt 输出结果如下:
{'Templates':
'Generator':
'V4Generator':
'SharedTemplates':
......
在target_opt 中预设的 'Templates' 'Generator' 'DataStorage' 都从generic_l4v4_target.py
的执行中获得了对应key的内容,
其中 Templates =>class Templates(base.Templates, SharedTemplates, ClientTemplates, ServiceTemplates, ServiceTemplateTemplates):
Generator =>from generator.v4generator import V4Generator
class Generator(V4Generator):
到此target_data已经很清楚了,就是target_opt ,其中包括了字典名和对应class Templates Generator DataStorage !!!
三. inputparser.py => 上面target.py中 self.inputparser = inputparser_construct (from inputparser import construct as inputparser_construct )
该文件包含下面类层次:
GenericASTGenerator, ASTGeneratorCImportMixIn(importer = CASTImporter(import_filenam))
\ /
\ /
ImportingASTGenerator
GenericASTGenerator ===> idl ast 生成
ASTGeneratorCImportMixIn ===> c preprocess 和c ast 生成
四. target.py target 类实例化(__init__)的时候通过get_target_data中获得了target_data ,就是generic_l4v4_target.py (假定-i v4)
generic_l4v4_target.py 的类层次如下:
base.Templates, SharedTemplates, ClientTemplates, ServiceTemplates, ServiceTemplateTemplates
\ | | | /
\ | | | /
Templates
其中 base.Templates 中get 是用来获取 SharedTemplates, ClientTemplates, ServiceTemplates, ServiceTemplateTemplates 中各个模板名字对应的文件名!!!
(template_name = getattr(self, name, None) => 比如 client_function_body ==>
'v4_generic/client_function_body.template.c')
五. 回到 target.py => run
run 之前 target_data 导出 targets/nicta/generic_l4v4_target.py 相关
generator,datastorage,tmplate等等
然后 output(file ,or stdout),output_type(client_stub),generator(from
generator.v4generator import V4Generator)
inputparser(from inputparser import construct as inputparser_construct)
templates(target_data's templates)
1. check output_type,必须3选1,default is client stub
2. basicast = create_basictype_ast(self.hardware_arch, self.generator_type) =>
from magpietypes.builtin import create_basictype_ast
生成下面类型语法树: Node + Type (parser_common.py)
type short (1)
+- meta_type = ['basic']
info (2)
+- size = [16]
type long (1)
+- meta_type = ['basic']
info (2)
+- size = [32]
type long long (1)
+- meta_type = ['basic']
info (2)
+- size = [64]
type unsigned short (1)
+- meta_type = ['basic']
info (2)
+- size = [16]
type unsigned long (1)
+- meta_type = ['basic']
info (2)
+- size = [32]
type unsigned long long (1)
+- meta_type = ['basic']
info (2)
+- size = [64]
type float (1)
+- meta_type = ['basic']
info (2)
+- size = [32]
type double (1)
+- meta_type = ['basic']
info (2)
+- size = [64]
type long double (1)
+- meta_type = ['basic']
info (2)
+- size = [80]
type char (1)
+- meta_type = ['basic']
info (2)
+- size = [8]
type unsigned char (1)
+- meta_type = ['basic']
info (2)
+- size = [8]
type wchar_t (1)
+- meta_type = ['basic']
info (2)
+- size = [16]
type bool (1)
+- meta_type = ['basic']
info (2)
+- size = [1]
type octet (1)
+- meta_type = ['basic']
info (2)
+- size = [8]
type int (1)
+- meta_type = ['basic']
info (2)
+- size = [32]
type unsigned int (1)
+- meta_type = ['basic']
info (2)
+- size = [32]
type signed char (1)
+- meta_type = ['basic']
info (2)
+- size = [8]
type fpage (1)
+- meta_type = ['basic']
info (2)
+- size = [64]
type __int64 (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type signed __int64 (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type unsigned __int64 (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type long int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type unsigned long int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type long unsigned int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type long long int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type unsigned long long int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type unsigned (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type short int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type boolean (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type signed short int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type signed int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type unsigned short int (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type Object (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type any (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type ValueBase (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type wchar (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
type Word (1)
+- meta_type = ['alias']
info (2)
+- target_type = [
3. 继续target.py.run()
=> self.generate_asts(basicast)
=> self.inputparser.produce_ast(filename, 'CORBA', basicast)
=> ImportingASTGenerator.produce_ast ( self.inputparser = inputparser_construct()
inputparser.py的 def construct():return ImportingASTGenerator())
=> GenericASTGenerator.perform_imports(baseast, data) data is idl file name
预处理 + cparser
=> raw_ast = idlparser(idl_filename, data, baseast)
idlparse
=> add raw_ast to baseast's child ,and return raw_ast (see proc_ast.txt file)
到这里已经AST生成完毕
=> self.asts.append(ASTInfo(ast)) ,generator\generator.py 再封装到 ASTInfo类,
其中一些方法用来方便处理ast
=> self.generate_output
=> generator_inst = self.generator(self.output, ast)
因为self.generator = target_data['Generator'] => targets\idl4
\generic_l4v4_target.py 的 class Generator(V4Generator):
点击(此处)折叠或打开
target_data = self.get_target_data(options['target']) => self.get_target_data
("traget/idl4/generic_l4v4_target.py")
=> execfile(traget/idl4/generic_l4v4_target.py,target_data)
get generic_l4v4_target.py object !!!!!!
获得v4generator(parent is generator) 的实例, ArchitectureInfo 等wordsize ,align 等信息
=> self.generator_go(generator_inst)
=> 设置self.output.context 字典的一些内容(self.output = GenericOutput()
=>output/generic.py)
self.output.context['templates'] = self.templates => 取templates的类实例
self.output.context.file.version_string = helper.VERSION_STRING
self.output.context['generator'] = generator_inst => class generator 的类实例
self.output.context.file.output_filename = options['output_filename']
输出文件名
self.output.context.file.idl_filename = generator_inst.astinfo.get_filename()
idl4 文件名
base_template = self.templates.get(options['output_type'])
通过base.template的get 获得output_type(client or service)对应模板的
文件名路径
self.output.go(base_template) ,开始output (output\generic.py => class
GenericOutput(BaseOutput): => GenericOutput.go )
接下部分到七.继续
六. parser_common.py 的类层次:
Node
|
ASTPart
/\
IDL elment Node (Declarator ,Interface ,Function ...)
比如:
class Interface(ASTPart): ==> 在 idlparser\antlr\astgen.py 中def interf(self,ast, pt): 使用该类生成实例!!!
def __init__(self, parent, children = None, name = None):
ASTPart.__init__(self, parent, 'interface', children, name)
七. output\generic.py output
self.fromtemplate(template_filename) v4_generic/main_client.template.h
=> markup(template_fullname, self.output, self.context) ==> output\wsogmm.py (internal_run_fn 就是template 文件中的run !!!)
markup = safe_markup_fromfile (output/generic.py ===> 包含了 outputcontext !!!)
===> return Markup.go(template, output, environment)
===> inst._run_template(template) ( go = classmethod(go) ) output/wsogmm.py
===> self._compile(template)