编程实战:类C语法的编译型脚本解释器(八)编译概览

 系列入口:编程实战:类C语法的编译型脚本解释器(系列)-CSDN博客

         前面已经介绍了Token、变量、变量表、表达式和语句,现在进入深水区,介绍编译过程,相当于解释型脚本的解释过程。

        编译的好处是提前发现语法错误,然后可以重复执行几千万次,解释型对此无能为力。

目录

一、代码概览

二、成员变量

三、编译的主逻辑


一、代码概览

        前面介绍的那些代码都是类,可以分开也可以放在一起,我的代表整个脚本的类是这样的:

         这两张截图就是脚本类CScript的全貌,前面介绍的变量表、Token集合、表达式和语句都是这个类的子类(这是无关紧要的,整个代码放在一个名字空间中,也不会在里面掺入别的模块,所以子类还是独立类没有关系)。

        public部分很简单,只有编译和执行的入口。private部分则是一系列互相递归的函数。

二、成员变量

        代码:

	public:string m_source;Variable::types return_type;string script_name;//如果是子函数,这是函数名long count_global_variable;//如果是子函数,这是全局变量个数(只能使用之前定义的全局变量)private:bool m_compiled;bool m_isFunction;//是否是子函数long m_execcount;//执行次数string m_msg;T_VARIABLE_BLOCK m_EnvVariables;//环境变量表,对于子函数,是参数vector<Sentence > m_sentences;//语句组vector<CScript > m_functions;//子函数vector<Expression*> m_NewExpressions;//所有new出来的表达式,析构时要清理

         多解释一下:

类型名称用途
stringm_source脚本源码
Variable::typesreturn_type脚本或子函数的返回值
stringscript_name如果是子函数,这是函数名,否则无意义
longcount_global_variable如果是子函数,这是可用的全局变量的个数,不过由于编译时按顺序编译,运行时又没有动态删除变量的机制,所以其实并不需要这个
boolm_compiled脚本是否编译成功
boolm_isFunction表明本对象是否是子函数
longm_execcount运行计数,此值可以用做业务分析,常年不用的插件可以删掉
stringm_msg如果编译或运行出错,这里是出错信息
T_VARIABLE_BLOCKm_EnvVariables对于脚本,是外部变量(环境变量),对于子函数,是调用参数
vector<Sentence >m_sentences脚本或子函数的所有语句,概念上,脚本或函数就是一组语句
vector<CScript >m_functions脚本的所有子函数
vector<Expression*>m_NewExpressions内部机制,用于清理

        从这个表我们对整个语言的语法结构就比较清晰了:

  • 脚本就是入口参数+语句+返回值
  • 语句就是控制结构和表达式
  • 表达式就是加减乘除和函数调用,以及常量和变量
  • 函数调用就是函数名、参数和返回值
  • 参数就是表达式——又回到表达式
  • 函数就是脚本——又回到最初

        几条简单规则的无限递归——直到常量和变量。

三、编译的主逻辑

        编译入口:

		bool Compile(char const* _source, vector<pair<string, Variable > >* pEnvs = NULL){Init(_source);string str;CTokens tokens;T_VARIABLE_BLOCK currentGlobals;T_VARIABLE_BLOCK currentParams;T_VARIABLE_S curentVars;curentVars.T_VARIABLE_S_init(&m_EnvVariables, &currentGlobals, -1, &currentParams);//当前环境变量和全局变量在子函数中同样有效,必须独立存储try{if (!AddEnvVariableDelcare(pEnvs)){m_msg += "添加环境变量失败\r\n";return false;}if (!tokens.ToTokens(m_source)){m_msg += "编译失败\r\n";return false;}size_t pos = 0;if (!Build(tokens, curentVars, pos)){m_msg += "编译失败\r\n";return false;}}catch (string const& e){m_msg += e;Report(&tokens, curentVars, str);m_msg += str;return false;}catch (char const* s){m_msg += s;Report(&tokens, curentVars, str);m_msg += str;return false;}return true;}

        主要分为三步:

  1. 设置外部变量(环境变量)
  2. 解析Token
  3. 执行编译Build()

        从源码到Token这一步是独立完成的,后续所有操作都基于Token。

        Build()的代码:

		bool Build(CTokens& tokens, T_VARIABLE_S& vars, size_t& pos){bool isFunction = (0 != pos);while (pos < tokens.m_tokens.size()){if (isFunction){if (tokens.IsDelimiter(pos, "}")){break;}}m_sentences.resize(m_sentences.size() + 1);Token* pToken;if (!GetSentence(tokens, vars, m_sentences[m_sentences.size() - 1], pToken, pos))return false;if (!m_sentences[m_sentences.size() - 1].CheckSentence(m_source, vars, false))return false;}m_compiled = true;return true;}

        逻辑非常简单:

  • 如果是子函数而下一个Token是“}”,子函数结束
  • 获取一个语句并检查

        就这么简单。再往后才是真正的深水区。

