下面来详细地分析语法分析相关的类,以便了解整个语法分析的过程和细节,这样也方便地复用第二人生里的脚本编译器,达到源码复用的目标。先来分析类LLScriptFilePosition,它的声明代码如下:

#001  class LLScriptFilePosition

#002  {

#003  public:

构造函数,保存脚本所在的行号和列号。

#004     LLScriptFilePosition(S32 line, S32 col)

#005         : mLineNumber(line), mColumnNumber(col), mByteOffset(0), mByteSize(0)

#006     {

#007     }

#008

析构函数。

#009     virtual ~LLScriptFilePosition() {}

#010

下面函数接口实现递归处理。

#011     virtual void recurse(FILE *fp, S32 tabs, S32 tabsize,

#012                         LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg,

#013                         LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count,

#014                         LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize,

#015  LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata) = 0;

获取代码的大小。

#016     virtual S32 getSize() = 0;

#017

输出对齐字符。

#018     void fdotabs(FILE *fp, S32 tabs, S32 tabsize);

#019

保存当前的行号。

#020     S32 mLineNumber;

保存当前的列号。

#021     S32 mColumnNumber;

#022

字节偏移位置。

#023     S32 mByteOffset;

字节的大小。

#024     S32 mByteSize;

#025  };

通过上面这个类来实现代码行号和列号的保存,并且可以递归调用生成代码。这个类是基类,后面会有很多类都继承它,用它来保存单词是出现在那里的,下面就来看看单词出现的类型,它的声明如下:

#001  class LLScriptType : public LLScriptFilePosition

从这里可以看到它是继承上面介绍的类LLScriptFilePosition。

#002  {

#003  public:

构造函数,可以初始化保存行号,列号和单词的类型。

#004     LLScriptType(S32 line, S32 col, LSCRIPTType type)

#005         : LLScriptFilePosition(line, col), mType(type)

#006     {

#007     }

#008

析构函数。

#009     ~LLScriptType() {}

#010

递归函数接口的实现。

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

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

获取大小的实现。

#013     S32 getSize();

#014

只存单词的类型。

#015     LSCRIPTType mType;

#016  };

#017

在第15行里定义一个类型LSCRIPTType,这是脚本文件里出现的类型,它的定义如下:

#001  typedef enum e_lscript_types

#002  {

空类型。

#003     LST_NULL,

整数类型。

#004     LST_INTEGER,

浮点数类型。

#005     LST_FLOATINGPOINT,

字符串类型。

#006     LST_STRING,

关键字类型。

#007     LST_KEY,

数组类型。

#008     LST_VECTOR,

四元数类型。

#009     LST_QUATERNION,

列表类型。

#010     LST_LIST,

未有定义类型。

#011     LST_UNDEFINED,

结束类型。

#012     LST_EOF

#013  } LSCRIPTType;

因此,上面的类里只能保存这几种类型,下面再来看类LLScriptType的实现代码:

#001  void LLScriptType::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     case LSCP_EMIT_ASSEMBLY:

根据类型mType从数组LSCRIPTTypeNames里获取相应的类字符串输出。

#012         fprintf(fp,"%s",LSCRIPTTypeNames[mType]);

#013         break;

获取类型。

#014     case LSCP_TYPE:

#015         type = mType;

#016         break;

输出CIL的汇编。

#017     case LSCP_EMIT_CIL_ASSEMBLY:

#018         print_cil_type(fp, mType);

#019         break;

#020     default:

#021         break;

#022     }

#023  }

#024

获取类型的大小,比如整数是4字节。

#025  S32 LLScriptType::getSize()

#026  {

#027     return LSCRIPTDataSize[mType];

#028  }

数组LSCRIPTDataSize具体值如下:

#001  const S32 LSCRIPTDataSize[LST_EOF] =

#002  {

#003     0,  // VOID

#004     4,  // integer

#005     4,  // float

#006     4,  // string

#007     4,  // key

#008     12, // vector

#009     16, // quaternion

#010     4,  // list

#011     0   // invalid

#012  };

#013

这个数组就是定义每一个类型占用内存的大小。到这里就把类型分析完成了,下一次再来分析其它的代码。

