1.script先由ResourceGroupMgr在prepare函数里根据不同的后缀名选择不同的ScriptLoader的派生类来加载,这里我们就以ScriptCompilerMgr为例。(今天开始细看材质加载部分的代码才发现ogre的材质解析原来还有两套,以前的一套是MaterialSerializer,1.6之后默认使用的是ScriptCompilerMgr.)
2.调用ScriptCompilerMgr内部ScriptCompiler对象的compile函数,这里其实也没有进行实际分析,只是创建并调用了分析和编译的对象:ScriptLexer,ScriptParser,ScriptCompiler。
3.先由ScriptLexer对文本进行分析,创建一个包含了所有token信息节点的列表,注意这一步仅仅是将所有材质里的词汇单元提取出来而已,还没有生成CST,乃至AST(当然这里的CST和AST都是简化的),这里的实现比较易读在ScriptLexer::tokenize中对文本的每个字符进行遍历,查找token(在ogre里也就是譬如{ } // \ : newline等,当然普通的字符肯定也算的),最后生成一个tokenlist。
4. 接下来将tokenList传入ScriptParser的parse函数中,这些token节点将被根据标记符的关系,而生成一个简单有父子关系的分析树,也就是CST了。到这里你就发现之前动辄就100个的nodelist已经变成了ConcreteNodeList,当然这里的node每个都是一个树了.以最外面的{}为根.当然没有{}的部分就变成一个节点(知道找到{或者别的标记符)
5.接着,在ScriptCompiler里将之前生成的CST转化为AST(这里的具体转化的代码我还没细看。。)
6.呼,终于要到最后了,根据每个AST的类型调用不同的ScriptTranslator,例如材质的话就取得MaterialTranslator来解释成最终的material,然后对其中的每个AST子节点再调用对应的ScriptTranslator,(例如pass就调用PassTranslator等)把所有的值都设置好,这样所有解释的工作终于完成了。
呼,的确是个很漫长的过程。。个人感觉如果把scriptLexer换成已有的什么文本解释库读取的速度会不会得到很多提升呢?譬如如今比较流行的rapidXml什么的,毕竟个人觉得这些专门优化文本库的性能还是很高的(虽然我得说尖括号啥的的确不是那么易读~)。当然我觉得ogre这么写的架势很可能有想将原来普通的脚本配置文件提升成ogre专用的脚本语言的趋势?(最早只是写了一堆Serializer而已)