您的位置:首页 > 其它

词法分析器(1.二叉排序树)

2006-04-15 17:14 281 查看
//////////////////////////////////////////////////////////////////////////
// Fundamentals of Compiler
//project: World analysis
//written by: kejie 03 computer science and techology 086
//create time: 2006.3.25
//modified: 2006.4.2
//file name: BSTree.h
//note: This file is declearation of binary sort tree declearation
//Copyright University of electronic science and technology of China, ZhongShan Institute.
//////////////////////////////////////////////////////////////////////////

#include<iostream.h>
#include<string.h>
#include<stdlib.h>
#include<fstream.h>
#include <iomanip.h>
#include <assert.h>

class BSTree;

//二叉排序树结点类
class BSTreeNode
{
public:
friend class BSTree;

BSTreeNode();
~BSTreeNode();
private:
char * world; //字符串
short int code; //编码
BSTreeNode * lchild, * rchild;
};

//二叉排序树
class BSTree
{
public:
BSTree();
BSTree(char * file, int CurCodeValue);
~BSTree();

bool LoadFile( const char * path); //从外部读入文件
bool SerachBst( char * keyword, BSTreeNode ** p); //从二叉树中查找
int GetWordCode( char * keyword ); //取得指定字符串在树中编码
int GetCurCode(); //取得当前编码号
void SetCurCode(int value);

bool InsertBst( char * keyword); //插入结点

void CodeTree(); //给整棵树编码
void PrintTree();
void DestroyTree(); //释放所有结点

private:
void CodeTreeNode(BSTreeNode * root);
void PrintTreeNode(BSTreeNode * root);
void DestroyTreeNode(BSTreeNode * root);
BSTreeNode * Troot;
char CurCode;

};

//////////////////////////////////////////////////////////////////////////
// Fundamentals of Compiler
//project: World analysis
//written by: kejie 03 computer science and techology 086
//create time: 2006.3.25
//modified: 2006.4.13
//file name: BSTree.cpp
//note: This file is the implenment of binary sort tree.
// It uses to store key worlds which load from file!
//Copyright University of electronic science and technology of China, ZhongShan Institute.
//////////////////////////////////////////////////////////////////////////
#include"BSTree.h"

char * KeyWorldPath = "keyworld.txt";

BSTreeNode::BSTreeNode()
{
code = 0x00;
world = 0;
lchild = rchild = NULL;
}

BSTreeNode::~BSTreeNode()
{
if ( world )
delete [] world;
}

BSTree::BSTree()
{
Troot = NULL;
//Troot->lchild = Troot->rchild = NULL;
CurCode = 0x00;
}

BSTree::BSTree(char * file, int CurCodeValue)
{
Troot = NULL;
//Troot->lchild = Troot->rchild = NULL;

assert(CurCodeValue>=0);
CurCode = 0x00;

LoadFile(file);
SetCurCode(CurCodeValue);
CodeTree();
}

BSTree::~BSTree()
{
DestroyTree();
}

//从外部文件读入关键子,默认路径为当前目录
bool BSTree::LoadFile( const char * path )
{

char buffer[20], *word;
int len =0;

ifstream input;
input.open(path);

while(input>>buffer)
{
len = strlen(buffer);
word = new char[len+1];

strcpy(word,buffer);
if ( !InsertBst(word) )
return false;

delete word;
}

input.close();

return true;

}

//从排序树中查找关键字
bool BSTree::SerachBst(char * keyword, BSTreeNode ** p)
{
int compres = 0;
BSTreeNode * ptr = Troot;

*p = NULL;

while( ptr )
{
//比较关键字字符串: 0 符合 >0 向右搜索 <0 向左搜索
compres = strcmp(ptr->world,keyword);
if ( compres == 0 )
{
*p = ptr;
return true;
}
else
{
*p = ptr;
ptr = compres>0?ptr->lchild:ptr->rchild;
}
}

return false;
}