第二人生的源码分析(109)脚本的语法分析(3)相关推荐

  1. 第二人生的源码分析(102)脚本的构造

    前面我们学习怎么样打开窗口来创建脚本,接着下来就需要知道这些脚本是做什么用的,这样最终才会按它的语义来正确地执行起来. 现在我们能够查看脚本的内容: default { state_entry() { ...

  2. v58.03 鸿蒙内核源码分析(环境脚本) | 编译鸿蒙原来很简单 | 百篇博客分析HarmonyOS源码

    颜渊问仁.子曰:"克己复礼为仁.一日克己复礼,天下归仁焉.为仁由己,而由人乎哉?"颜渊曰:"请问其目."子曰:"非礼勿视,非礼勿听,非礼勿言,非礼勿动 ...

  3. Nmap源码分析(脚本引擎)

    Nmap提供了强大的脚本引擎(NSE),以支持通过Lua编程来扩展Nmap的功能.目前脚本库已经包含300多个常用的Lua脚本,辅助完成Nmap的主机发现.端口扫描.服务侦测.操作系统侦测四个基本功能 ...

  4. nginx源码分析configure脚本详解

    一.前言 在分析源码时,经常可以看到类似 #if (NGX_PCRE) .... #endif 这样的代码段,这样的设计可以在不改动源码的情况下,通过简单的定义宏的方式来实现功能的打开与关闭,但是在n ...

  5. nginx源码分析——configure脚本

    源码:nginx 1.13.0-release 一.前言 在分析源码时,经常可以看到类似 #if (NGX_PCRE) .... #endif 这样的代码段,这样的设计可以在不改动源码的情况下,通过简 ...

  6. 第二人生的源码分析(二十六)底层网络协议

    为了理解第二人生的客户端与服务器的沟通,那么下面就来分析一下第二人生采用的网络协议.在目前的网络里,主要有两个协议:TCP和UDP,而第二人生里是采用UDP协议.TCP协议与UDP协议的主要区别,就是 ...

  7. (转)Bootstrap 之 Metronic 模板的学习之路 - (4)源码分析之脚本部分

    https://segmentfault.com/a/1190000006709967 上篇我们将 body 标签主体部分进行了简单总览,下面看看最后的脚本部门. 页面结尾部分(Javascripts ...

  8. v50.03 鸿蒙内核源码分析(编译环境) | 编译鸿蒙防掉坑指南 | 百篇博客分析HarmonyOS源码

    颜渊死.子曰:"噫!天丧予!天丧予!" <论语>:先进篇 百篇博客系列篇.本篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙防掉坑指南 编译构建相关篇 ...

  9. v59.04 鸿蒙内核源码分析(构建工具) | 顺瓜摸藤调试构建过程 | 百篇博客分析HarmonyOS源码

    仲弓问仁.子曰:"出门如见大宾,使民如承大祭.己所不欲,勿施于人.在邦无怨,在家无怨."仲弓曰:"雍虽不敏,请事斯语矣." <论语>:颜渊篇 百篇博 ...

  10. v61.03 鸿蒙内核源码分析(忍者ninja) | 忍者的特点就是一个字 | 百篇博客分析OpenHarmony源码

    司马牛问君子.子曰:"君子不忧不惧."曰:"不忧不惧,斯谓之君子已乎?"子曰:"内省不疚,夫何忧何惧?" <论语>:颜渊篇 百篇 ...

最新文章

  1. pytorch多进程加载数据
  2. SAP外币评估 fagl_fc_val 多评估与少评估问题
  3. 类库,通用变量,is/as运算符,委托。
  4. putty连虚拟机中Linux出现Access Denied
  5. STM32F7xx —— 96位唯一ID
  6. 十二、Python第十二课——函数
  7. word之八大文本替换技巧
  8. Sleutel:密码治理器
  9. JavaWeb — session+Cookie
  10. 01数据结构——绪论
  11. (1)封装JSON数据的三种方式
  12. 软件开发的201个原则
  13. 如何判断绝缘接头质量的好坏?
  14. 为何现在手机都是type-c接口,这四个优点知道吗?看完你就知道了
  15. 初识C语言:了解基础指针
  16. 快来看看你的苹果手机还能卖多少钱?2022最新苹果手机回收报价单
  17. TSP的最佳解决方案
  18. 查询出学生表中年龄和分数相同的所有同学的名字
  19. 阮一峰 / ES6 数组的解构赋值
  20. 吴恩达深度学习视频笔记

热门文章

  1. mipi的dsi全称_mipi协议里面csi和dsi是什么意思
  2. 丹佛机场自动行包系统案例
  3. 乐虎 尖叫_如果您想更快地尖叫! 为什么政府技术需要(很多)更好的治理
  4. Arduino开发实例-433M无线模块数据发送与接收
  5. ERP Qt实现之路 前言
  6. 2019第九届蓝桥杯大赛个人赛决赛真题C语言B组——调手表
  7. 百度url提交入口 百度网站收录提交入口网址
  8. 中文名颜色大全,妈妈再也不担心我找不着好颜色了.
  9. linux内核热插拔,Linux热插拔机制的介绍和应用
  10. LED驱动程序的编写