实现一个数字电路的脚本解释器(三)——SymbolList的实现

今天实现的是符号表,符号表用于把脚本中的符号和值对应起来,在脚本运行过程中,解释器会对符号表进行添加,查询和修改

在数字电路中,我们暂时认为一个变量就是一根线或者是它上边的节点,这个变量的值就代表了电平,可以简单的定义为三种情况:H,L,和未定义也就是高阻

为了方便查询,我们设定一个查询接口,只要输入一个变量名称就会得到对应的值,至于怎么得到的,对于外部是不可见的

设计一个修改接口,当输入变量名和数值时,就会修改或者创建对应的变量符号


类的设计如下:

//src/SyntacticAnalyzer/SymbolList.h

#ifndef SYMBOLLIST_H
#define SYMBOLLIST_H

#include "../../public/ErrorDefine.h"
#include <string>
using namespace std;

class SymbolInfo{
	public:
		SymbolInfo(){Next=NULL;};
		string		SymbolName;		//符号名称
		int			Value;			//符号值
		SymbolInfo	*Next;			//下一个节点指针,如果为NULL表示链表结束
	private:
};

class SymbolList{						//符号表,使用链表形式处理数据
	public:
		SymbolList(){FirstSymbol=NULL;};//初始化
		~SymbolList();					//用析构函数删除子链
		int AddSymbol(string _SymbolName,int _Value=0x2);	//添加符号
		int UpdSymbol(string _SymbolName,int _Value);		//修改数据
		int GetSymbol(string _SymbolName,int& _Value);		//取得符号对应的数值
	private:
		SymbolInfo	*FirstSymbol;		//指向符号表第一个元素
};

#endif

来分析一下这个实现过程:

符号表同样是通过链表来实现,链表元素是SymbolInfo,SymbolList存储了链表元素的开头指针,SymbolList的析构函数负责释放链表空间

AddSymbol函数有个默认的0x2这个是未定义的默认值,表示为不确定值,也就是高阻态

所有的函数返回值都是错误值,取得的变量值需要用_Value来接收


//src/SyntacticAnalyzer/SymbolList.cpp

#include "SymbolList.h"
SymbolList::~SymbolList(){		//使用析构函数释放空间
	SymbolInfo *_FirstSymbol;
	while(0!=FirstSymbol){
		_FirstSymbol=FirstSymbol->Next;
		try{
			delete FirstSymbol;
		}
		catch(int ErrorID){
			throw ERROR_DELETE;
		}
		FirstSymbol=_FirstSymbol;
	}
}
int SymbolList::AddSymbol(string _SymbolName,int _Value){	//_Value有默认值3,表示未定义
	SymbolInfo *_FirstSymbol;
	_FirstSymbol=FirstSymbol;
	int _Value_tmp;
	if(GetSymbol(_SymbolName,_Value_tmp)==0){	//返回不等于3则表示存在元素
		return ERROR_SYMBOLEXIST;
	}
	try{
		FirstSymbol=new SymbolInfo;
	}
	catch(int ErrorID){
		return ERROR_NEW;
	}
	FirstSymbol->Next =_FirstSymbol;
	FirstSymbol->SymbolName=_SymbolName;
	if(_Value<0 || _Value>2){
		_Value=2;		//如果赋予的值无效,就将值写成未定义
	}
	FirstSymbol->Value=_Value;
	return 0;
}
int SymbolList::GetSymbol(string _SymbolName,int& _Value){		//返回符号对应的数值
	SymbolInfo	*_SymbolPointer;
	_SymbolPointer=FirstSymbol;
	while(_SymbolPointer!=0){
		if(_SymbolPointer->SymbolName==_SymbolName){
			_Value=_SymbolPointer->Value;
			return 0;
		}
		_SymbolPointer=_SymbolPointer->Next;
	}
	return ERROR_SYMBOLNOTEXIST;
}
int SymbolList::UpdSymbol(string _SymbolName,int _Value){
	int _Return=0;
	int _Valuex=0;
	if(ERROR_SYMBOLNOTEXIST==GetSymbol(_SymbolName,_Valuex)){	//如果不存在符号就添加一个
		if(_Return=AddSymbol(_SymbolName,_Value)){
			return _Return;
		}
		return 0;
	}
	SymbolInfo	*_SymbolPointer;
	_SymbolPointer=FirstSymbol;
	while(_SymbolPointer!=0){
		if(_SymbolPointer->SymbolName==_SymbolName){
			_SymbolPointer->Value=_Value;
			return 0;
		}
		_SymbolPointer=_SymbolPointer->Next;
	}
	return ERROR_NOTDEFINE;	//这里实际上是多余的返回
}


实现的方法就是从开头开始依次进行查询函数名,若函数名相同就进行对应的操作

需要注意的是,调用UpdSymbol时,如果符号不存在,就会自己创建一个

这个表的实现和数据栈实现很相似,只是接口和功能不同

对应的错误编号在(零)中说明了


接下来是对代码进行测试:

//main.cpp

#include <iostream>
#include <string>
using namespace std;

int main(){  
	SymbolList _Symbol_List;	//创建一个对象
	_Symbol_List.UpdSymbol("Var1",1);
	_Symbol_List.AddSymbol("Var2",2);
	int _Value=0;
	_Symbol_List.GetSymbol("Var1",_Value);
	cout << "Var1=" << _Value;
	_Symbol_List.GetSymbol("Var2",_Value);
	cout << "Var2=" << _Value;
	return 0;
}


 可以看到打印出了对应的值,初步认为通过测试了。 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值