(这里是结束,但不是整个系列的结束)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/201253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS鸿蒙操作系统架构

目录 1. 分布式架构&#xff1a; 2. 统一的开发平台&#xff1a; 3. 多内核共享&#xff1a; 4. 自适应界面&#xff1a; 5. AR、VR、MR支持&#xff1a; 6. 安全和隐私保护&#xff1a; 7. AI集成&#xff1a; 8. 应用生态系统&#xff1a; 9. 开源和开放&#xff1a…

振弦采集仪在土体与岩体监测中的可靠性与精度分析

振弦采集仪在土体与岩体监测中的可靠性与精度分析 振弦采集仪是一种用于土体和岩体监测的重要设备&#xff0c;它可以通过测量振动信号来获取土体或岩体的力学参数&#xff0c;如应力、应变、弹性模量等。而振弦采集仪的可靠性和精度是影响其应用效果的关键因素。 首先&#x…

鸿蒙4.0开发笔记之ArkTS语法基础之条件渲染和循环渲染的使用(十五)

文章目录 一、条件渲染&#xff08;if&#xff09;二、循环渲染&#xff08;ForEach&#xff09; 一、条件渲染&#xff08;if&#xff09; 1、定义 正如其他语言中的if…else…语句&#xff0c;ArkTS提供了渲染控制的能力&#xff0c;条件渲染可根据应用的不同状态&#xff0…

竞赛活动过程中评委亮灯是如何实现的

选秀节目中用到的那种评委爆灯效果要通过软件和硬件一起实现&#xff0c;软件实现在新一轮开始时&#xff0c;统一灭灯&#xff0c;评委通过按钮触发软件打开相应的灯&#xff0c;并自动发出声音。其实用到的物料包括&#xff1a;软件、按钮、灯、工业控制器。软件是核心&#…

virtualbox虚拟机安装ubuntu系统,启动黑屏

我在virtualbox虚拟机里面安装ubuntu系统&#xff0c;某次打开就卡在启动界面了。下面这样&#xff1a;&#xff08;这个截图信息是我在解决了问题之后重新进入ubnutu系统时截取的&#xff0c;不完整&#xff0c;但就是类似这样&#xff09; 报错信息&#xff1a; error: no s…

解决Kettle无法传输生偏字的问题

最近在搞数据传输&#xff0c;然后涉及到人名的时候&#xff0c;难免会碰到生僻字&#xff0c;utf8是无法存储的&#xff0c;然后我把目标表改为utf8mb4&#xff0c;但是还是无法传输生僻字&#xff0c;这就很奇怪了&#xff0c;明明两边的数据库都是MySQL 5.7x&#xff0c;但是…

【labview报错,缺少GOOP Development Suite】

操作 当labview报此错误时&#xff0c;第一类情况为缺少包&#xff0c;第二类为所使用的GPU包已失效 以下为第一类缺包的解决方式 登录VIPM&#xff0c;如何安装VIPM查看此贴&#xff1a;VIPM安装 打开VIPM后&#xff0c;右上角输入goop,双击搜索出的安装包 勾选需要安装的包…

Linux部署Kettle(pentaho-server-ce-9.4.0.0-343)记录/配置MySQL存储

下载地址 Kettle 是一个开源的数据集成工具&#xff0c;它是 Pentaho Data Integration&#xff08;PDI&#xff09;项目的一部分。要访问 Kettle 的官方网站&#xff0c;可以通过访问其母公司 Hitachi Vantara 的网站来找到相关信息 官方网站&#xff1a;https://www.hitachi…

浪潮信息KeyarchOS EDR 安全防护测评

背景 近几年服务器安全防护越来越受到企业的重视&#xff0c;企业在选购时不再仅仅看重成本&#xff0c;还更看重安全性&#xff0c;因为一旦数据泄露&#xff0c;被暴力破解&#xff0c;将对公司业务造成毁灭性打击。鉴于人们对服务器安全性的看重&#xff0c;本篇文章就来测…