//从排序树中插入关键字,插入同时给关键字等长编码 从 0x00 - 0xFF 最多256个
bool BSTree::InsertBst(char * keyword)
{
BSTreeNode *s, *p;
s = NULL;
p = NULL;

//查找不到结点时插入
if( ! SerachBst(keyword,&p ))
{
s = new BSTreeNode;
if (!s)
return false;

//加多一位保存 "/0"
s->world = new char[strlen(keyword)+1];
strcpy(s->world,keyword);
s->lchild = s->rchild = NULL;

//如是Troot根结点为空,直接指定,如果不是,关键字少的放左边,大的放右边
if( !Troot )
{
Troot = s;
}
else if ( strcmp(p->world,keyword)<0)
p->rchild = s;
else
p->lchild = s;

}
return true;
}

//给用中序遍历给所有结点编码,以后查找时可实现最优
void BSTree::CodeTreeNode(BSTreeNode * root)
{
if(root)
{
CodeTreeNode(root->lchild);
root->code = CurCode++;
CodeTreeNode(root->rchild);
}
}

void BSTree::CodeTree()
{
CodeTreeNode(Troot);
}

//打印有序树及编码
void BSTree::PrintTreeNode(BSTreeNode * root)
{
if(root)
{
PrintTreeNode(root->lchild);
cout<<root->world<<setw((15 - strlen(root->world)))<<":"<<hex<<root->code<<endl;
PrintTreeNode(root->rchild);
}
}

void BSTree::PrintTree()
{
PrintTreeNode(Troot);
}

//说明:释放所有结点
//过程:
//不断删除顶点结点,有以下几种情况
//1.如果顶点无左右结点,完成
//2.有左结点无右结点,将左结点设为新顶点
//3.有右结点无左结点,将右结点设为新顶点
//4.左右结点都有,将左结点设为新顶点,同时将右结点的父结点设为左结点子树中最右下结点,构成一棵新树
void BSTree::DestroyTreeNode(BSTreeNode * root)
{
BSTreeNode *p, *q;

while( root != NULL )
{
if ( root->lchild == NULL && root->rchild == NULL )
{
delete [] root->world;
root->world = NULL;
delete root;
return;
}

if ( root->lchild != NULL && root->rchild == NULL )
{
p = root;
root = root->lchild;

//先释放结点中的字符串,再删除整个结点! 字符串释放后要设为NULL,否则再删除结点时会出错
delete [] p->world;
p->world = NULL;
delete p;
}
else if (root->lchild == NULL && root->rchild != NULL )
{
p = root;
root = root->rchild;

delete [] p->world;
p->world = NULL;
delete p;
}
else
{
p = root;
q = root->rchild;
root = root->lchild;

delete [] p->world;
p->world = NULL;
delete p;

p = root;

//和并右子树,找出当前root的最右下结点,指向q
while ( p->rchild != NULL )
p = p->rchild;

p->rchild = q;

}
}

}

//取得当前编码值
int BSTree::GetCurCode()
{
return CurCode;
}

//设置当前编码值
void BSTree::SetCurCode(int value)
{
CurCode = value;
}

void BSTree::DestroyTree()
{
DestroyTreeNode(Troot);
}

//查找关键字编码
int BSTree::GetWordCode( char * keyword )
{
int compres = 0;
BSTreeNode * ptr = Troot;

while( ptr )
{
//比较关键字字符串: 0 符合 >0 向右搜索 <0 向左搜索
compres = strcmp(ptr->world,keyword);
if ( compres == 0 )
{
return ptr->code;
}
else
{
ptr = compres>0?ptr->lchild:ptr->rchild;
}
}

return -1;
}

/*
int main()
{
BSTree btree;

btree.LoadKeyWorld(KeyWorldPath);
btree.CodeTree();

btree.DestroyTree();

//cout<<btree.GetWordCode("struct");

return 0;
}
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: