当前位置: 首页 > article >正文

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

系列入口:

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

        本文介绍变量表的实现。

一、变量表的组织结构

        堆栈结构,进入一层新建一个层级,退出一层则丢弃整个层。

        查找时自顶向下逐级查找,直到最后的环境变量(执行脚本前预设的变量)。

二、代码

		//变量表
		struct T_VARIABLE_BLOCK : public vector<pair<string, Variable > >
		{
			bool AddVariable(string const& var_name, Variable const& var)
			{
				for (const_iterator it = begin(); it != end(); ++it)
				{
					if (it->first == var_name)
					{
						return false;
					}
				}

				push_back(pair<string, Variable >(var_name, var));
				return true;
			}
			Variable* FindVariable(string const& var_name)const
			{
				return FindVariable(var_name.c_str());
			}
			Variable* FindVariable(char const* var_name)const
			{
				for (const_reverse_iterator it = rbegin(); it != rend(); ++it)
				{
					if (it->first != var_name)
					{
						continue;
					}
					return (Variable*)&it->second;
				}
				return NULL;
			}
		};
		class T_VARIABLE_S
		{
		private:
			typedef vector<T_VARIABLE_BLOCK > T_DATA;

			T_VARIABLE_BLOCK* m_pEnvs;//指向环境变量
			T_VARIABLE_BLOCK* m_pGlobals;//指向全局变量
			long m_Globals_count;//全局变量个数
			T_VARIABLE_BLOCK* m_pParams;//指向参数
			T_DATA m_local_variables;//局部变量
		public:
			T_VARIABLE_S() :m_pEnvs(NULL), m_pGlobals(NULL), m_Globals_count(-1), m_pParams(NULL) {}
			long getGlobalCount()const { return m_pGlobals->size(); }
			void T_VARIABLE_S_init(T_VARIABLE_BLOCK* pEnv, T_VARIABLE_BLOCK* pG, long Globals_count, T_VARIABLE_BLOCK* pP)
			{
				m_pEnvs = pEnv;
				m_pGlobals = pG;
				m_Globals_count = Globals_count;
				m_pParams = pP;
				m_local_variables.clear();
			}
			void T_VARIABLE_S_init(T_VARIABLE_BLOCK const* pEnv, T_VARIABLE_BLOCK const* pG, long Globals_count, T_VARIABLE_BLOCK const* pP)
			{
				m_pEnvs = (T_VARIABLE_BLOCK*)pEnv;
				m_pGlobals = (T_VARIABLE_BLOCK*)pG;
				m_Globals_count = Globals_count;
				m_pParams = (T_VARIABLE_BLOCK*)pP;
				m_local_variables.clear();
			}
			void FromParentVars(T_VARIABLE_S& vars, long Globals_count, T_VARIABLE_BLOCK const* pP)
			{
				T_VARIABLE_S_init(vars.m_pEnvs, vars.m_pGlobals, Globals_count, pP);
			}
			void FromParentVars(T_VARIABLE_S const& vars, long Globals_count, T_VARIABLE_BLOCK const* pP)
			{
				T_VARIABLE_S_init(vars.m_pEnvs, vars.m_pGlobals, Globals_count, pP);
			}
			void PushLevel()
			{
				m_local_variables.resize(m_local_variables.size() + 1);
				//cout << "PushLevel " << m_datas.size() << endl;
			}
			void PopLevel()
			{
				if (m_local_variables.size() > 0)m_local_variables.resize(m_local_variables.size() - 1);
				//cout << "PopLevel " << m_datas.size() << endl;
			}
			bool AddVariable(string const& var_name, Variable const& var)
			{
				if (NULL != FindVariable(var_name))return false;
				if (0 == m_local_variables.size())
				{//全局变量
					m_pGlobals->push_back(pair<string, Variable >(var_name, var));
				}
				else
				{//局部变量
					m_local_variables.rbegin()->push_back(pair<string, Variable >(var_name, var));
				}
				return true;
			}
			Variable* FindVariable(string const& var_name)const
			{
				return FindVariable(var_name.c_str());
			}
			Variable* FindVariable(char const* var_name)const
			{
				long count;

				//从顶层向底层查找
				for (T_DATA::const_reverse_iterator it = m_local_variables.rbegin(); it != m_local_variables.rend(); ++it)
				{
					for (T_VARIABLE_BLOCK::const_iterator it_block = it->begin(); it_block != it->end(); ++it_block)
					{
						if (it_block->first != var_name)
						{
							continue;
						}
						return (Variable*)&it_block->second;
					}
				}

				//再找参数
				count = m_pParams->size();
				for (--count; count >= 0; --count)
				{
					if ((*m_pParams)[count].first != var_name)
					{
						continue;
					}
					return (Variable*) & (*m_pParams)[count].second;
				}

				//再找全局变量
				count = (m_Globals_count < 0 ? m_pGlobals->size() : m_Globals_count);
				if (m_Globals_count >= 0 && m_Globals_count > (long)m_pGlobals->size())
				{
					cout << "错误的有效全局变量个数 " << m_Globals_count << " 最大 " << m_pGlobals->size() << endl;
					return NULL;
				}
				for (--count; count >= 0; --count)
				{
					if ((*m_pGlobals)[count].first != var_name)
					{
						continue;
					}
					return (Variable*) & (*m_pGlobals)[count].second;
				}

				//最后找环境变量
				for (T_VARIABLE_BLOCK::const_reverse_iterator it = m_pEnvs->rbegin(); it != m_pEnvs->rend(); ++it)
				{
					if (it->first != var_name)
					{
						continue;
					}
					return (Variable*)&it->second;
				}

				return NULL;
			}
			string ToString(long level = 0)const
			{
				stringstream ret;
				ret << this << endl;
				long n = 0;
				ret << "环境变量:" << endl;
				for (T_VARIABLE_BLOCK::const_iterator it = m_pEnvs->begin(); it != m_pEnvs->end(); ++it)
				{
					ret << n << " : " << it->first << " : " << it->second.ToString() << endl;
					++n;
				}
				ret << "全局变量:有效数" << this->m_Globals_count << endl;
				for (T_VARIABLE_BLOCK::const_iterator it = m_pGlobals->begin(); it != m_pGlobals->end(); ++it)
				{
					ret << n << " : " << it->first << " : " << it->second.ToString() << endl;
					++n;
				}
				ret << "参数:" << endl;
				for (T_VARIABLE_BLOCK::const_iterator it = m_pParams->begin(); it != m_pParams->end(); ++it)
				{
					ret << n << " : " << it->first << " : " << it->second.ToString() << endl;
					++n;
				}
				ret << "局部变量:" << endl;
				for (T_DATA::const_iterator it = m_local_variables.begin(); it != m_local_variables.end(); ++it)
				{
					for (T_VARIABLE_BLOCK::const_iterator it_block = it->begin(); it_block != it->end(); ++it_block)
					{
						//if(it_block->second->isconst)continue;
						ret << n << " : " << it_block->first << " : " << it_block->second.ToString() << endl;
					}
					++n;
				}
				return ret.str();
			}
		};


