64,654
社区成员
发帖
与我相关
我的任务
分享
// lisp.h
#include <string>
#include <list>
typedef unsigned int uint;
// Lisp原子ADT
class LispAtom
{
public:
std::string m_Value;
};
class LispList;
// Lisp表达式ADT
class LispCode
{
public:
enum CodeType
{
ATOM, // 是一个原子
LIST, // 是一个表
UNDEFINE // 未定义
};
// 获取表达式类型
CodeType Type();
// 获取原子对象
LispAtom &Atom();
// 获取表对象
LispList *List();
// 设置为原子
void SetAtom();
// 设置为表
void SetList();
// 清除数据
void Clear();
public:
LispCode();
~LispCode();
private:
LispAtom m_Atom;
LispList *m_List;
CodeType m_Type;
std::list<LispList *> m_ClassPtrs;
};
// Lisp表ADT
class LispList
{
public:
// 加入表达式
bool Plus(LispCode &code);
// 移除表达式
bool Minus(uint index);
// 获取表达式
LispCode &Get(uint index);
// 表达式总数
uint Count();
// 清除所有数据
void Clear();
public:
LispList();
~LispList();
private:
std::list<LispCode> m_Codes;
};
#include "lisp.h"
bool LispList::Plus(LispCode &code)
{
m_Codes.push_back(code);
return true;
}
bool LispList::Minus(uint index)
{
if (index >= this->Count()) return false;
auto code_it = m_Codes.begin();
while (index > 0)
{
code_it++;
}
m_Codes.erase(code_it);
return true;
}
LispCode &LispList::Get(uint index)
{
assert(index < this->Count());
auto code_it = m_Codes.begin();
while (index > 0)
{
code_it++;
}
return (*code_it);
}
uint LispList::Count()
{
return m_Codes.size();
}
void LispList::Clear()
{
m_Codes.clear();
return;
}
LispList::LispList()
{
}
LispList::~LispList()
{
}
LispCode::CodeType LispCode::Type()
{
return m_Type;
}
LispAtom &LispCode::Atom()
{
assert(ATOM == this->Type());
return m_Atom;
}
LispList *LispCode::List()
{
assert(LIST == this->Type());
if (NULL == m_List) m_List = new LispList();
return m_List;
}
void LispCode::SetAtom()
{
this->Clear();
m_Type = ATOM;
return;
}
void LispCode::SetList()
{
this->Clear();
m_Type = LIST;
return;
}
void LispCode::Clear()
{
m_Type = UNDEFINE;
m_Atom.m_Value.clear();
m_List = NULL;
return;
}
LispCode::LispCode()
{
m_Type = UNDEFINE;
m_List = NULL;
}
LispCode::~LispCode()
{
this->Clear();
}
// LispToken.h
enum LispToken
{
LBRACK, // 左大括号
RBRACK, // 右大括号
ATOM // 原子
};
// lispscanner.h
class LispTokenNode
{
public:
LispToken m_Token;
// 仅原子有此值(ID名、字符串、数值、...)
std::string m_Value;
};
class LispScanner
{
public:
// 从字符串解析Lisp词法
bool Parse(const char *str);
// 获取单词节点链表
std::list<LispTokenNode> &NodeList();
// 清除所有节点数据
void Clear();
private:
std::list<LispTokenNode> m_Nodes;
};
// lispscanner.cpp
#include "lispscanner.h"
// 当字符串结束(遇到0)的时候返回False
static bool SkipWhiteChar(char **pp)
{
char *src = *pp;
while (0 != *src)
{
if ((' ' != *src) && ('\t' != *src) && ('\n' != *src) && ('\r' != *src)) break;
src++;
}
*pp = src;
return (0 != *src);
}
bool LispScanner::Parse(const char *str)
{
assert(NULL != str);
char *p = (char *)str;
LispTokenNode node;
while (0 != *p)
{
if (!SkipWhiteChar(&p)) break;
char cur_char = *p++;
// 表开始符号
if ('(' == cur_char)
{
node.m_Value.clear();
node.m_Token = LBRACK;
m_Nodes.push_back(node);
}
// 表结束符号
else if (')' == cur_char)
{
node.m_Value.clear();
node.m_Token = RBRACK;
m_Nodes.push_back(node);
}
// 原子
else
{
std::string atom_value;
while ((')' != cur_char) && (' ' != cur_char) && ('\n' != cur_char) && ('\t' != cur_char) && ('\r' != cur_char))
{
// 不正确的结束
if (0 == cur_char) return false;
atom_value.append(1, cur_char);
cur_char = *p++;
}
node.m_Value = atom_value;
node.m_Token = ATOM;
m_Nodes.push_back(node);
//
if (')' == cur_char) p--;
}
}
return true;
}
std::list<LispTokenNode> &LispScanner::NodeList()
{
return m_Nodes;
}
void LispScanner::Clear()
{
m_Nodes.clear();
return;
}
#include "lisp.h"
#include "lispscanner.h"
// 这个就是生成表达式树的函数
std::list<LispCode> Parse(const std::string &text)
{
LispScanner scanner;
scanner.Parse(text.c_str());
std::list<LispCode> code_list;
LispCode gen_code;
auto node_list = scanner.NodeList();
auto node_it = node_list.begin();
while (node_list.end() != node_it)
{
// GenericCodeTree就是那个递归生成表达式树的函数,不过被我删了
// 问题就是无论如何都无法正确生成表达式树
// 不是缺这个就是指针混乱
// 比如:gen_code下面有一个列表a,这个列表a下面也有一个列表b,这个列表b有一个表达式,指向gen_code...,结果就是无限循环
// if (!GenericCodeTree(node_it, node_list.end(), gen_code)) break;
// code_list.push_back(gen_code);
}
return code_list;
}
// 测试数据:
const char *lisp_text =
"(texts
(1 逃亡启动器)
(2 使用了错误的参数)
(3 登录失败)
(4 游戏启动失败)
(5 用户系统初始化系统)
)";