第二人生的源码分析(110)脚本的语法分析(5)

系统 1849 0
 

在脚本里有很多语句组成的,那么对于语句又是怎么进行语法分析的呢?下面就来分析 for 语句的分析过程,它的声明代码如下:

#001   class LLScriptFor : public LLScriptStatement

#002   {

#003   public:

 

构造函数,输入保存的值。

#004      LLScriptFor(S32 line, S32 col, LLScriptExpression *sequence, LLScriptExpression *expression, LLScriptExpression *expressionlist, LLScriptStatement *statement)

#005          : LLScriptStatement(line, col, LSSMT_FOR), mSequence(sequence), mExpression(expression), mExpressionList(expressionlist), mStatement(statement),

#006   mType(LST_NULL)

#007      {

#008      }

#009  

 

析构造函数。

#010      ~LLScriptFor()

#011      {

#012      }

#013  

 

递归处理函数。

#014      void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type,

#015   LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);

 

获取语句生成代码的大小。

#016      S32 getSize();

#017  

 

初始化表达式。

#018      LLScriptExpression       *mSequence;

 

条件判断表达式。

#019      LLScriptExpression       *mExpression;

 

最后执行的表达式列表。

#020      LLScriptExpression       *mExpressionList;

 

循环体的语句块。

#021      LLScriptStatement        *mStatement;

 

脚本的类型。

#022      LSCRIPTType              mType;

#023   };

 

 

下面来分析它的递归调用函数的处理:

#001   void LLScriptFor::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type,

#002   LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)

#003   {

 

如果分析出错就返回。

#004      if (gErrorToText.getErrors())

#005      {

#006          return;

#007      }

 

下面根据不同的遍来处理。

#008      switch(pass)

#009      {

 

打印输出脚本的代码。

#010      case LSCP_PRETTY_PRINT:

#011          fdotabs(fp, tabs, tabsize);

#012          fprintf(fp, "for ( ");

#013          if(mSequence)

#014              mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#015   NULL);

#016          fprintf(fp, " ; ");

#017          mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#018          fprintf(fp, " ; ");

#019          if(mExpressionList)

#020              mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#021   entrycount, NULL);

#022          fprintf(fp, " )/n");

#023          if(mStatement)

#024              mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#025   NULL);

#026          break;

 

 

下面输出编译出来的汇编代码。

#027      case LSCP_EMIT_ASSEMBLY:

#028          {

#029              S32 tjump1 =   gTempJumpCount++;

#030              S32 tjump2 =   gTempJumpCount++;

#031              if(mSequence)

#032                  mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,

#033   entry, entrycount, NULL);

#034              fprintf(fp, "LABEL ##Temp Jump %d##/n", tjump1);

#035              mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#036   NULL);

#037              fprintf(fp, "JUMPNIF ##Temp Jump %d##/n", tjump2);

#038              if(mStatement)

#039                  mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,

#040   entry, entrycount, NULL);

#041              if(mExpressionList)

#042                  mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,

#043   entry, entrycount, NULL);

#044              fprintf(fp, "JUMP ##Temp Jump %d##/n", tjump1);

#045              fprintf(fp, "LABEL ##Temp Jump %d##/n", tjump2);

#046          }

#047          break;

 

下面优化代码,如果代码不用运行,就可以删除。

#048      case LSCP_PRUNE:

#049          if (ptype == LSPRUNE_DEAD_CODE)

#050              prunearg = TRUE;

#051          else

#052              prunearg = FALSE;

#053          break;

 

下面进行 for 语句的类型检查。

#054      case LSCP_TYPE:

#055          if(mSequence)

#056              mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#057   NULL);

#058          mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#059          mType = type;

#060          if(mExpressionList)

#061              mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#062   entrycount, NULL);

#063          if(mStatement)

#064              mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#065   NULL);

#066          break;

 

下面生成 for 语句的目标代码。

#067      case LSCP_EMIT_BYTE_CODE:

#068          {

#069              char jumpname1[32];         /*Flawfinder: ignore*/

#070              snprintf(jumpname1, sizeof(jumpname1), "##Temp Jump %d##", gTempJumpCount++);   /* Flawfinder: ignore */

#071              char jumpname2[32];             /*Flawfinder: ignore*/

#072              snprintf(jumpname2, sizeof(jumpname2), "##Temp Jump %d##", gTempJumpCount++);    /* Flawfinder: ignore */

#073  

#074              if(mSequence)

#075                  mSequence->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap,

#076   stacksize, entry, entrycount, NULL);

#077              chunk->addLabel(jumpname1);

#078              mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#079   entrycount, NULL);

#080              chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);

#081              chunk->addByte(LSCRIPTTypeByte[mType]);

#082              chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);

#083              chunk->addJump(jumpname2);

#084              if(mStatement)

#085                  mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,

#086   entry, entrycount, NULL);

#087              if(mExpressionList)

#088                  mExpressionList->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk,

#089   heap, stacksize, entry, entrycount, NULL);

#090              chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);

#091              chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);

#092              chunk->addJump(jumpname1);

#093              chunk->addLabel(jumpname2);

#094          }

#095          break;

 

下面生成 CIL 的汇编代码。

#096      case LSCP_EMIT_CIL_ASSEMBLY:

#097          {

#098              S32 tjump1 =   gTempJumpCount++;

#099              S32 tjump2 =   gTempJumpCount++;

#100              if(mSequence)

#101                  mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,

#102   entry, entrycount, NULL);

#103              fprintf(fp, "LabelTempJump%d:/n", tjump1);

#104              mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#105   NULL);

#106              fprintf(fp, "brfalse LabelTempJump%d/n", tjump2);

#107              if(mStatement)

#108                  mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,

#109   entry, entrycount, NULL);

#110              if(mExpressionList)

#111                  mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize,

#112   entry, entrycount, NULL);

#113              fprintf(fp, "br LabelTempJump%d/n", tjump1);

#114              fprintf(fp, "LabelTempJump%d:/n", tjump2);

#115          }

#116          break;

 

下面进行递归处理 for 里出现的表达式。

#117      default:

#118          if(mSequence)

#119              mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#120   NULL);

#121          mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#122          if(mExpressionList)

#123              mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry,

#124   entrycount, NULL);

#125          if(mStatement)

#126              mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount,

#127   NULL);

#128          break;

#129      }

#130      gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);

#131   }

 

在语法分析里,把所有合法的语句都生成一个合适的类对象,然后通过遍历所有类对象进行类型检查,或者生成代码。所有其它语句都是这样进行的,比如语句 if 就是使用类 LLScriptIf 来保存和分析的。当检查所有脚本都是合法的语法后,就生成了语法树,后面通过遍历语法树来生成代码。

 

 

 

第二人生开发包提供,价格 198 / 套(含邮费)。

包括内容如下:

1.     《第二人生的源码分析》 PDF 文档。

2.     第二人生客户端源程序。

3.     2G U 盘一个,主要用来拷贝源程序以及相关开发工具。

 

提供三个月的技术服务,

提供快速编译指导,比如通过 QQ 远程编译操作。

提供完整的书参考。

 

联系方式:

QQ:              9073204

MSN:             caimouse1976@sina.com

EMAIL:            ccaimouse@gmail.com

 

第二人生的源码分析(110)脚本的语法分析(5)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论