还记得第一篇文章总结的解释器模型吧
现在还有FunctionList和脚本文件读取的功能没有实现,今天实现的就是FunctionList的功能
一样是功能分析:
FunctionList需要把函数名称和所在文件和行号对应存储起来
查询某个函数的时候只需要输入一个函数名称,就会返回函数所在的文件名称和行号信息(这里返回一个FunctionInfo类,其中包含了对应信息)
并没有设计一个删除函数,因为考虑到SymbolList和FunctionList是只在一个层中使用,退出层return的时候,会自动释放掉,也不必要在层运行的时候删除函数信息
创建一个FunctionList.h,输入:
#ifndef FUNCTIONLIST_H
#define FUNCTIONLIST_H
#include "../../public/ErrorDefine.h"
#include <string>
using namespace std;
class FunctionInfo{
public:
FunctionInfo(){Next=0;};
string FunctionName; //函数名
string FileName; //所在文件名称
int LineNumber; //函数开始行号
FunctionInfo *Next; //下一个节点指针,如果为NULL表示链表结束
int Copy(FunctionInfo& _FunctionInfo){
this->FunctionName=_FunctionInfo.FunctionName;
this->FileName=_FunctionInfo.FileName;
this->LineNumber=_FunctionInfo.LineNumber;
this->Next=0;
return 0;
}
private:
};
class FunctionList{ //函数表,使用链表的形式处理数据
public:
FunctionList(){FirstFunction=0;};
~FunctionList(); //用析构函数删除子链接
int AddFunction(FunctionInfo&); //添加函数信息到表
int AddFunction(string _FunctionName,string _FileName,int LineNumber);
int GetFunction(string _FunctionName,FunctionInfo& _FunctionInfo); //由函数名取得函数信息
//int DelFunction(string _FunctionName); //删除函数信息,因为删除函数是很少情况下发生的所以使用FunctionInfo单向链表
int ExistFunction(string _FunctionName); //校验函数是否存在,存在着返回0
FunctionInfo *FirstFunction; //指向函数表第一个元素
private:
};
#endif
同样的是用链表来实现,链表的元素是FunctionInfo,每个元素保存了一个函数的信息,用成员函数copy可以实现复制操作,当然也可以用操作符重载来实现
下边是cpp文件FunctionList.cpp的内容,原理和SymbolList几乎相同
#include "FunctionList.h"
FunctionList::~FunctionList(){
FunctionInfo *_FirstFunction;
while(0!=FirstFunction){
_FirstFunction=FirstFunction->Next;
try{
delete FirstFunction;
}
catch(int ErrorID){
throw ERROR_DELETE;
}
FirstFunction=_FirstFunction;
}
}
int FunctionList::AddFunction(FunctionInfo& _FunctionInfo){
if(_FunctionInfo.FunctionName=="" || _FunctionInfo.FileName==""){
return ERROR_NAMEINVALiD; //函数名无效
}
if(ExistFunction(_FunctionInfo.FunctionName)==0){ //如果函数已经存在
return ERROR_FUNCTIONEXIST;
}
FunctionInfo* _FirstFunction=FirstFunction;
try{
FirstFunction=new FunctionInfo;
}
catch(int ErrorID){
return ERROR_NEW; //内存分配失败
}
FirstFunction->Copy(_FunctionInfo); //复制函数信息
FirstFunction->Next=_FirstFunction; //拷贝指针
return 0;
}
int FunctionList::AddFunction(string _FunctionName,string _FileName,int _LineNumber){
FunctionInfo _FunctionInfo;
_FunctionInfo.FunctionName=_FunctionName;
_FunctionInfo.FileName=_FileName;
_FunctionInfo.LineNumber=_LineNumber;
_FunctionInfo.Next=0;
return AddFunction(_FunctionInfo);
}
int FunctionList::GetFunction(string _FunctionName,FunctionInfo& _FunctionInfo){
FunctionInfo* _FunctionPointer=FirstFunction;
while(0!=_FunctionPointer){
if(_FunctionPointer->FunctionName==_FunctionName){
_FunctionInfo.Copy(*_FunctionPointer);
return 0; //获取成功
}
_FunctionPointer=_FunctionPointer->Next;
}
return ERROR_FUNCTIONNOTEXIST; //未能找到元素
}
int FunctionList::ExistFunction(string _FunctionName){ //校验函数是否存在,存在就返回0值
FunctionInfo _FunctionInfo;
return GetFunction(_FunctionName,_FunctionInfo);
}
可以简单的用main来测试能否正常的添加和取得函数信息
现在四个主要部分中三个部分就大功告成了,至少勉强可以使用,接下来第四个是文件流表,下一篇文章分析它的作用和实现