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

//////////////////////////////////////////////////////////////////////////
//     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;
}
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值