【ArcGIS Pro】探索性插值无法覆盖所需shp范围

做个小记录自用&#xff0c;实际不准。 1 看看就行 pro插值 看看过程就行。有详细过程&#xff0c;类似tutorial https://learn.arcgis.com/zh-cn/projects/interpolate-temperatures-using-the-geostatistical-wizard/ 2 注意用投影坐标系 wgs84转投影坐标系 https://blog…

OSG编程指南<十八>:OSG读写保存文件及对中文字符的支持

基本几何体的绘制只适用于简单的编程&#xff0c;当场景中需要加载一个很复杂的模型时&#xff0c;还是需要从外部导入。osgDB 库 提供了读取二维图像和三维模型的接口&#xff0c;同时&#xff0c;也管理着第三方插件系统&#xff0c;以实现对不同格式文件的读取。 1、OSG 支…

在耳机心率血氧健康检测中应用的穿戴心率血氧接收芯片

时代快速发展的今天&#xff0c;随着生活节奏的加快&#xff0c;工作压力的加大&#xff0c;越来越多的消费者开始关注到自身身体健康&#xff0c;加班熬夜生活不规律&#xff0c;很容易让我们的身体处于亚健康的状态&#xff0c;而心率和体温的变化&#xff0c;就能反应我们身…

报表多源关联

报表多源关联 需求背景 在项目中会遇到多种数据展现在一起的报表。例如部分指标在关系型数据库中&#xff0c;部分指标通过restful接口获得到json&#xff0c;然后根据共同的维度关联一起&#xff0c;形成新的数据集。 解决方案 在硕迪报表中有两种方式实现该多源报表&…

生产环境_从数据到层级结构JSON:使用Spark构建多层次树形数据_父子关系生成

代码补充了&#xff01;兄弟萌 造的样例数据 val data Seq(("USA", "Male", "Asian", "Chinese"),("USA", "Female", "Asian", "Chinese"),("USA", "Male", "Bl…

SSL证书续签指南

SSL证书的有效期通常为一年&#xff0c;过期后将无法提供有效的加密保护&#xff0c;使网站容易受到黑客攻击和数据泄露的风险。所以SSL证书定期要进行续签&#xff0c;好确保网站的持久安全性。 首先我们要检查当前证书的有效期&#xff0c;打开网站&#xff0c;点击浏览器地址…

网络安全等级保护V2.0测评指标

网络安全等级保护&#xff08;等保V2.0&#xff09;测评指标&#xff1a; 1、物理和环境安全 2、网络和通信安全 3、设备和计算安全 4、应用和数据安全 5、安全策略和管理制度 6、安全管理机构和人员 7、安全建设管理 8、安全运维管理 软件全文档获取&#xff1a;点我获取 1、物…

TinyMPC - CMU (卡耐基梅隆大学)开源的机器人 MPC 控制器

系列文章目录 CasADi - 最优控制开源 Python/MATLAB 库 文章目录 系列文章目录前言一、机器人硬件对比1.1 Teensy 上的微控制器基准测试1.2 机器人硬件1.3 BibTeX 二、求解器三、功能&#xff08;预期&#xff09;3.1 高效3.2 鲁棒3.3 可嵌入式3.4 最小依赖性3.5 高效热启动3.…

手机怎么录屏?实用技巧,轻松录制!

手机录屏功能在现代通信和创作中扮演着重要的角色。无论是分享游戏过程、演示手机操作&#xff0c;还是创作教程视频&#xff0c;手机录屏成为了用户不可或缺的工具。本文将深入研究手机怎么录屏的三种方法&#xff0c;通过详细的步骤介绍&#xff0c;帮助用户轻松掌握手机录屏…

【无标题】从0到1 搭建一个vue3+Django项目

目录 一、后端项目python django二、前端项目vitevue3三、后端配置3.1 将路由指向app3.2 app下创建urls.py&#xff0c; 写入路由3.3 views写入test函数3.4 启动服务&#xff0c;访问路由 四、前端配置4.1 安装一些工具库及创建文件4.1.1 安装需要用的三方库4.1.2 创建文件 4.2…

Nacos 服务注册与发现

一、Spring Cloud Commons 二、使用方法 &#xff08;1&#xff09;在cloud-demo父工程中添加spring-cloud-alilbaba的管理依赖 &#xff08;2&#xff09;注释掉order-service和user-service中原有的eureka依赖 &#xff08;3&#xff09;添加nacos的客户端依赖 &#xff08;4…