编程实战:类C语法的编译型脚本解释器(十)编译表达式

 系列入口:编程实战:类C语法的编译型脚本解释器(九)编译语句

         本文介绍表达式的编译。

一、代码概览

         表达式的编译就是不断获取下一个标识符,直到遇到不属于表达式的东西。

        完整代码如下:

		Expression* GetExpression(CTokens& tokens, T_VARIABLE_S& vars, Expression* pExpression, size_t& pos, char const* endch, bool half = false)
		{
			size_t start_pos = pos;
			size_t op_pos = 0;
			Token* pToken;
			Expression* pOperand = NULL;//下一个操作数
			Token* pOperator = NULL;//指向下一个操作符

			while (true)
			{
				if (NULL == pOperand && NULL == pOperator)
				{
					tokens.MoveCurrentToken(pToken, pos);
					if (tokens.IsPosNotToken(pos))
					{
						return pExpression;
					}

					if (isExpressionEnd(tokens, pos, endch))
					{//空语句
						if (NULL == pExpression)
						{
							pExpression = NewExpression();
							pExpression->source_start = tokens.TokenStart(pos);
							pExpression->source_end = tokens.TokenStart(pos);
							if (NULL == pExpression)throw "内存不足";
						}
						return pExpression;
					}
					//取下一个操作数,可能没有(当下一个标记是操作符)
					if (NULL != pOperator)cout << pOperator->text << endl;
					GetOperand(tokens, vars, pOperand, pos);
					//取下一个操作符
					if (GetOperator(tokens, pOperator, pos))op_pos = pos - 1;
				}

				if (NULL == pOperand && NULL == pOperator)
				{//什么都没取到,结束
					return pExpression;
				}

				if (NULL == pExpression)
				{//新建表达式
					if (NULL == pOperator || isExpressionEnd(tokens, pos - 1, endch))
					{
						if (isExpressionEnd(tokens, pos - 1, endch))--pos;
						else
						{
							string str;
							if (!isExpressionEnd(tokens, pos, endch))
							{
								cout << tokens.m_tokens[pos - 1].text << " " << endch << endl;
								cout << pOperand->ToString(m_source, vars) << endl;
								CException::Throw(__FILE__, __LINE__, m_source, tokens.TokenStart(pos), "期待操作符");
							}
						}
						pExpression = pOperand;
						return pExpression;
					}
					else
					{
						pExpression = NewExpression();
						if (NULL == pExpression)throw "内存不足";
						pExpression->source_start = tokens.TokenStart(start_pos);
						pExpression->source_end = tokens.TokenStart(op_pos);
						pExpression->type = Expression::OPERATION;
						pExpression->op = pOperator->text;
						if (NULL != pOperand)pExpression->AddLeftOperand(*pOperand);
					}
					pOperand = NULL;
					pOperator = NULL;
				}
				else
				{//追加表达式
					if (NULL == pOperator || isExpressionEnd(tokens, pos - 1, endch))
					{//操作符为空
						if (isExpressionEnd(tokens, pos - 1, endch))--pos;
						pExpression->AddRightOperand(*pOperand);
						pExpression->source_end = tokens.TokenStart(pos);
						pOperand = NULL;
						return pExpression;
					}
					else
					{
						long level1, level2;
						if (NULL == pExpression->pLeftOperand())level1 = 2;//单目算符
						else if (!tokens.GetOperatorLevel(pExpression->op.c_str(), level1))Throw(__FILE__, __LINE__, pExpression->op + " 操作符优先级未知或此处不应该出现此操作符");
						if (NULL == pOperand)level2 = 2;//单目算符
						else if (!tokens.GetOperatorLevel(pOperator->text.c_str(), level2))Throw(__FILE__, __LINE__, pOperator->text + " 操作符优先级未知或此处不应该出现此操作符");
						if (level1 < level2 || level1 == level2 && tokens.IsOperatorLeftFirst(level1))
						{
							pExpression->AddRightOperand(*pOperand);
							pExpression->source_end = tokens.TokenStart(pos - 1);
							if (half)
							{
								--pos;//退回最后一个操作符
								return pExpression;
							}
							Expression* tmp = NewExpression();
							if (NULL == tmp)throw "内存不足";
							tmp->type = Expression::OPERATION;
							tmp->source_start = pExpression->source_start;
							tmp->source_end = op_pos;
							tmp->op = pOperator->text;
							tmp->AddLeftOperand(*pExpression);
							pExpression = tmp;
							pOperand = NULL;
							pOperator = NULL;
						}
						else
						{
							Expression* tmp = NewExpression();
							if (NULL == tmp)throw "内存不足";
							tmp->type = Expression::OPERATION;
							if (NULL == pOperand)tmp->source_start = tokens.TokenStart(op_pos);
							else tmp->source_start = pOperand->source_start;
							tmp->source_end = tokens.TokenStart(op_pos);
							tmp->op = pOperator->text;
							tmp->AddLeftOperand(*pOperand);
							pOperand = NULL;
							pOperator = NULL;

							pOperand = GetExpression(tokens, vars, tmp, pos, endch, true);
							if (GetOperator(tokens, pOperator, pos))op_pos = pos - 1;
						}
					}
				}
			}
			//return pExpression;
		}

        参数char const* endch指出期待什么样的结尾,分为“}”和“)”两种情况。

