您的位置:首页 > 其它

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

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

在数字电路中,我们暂时认为一个变量就是一根线或者是它上边的节点,这个变量的值就代表了电平,可以简单的定义为三种情况: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;
}


可以看到打印出了对应的值,初步认为通过测试了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