http://www.kler.cn/a/154648.html

相关文章:

  • Windows下使用adb实现在模拟器中ping
  • Go八股(Ⅵ)Goroutine 以及其中的锁和思想
  • Mac终端字体高亮、提示插件
  • C++ | Leetcode C++题解之第560题和为K的子数组
  • Vue监视属性变化watch
  • WPF中如何使用区域导航
  • HarmonyOS——解决本地模拟器无法选择设备的问题
  • 编程实战:类C语法的编译型脚本解释器(三)
  • 2312skia,15vulkan及技巧
  • Go语言实现深度学习的正向传播和反向传播
  • 深入理解Servlet(上)
  • 深度学习记录--计算图(前向后向传播)
  • 最新AI智能写作回答系统源码 附完整的搭建教程
  • java学习part29线程通信
  • 锐捷EWEB网管系统 RCE漏洞复现
  • oracle sql相关语法
  • Docker的常用基本命令(基础命令)
  • 在Windows中如何知道当前cmd的python解释器来自哪个位置
  • 在 ArcGIS 软件中添加左斜宋体(东体)的方法与步骤
  • 管理类联考-性质
  • 无人机助力电力设备螺母缺销智能检测识别,python基于YOLOv7开发构建电力设备螺母缺销小目标检测识别系统
  • C++作业2
  • 编写高质量Python (第26条) 用 functools.wraps 定义函数装饰器
  • AIGC: 关于ChatGPT中token和tiktoken工具
  • uniapp 微信小程序连接蓝牙卡死
  • 前端打包添加前缀