(我还没写完)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java+Swing: (jframe自定义图标和居中显示) 整理1

package com.test;import javax.swing.*; import java.awt.*; import java.net.URL;/*** Author&#xff1a;xiexu* Date&#xff1a;2023/12/3 19:13*/ public class JframeTest {JFrame jFrame;JButton jButton;public JframeTest() {// 容器组件&#xff08;jframe, jpanel,…

深圳冬季穿搭造型

深圳冬季穿搭造型 今天是2023年11月17日&#xff0c;北方在11月初就降下了大雪&#xff0c;那是我的老家&#xff0c;无比怀念。 而在深圳&#xff0c;冬天是体会不到那份冷冽的寒冷的&#xff0c;所以在深圳&#xff0c;每天的晚上&#xff0c;我都会出去散步&#xff0c;昨…

Kubernetes Service控制器详解以及切换为ipvs代理模式

文章目录 一、Service 存在的意义二、Pod与Service的关系三、Service定义与创建四、Service三种常用类型五、Service代理模式六、切换Service代理模式七、service总体工作流程八、kube-proxy ipvs和iptables的异同九、Service DNS名称 一、Service 存在的意义 service的引入主…

推荐10款App安全测试工具

移动互联网时代&#xff0c;我们的生活和工作深受 App 影响。伴随移动 App 的广泛应用&#xff0c;App 安全日益重要。本文介绍了 App 开发可能用到的安全测试工具。 当今&#xff0c; 全球移动用户大约超过37亿。 Google Play 上大约有 220 万个 App&#xff0c; 苹果App Sto…

二极管是什么

二极管 电子元器件百科 文章目录 二极管前言一、二极管是什么二、二极管的类别三、二极管的应用实例四、二极管的作用原理总结前言 二极管是一种重要的电子器件,通过其整流行为和管理方向的特性,可以在电路中实现电流控制和电压整流等功能。 一、二极管是什么 二极管是一种…

idea__SpringBoot微服务03——yaml(新注解)(新的依赖)

yaml 一、数据格式二、注入配置文件&#xff08;yaml注入&#xff09;&#xff08;新注解ConfigurationProperties&#xff09;三、注入配置文件&#xff08;properties注入&#xff09;&#xff08;新注解PropertySource&#xff09;四、yaml配置文件占位符${}五 、yaml跟prop…

【虚拟机】Docker基础 【二】【数据卷和挂载本地目录】

2.2.数据卷 容器是隔离环境&#xff0c;容器内程序的文件、配置、运行时产生的容器都在容器内部&#xff0c;我们要读写容器内的文件非常不方便。大家思考几个问题&#xff1a; 如果要升级MySQL版本&#xff0c;需要销毁旧容器&#xff0c;那么数据岂不是跟着被销毁了&#x…

智能优化算法应用:基于蜜獾算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蜜獾算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蜜獾算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蜜獾算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

深入理解 new 操作符:创建对象的秘密武器(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

SQL Server 数据库,创建触发器避免数据被更改

5.4触发器 触发器是一种特殊类型的存储过程&#xff0c;当表中的数据发生更新时将自动调用&#xff0c;以响应INSERT、 UPDATE 或DELETE 语句。 5.4.1什么是触发器 1.触发器的概念 触发器是在对表进行插入、更新或删除操作时自动执行的存储过程&#xff0c;触发器通常用于强…

Elastcsearch:通过 Serverless 提供更多服务

作者&#xff1a;Ken Exner 人们使用 Elasticsearch 解决最大数据挑战的方式一直令我们感到惊讶。 从超过 40 亿次下载、70,000 次提交、1,800 名贡献者以及我们全球社区的反馈中可以清楚地看出这一点。 Elastic 在广泛的用例中发挥的作用促使我们简化复杂性&#xff0c;让搜索…

9.基于SpringBoot3+I18N实现国际化

1. 新建资源文件 在resources目录下新建目录i18n, 然后 新建messages_en.properties文件 user.login.erroraccount or password error&#xff01;新建messages_zh_CN.properties文件 user.login.error帐户或密码错误&#xff01;2. 新建LocaleConfig.java文件 Configurati…

gpt3、gpt2与gpt1区别

参考&#xff1a;深度学习&#xff1a;GPT1、GPT2、GPT-3_HanZee的博客-CSDN博客 Zero-shot Learning / One-shot Learning-CSDN博客 Zero-shot&#xff08;零次学习&#xff09;简介-CSDN博客 GPT-2 模型由多层单向transformer的解码器部分构成&#xff0c;本质上是自回归模型…

Hazelcast分布式内存网格(IMDG)基本使用,使用Hazelcast做分布式内存缓存

文章目录 一、Hazelcast简介1、Hazelcast概述2、Hazelcast之IMDG3、数据分区 二、Hazelcast配置1、maven坐标2、集群搭建&#xff08;1&#xff09;组播自动搭建 3、客户端4、集群分组5、其他配置 三、Hazelcast分布式数据结构1、IMap2、IQueue&#xff1a;队列3、MultiMap4、I…

MySQL和MongoDB简介以及它们之间的区别

本文主要介绍MySQL和MongoDB的简介以及它们之间的区别。 目录 MySQL简介MySQL的优缺点MySQL的应用场景MongoDB简介MongoDB的优缺点MongoDB的应用场景MySQL和MongoDB的区别 MySQL简介 MySQL是一种开源的关系型数据库管理系统&#xff0c;是世界上最流行的数据库之一。它支持多用…

基于Java SSM框架实现弹幕视频网站系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现弹幕视频网站系统演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;弹幕视频网站当然也不能排除在外。弹幕视频网站是以实际运用为开发背景&…

语义分割网络FCN

语义分割是一种像素级的分类&#xff0c;输出是与输入图像大小相同的分割图&#xff0c;输出图像的每个像素对应输入图像每个像素的类别&#xff0c;每一个像素点的灰度值都是代表当前像素点属于该类的概率。 语义分割任务需要解决的是如何把定位和分类这两个问题一起解决&…

强敌环伺:金融业信息安全威胁分析——钓鱼和恶意软件

门口的敌人&#xff1a;分析对金融服务的攻击 Akamai会定期针对不同行业发布互联网状态报告&#xff08;SOTI&#xff09;&#xff0c;介绍相关领域最新的安全趋势和见解。最新的第8卷第3期报告主要以金融服务业为主&#xff0c;分析了该行业所面临的威胁和Akamai的见解。我们发…

SLAM算法与工程实践——SLAM基本库的安装与使用(1):Eigen库

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址&#xff1a; SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…

外包干了一个月,技术明显进步。。。。。

先说一下自己的情况&#xff0c;本科生生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了3年的功能测试…