⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.h

📁 一个实现词法分析的程序 VC++环境 所需的efile.pas rfile.pas和头文件 仅供参考
💻 H
字号:
#include <stdlib.h>
#include <fstream.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <iostream.h>
#define    WORD                0x0  
#define    NUMERIC             0x2
#define    COMMENTS            0x3
#define    INTERIEAVE          0x4
#define    CONSTANT            0x1
#define    ILLEGAL             0x5
char codebuf[100][100];      //源代码总缓冲区
char CodeingList[60][100];//编码表存储
int SumLine;
typedef struct errornote //错误记录结构
{
	int line;   //错误所在行
	int row;    //错误所在列
	int num;    //错误总行数
	int kind;   //错误类型 :1 注释为闭合2 小数点错误3 
}ENote;
//堆栈操作
typedef struct character
{
    char word;
	character *next;
}ch;          //堆栈结点结构
typedef struct dualitynode  //二远组结构
{
	int num;    //种别码
	int value; //单词自身值
    dualitynode *next;
}DUALITY;
typedef struct name
{
	int Pos;  //起始位置
	int len;  //长度
}NAME;
enum type{No,integer,real,character};
enum kind{no,constant};
//标识符都没有类型,种属和值
//字符常量类型为字符,种属为常数,没有值
//数字常量类型为整,实,种属为常数,有值,无名字
typedef struct symboltable  //符号表结构
{
  	NAME strname;   //名字
    type typesign;  //类型
	kind kindsign;  //种属
	char *value;   //数值,以字符形式形式存储
}ST;
////////////////////////////////////////////////
//符号表类
class table
{
	ST *st;  //符号表指针
    char *str; //符号串0 预留
	int item;  //符号表总项数,0项预留
    int len;  //符号串长度
public:
	table()
	{
		item=0;
		len=0;
		st=(ST *)malloc(sizeof(ST));
		st[0].value=NULL;
		str=NULL;
	}
	~table()
	{
		/*for(int i=0;i<=item;i++)
		{
			free(st[i].value);
		}*/
		free(st);
		free(str);
	}
	int exame(char *content,int flag);
	int findstr(char *sub,int pos);
	bool writefile();
	void display();
};
/////////////////////////////
class stack   //堆栈类
{
	ch *top;  //栈顶指针
	ch *base;
public:
	stack();
	~stack();
	void push(char);
	bool Pop(char &);
	char * &getcontent();
	void print();
};
////////////////////////////
class duality       //2元组类
{
DUALITY *head;        //全局变量,链表头
DUALITY *tail;        //全局变量,链表尾
public:
	duality()
	{head=NULL;
	tail=NULL;}
	/*~duality()
	{DUALITY *temp1,*temp2;
	 temp1=temp2=head;
	 while(temp1->next!=NULL)
	 {temp2=temp1->next;
	  free(temp1);
	  temp1=temp2;
	 }
	 free(temp1);
	}*/
    void fillduality(int n,int num);
    bool writedualityfile();//将链表写入文件
    void displayduality();
    void displayduality(ofstream OutFile);
};
void readfile(char *filename,char bufname[][100]);//读源代码文件
char *Mygetline(int line);  //读入一行字符
char getword(char *p,int &n); //读入一个字符
int judge(char substr[]);    //查询编码表
int Translate(char temp);    //字符转换
bool checkreal(char *ch);//判定是否为实数
void Getstackcontent(char tm[],stack &s);   //获得堆栈的全部内容
void printerror();
//////////////////////////////////////////////
//函数实现
void readfile(char *filename,char bufname[][100])
{
	char temp;
	int line=0,ArrayPos=0,i=0;
	ifstream InFile;
	InFile.open(filename,ios::in);
			line=0;
			while(InFile.get(temp))
			{
				
				if(temp=='\n')
				{
					bufname[line][ArrayPos]='\0';
					line++;
					ArrayPos=0;
				}
				else
				{
					bufname[line][ArrayPos]=temp;
				    ArrayPos++;
				}
			}
			SumLine=line+1;
   InFile.close();
}
int table::findstr(char *sub,int pos)
{
    int i=0,j=pos-1;
	int slen=strlen(sub);
	if(str==NULL)
	{return 0;}
    while(i<slen&&j<len)
	{
		if(sub[i]==str[j])
		{i++;j++;}
		else
		{i=0;j=j-i+1;}
	}
	if(i==slen)
	{return j-slen+1;}
	else
	{return 0;}
}
int table::exame(char *content,int flag)
{
   int length;
   int m;
   int pos=1;
   ST *temp;
   char *p;
   length=strlen(content);
	if(flag==WORD||flag==CONSTANT)     //如果是标识符后者字符常数
    {
	    while(m=findstr(content,pos))//找到在字符串表中的位置,没找到返回0
        {
			for(int i=1;i<=item;i++)
			{
				//WORD值为0,CONSTANT值为1,恰好和typesign值对应
				//找到字符值相同的,再判断类型是否想同
				if((st[i].strname.Pos==m)&&((int)st[i].kindsign==flag)&&(st[i].strname.len==length))
				{
					{return i;}
				}//找到入口并返回
			}
			pos=m+length;
		}
            //没找到则插入新项
		    temp=(ST *)realloc(st,(item+2)*sizeof(ST));//给符号表增加空间
			st=temp;
			st[item+1].strname.Pos=len+1;     //填写name项
			st[item+1].strname.len=length;
			p=(char *)realloc(str,len+length+1);
			str=p;
			for(int i=0;i<=length;i++)  //将新串添加到字符串中
			{str[len+i]=content[i];}
			//strcat(str,content); //把新串添加到符号串中
			len=len+length;
			item++;        //符号表项加1
			if(flag==CONSTANT)  //根据标识符或者字符常量填写不同内容
			{st[item].kindsign=constant;
			 st[item].typesign=character;
			}
			else
			{st[item].kindsign=no;
			 st[item].typesign=No;
			} //填写其他项
			
            st[item].value=NULL;
			return item; //返回符号表入口
	
    }
   else  //如果是数字常量
   {
	  if(st!=NULL)
	  {
		  for(int i=1;i<=item;i++)
		  { 
		     if(st[i].value!=NULL)
			 {if(!strcmp(st[i].value,content))//顺序查找值相同的项
			  {return i;}//返回入口
			 }
		  }
	  }
	   //如果没有找到,也添加一项
	  st=(ST *)realloc(st,(item+2)*sizeof(ST));//给符号表增加空间
      st[item+1].strname.Pos=0;     //填写name项
	  st[item+1].strname.len=0;
	  item++;        //符号表项加1
	  st[item].kindsign=constant; //填写其他项
      st[item].value=(char *)malloc(length);
	  strcpy(st[item].value,content);
	  st[item].typesign=integer;
	   for(int i=0;i<length;i++) //判断是否为实数
	   {
		  if(content[i]=='.')
		  {st[item].typesign=real;
		  break;
		  }
	   }
	 return item;
   }
}
bool table::writefile()
{
    ofstream OutFile;
	OutFile.open("table.txt",ios::out);
	if(!OutFile)
	{
		cerr<<"can't open this file"<<endl;
		return false;
	}
	OutFile.width(10);
	OutFile<<"name";
	OutFile.width(10);
	OutFile<<"type";
	OutFile.width(10);
	OutFile<<"kind";
	OutFile.width(10);
	OutFile<<"value";
	OutFile.width(10);
	OutFile<<"addr"<<'\n';
	for(int i=1;i<=item;i++)
	{
		if(st[i].strname.Pos==0)
		{
			OutFile.width(10);
			OutFile<<" ";
		}
		else
		{
			OutFile.width(5);
			OutFile<<st[i].strname.Pos;
			OutFile.width(5);
			OutFile<<st[i].strname.len;
		}
		if(st[i].kindsign==constant)
		{
			OutFile.width(10);
			OutFile<<"constant";
		}
		else
		{
			OutFile.width(10);
			OutFile<<" ";
		}
		if(st[i].typesign==no)
		{
            OutFile.width(10);
			OutFile<<" ";
		}
		else
		{
            if(st[i].typesign==real)
			{OutFile.width(10);
			OutFile<<"real";}
			if(st[i].typesign==integer)
			{OutFile.width(10);
			OutFile<<"integer";}
			if(st[i].typesign==character)
			{OutFile.width(10);
			OutFile<<"character";}
		}
		if(st[i].value==NULL)
		{
			OutFile.width(10);
			OutFile<<"  "<<endl;
		}
		else
		{
			OutFile.width(10);
			OutFile<<st[i].value<<endl;
		}
		OutFile<<'\n';
	}
	OutFile<<str<<'\n';
}
void table::display()
{
	cout.width(10);
	cout<<"name";
	cout.width(10);
	cout<<"type";
	cout.width(10);
	cout<<"kind";
	cout.width(10);
	cout<<"value";
	cout.width(10);
	cout<<"addr"<<endl;
	for(int i=1;i<=item;i++)
	{
		if(st[i].strname.Pos==0)
		{
			cout.width(10);
			cout<<" ";
		}
		else
		{
			cout.width(5);
			cout<<st[i].strname.Pos;
			cout.width(5);
			cout<<st[i].strname.len;
		}
		if(st[i].kindsign==constant)
		{
			cout.width(10);
			cout<<"constant";
		}
		else
		{
			cout.width(10);
			cout<<" ";
		}
		if(st[i].typesign==no)
		{
            cout.width(10);
			cout<<" ";
		}
		else
		{
            if(st[i].typesign==real)
			{cout.width(10);
			cout<<"real";}
			if(st[i].typesign==integer)
			{cout.width(10);
			cout<<"integer";}
			if(st[i].typesign==character)
			{cout.width(10);
			cout<<"character";}
		}
		if(st[i].value==NULL)
		{
			cout.width(10);
			cout<<"  "<<endl;
		}
		else
		{
			cout.width(10);
			cout<<st[i].value<<endl;
		}
		cout<<'\n';
	}
	printf("%s",str);
}
char *Mygetline(int line) //从缓冲区读一行字符
{
	char *temp;
	temp=codebuf[line-1];
	return temp;
}
char getword(char *p,int &n)   //从一行字符读一个字符
{
   char temp;
   temp=p[n-1];
   n++;
   return temp;
}


int judge(char substr[])  //查询编码表,筛选出关键字,也用于搜索分界符
{
	int Pos=0,len;
    //readfile("date.ls");  //可在主函数中预先读出
    len=strlen(substr);
	while(Pos<60)
	{
		if(strcmp(substr,CodeingList[Pos])==0)
		{break;}
		Pos++;
	}
	if(Pos>59)
	{return 0;}       //如果没找到返回0
	return Pos+1;     //返回种别码
}
inline stack::stack()
{
	top=new ch;
	top->next=NULL;
}
inline stack::~stack()
{
	ch *temp1,*temp2;
	temp1=top;
	while(temp1->next!=NULL)
	{
		temp2=temp1->next;
		delete temp1;
		temp1=temp2;
	}
}
void stack::print()    //打印
{
	ch *temp;
	if(top->next==NULL)
	{cout<<"stack is empty!"<<endl;
	 return;
	}
	temp=top;
    cout<<temp->word<<endl;   //从栈头打印到栈尾
	temp=temp->next;
	while(temp->next!=NULL)
	{
		cout<<temp->word<<endl;
		temp=temp->next;	
	}
}
void stack::push(char w)  //字符压栈
{
    ch *p;
	p=new ch;
	p->word=w;
	p->next=top;
    top=p;

}
bool stack::Pop(char &p)  //字符出栈
{
    ch *temp;
	if(top->next==NULL)
	{
       return false;
	}
	p=top->word;
    temp=top;
	top=temp->next;
	delete temp;
	return true;
}
int Translate(char temp)        //字符转换函数
{
    int n;
	n=(int)temp;
	if(n<91&&n>64||n>96&&n<123)
	{
		return WORD;   //字符
	}
	if(n>47&&n<58)
	{
		return NUMERIC;//数字常量
	}
	if(n==47)
	{
		return COMMENTS;//注解符 /
	}
	if(n>39&&n<48||n>57&&n<63||n>90&&n<94||n==124)
	{
		return INTERIEAVE;//分界符
	}
	if(n==39)
	{
		return CONSTANT;  //字符常量标志'
	}
	if(n!=' '&&n!='\0')
	{
		return ILLEGAL;   //非法字符
	}
	return -1;
}
bool checkreal(char *ch)//判定是否为实数
{
	for(int i=0;i<strlen(ch);i++)
	{if(ch[i]=='.')
	    return true;
	}
	return false;
}
void printerror(ENote *eNote)
{
	int i;
	ofstream OutFile;
	if(!OutFile)
	{
		cerr<<"can't open this file"<<'\n';
		return;
	}
	OutFile.open("errorfile.txt",ios::out);
	for(i=0;i<eNote[0].num;i++)
	{
		switch(eNote[i].kind)
		{
		case 1:
			printf("error %d:line %d row %d 注释未闭合\n",
				   i+1,eNote[i].line,eNote[i].row);
			OutFile<<"error "<<i+1<<":line "<<eNote[i].line
				  <<" row "<<eNote[i].line<<" 注释未闭合"<<'\n';
			break;
		case 2:
            printf("error %d:line %d row %d 小数点重复\n",
				   i+1,eNote[i].line,eNote[i].row);
			OutFile<<"error "<<i+1<<":line "<<eNote[i].line
				  <<" row "<<eNote[i].line<<"小数点重复"<<'\n';
			break;
		case 3:
			printf("error %d:line %d row %d 非法标识符\n",
				   i+1,eNote[i].line,eNote[i].row);
            OutFile<<"error "<<i+1<<":line "<<eNote[i].line
				  <<" row "<<eNote[i].line<<"非法标识符"<<'\n';
			break;
		case 4:
			printf("error %d:line %d row %d 引号不封闭\n",
				   i+1,eNote[i].line,eNote[i].row);
			OutFile<<"error "<<i+1<<":line "<<eNote[i].line
				  <<" row "<<eNote[i].line<<"引号不封闭"<<'\n';
			break;
		case 5:
		    printf("error %d:line %d row %d 非法字符\n",
				   i+1,eNote[i].line,eNote[i].row);
			OutFile<<"error "<<i+1<<":line "<<eNote[i].line
				  <<" row "<<eNote[i].line<<"非法字符"<<'\n';
			break;
		}
	} 
}
void duality::fillduality(int n,int num)//n:种别码,num 符号表入口号,如果为0就不存在
{
     
	DUALITY *temp;
        temp=(DUALITY *)malloc(sizeof(DUALITY));
		temp->num=n;
		temp->value=num;//如果是关键字或界符值为0,输出时输出'_';
		                //符号表从1开始
	if(head==NULL)      //向链表添加一项
	{
		tail=head=temp;
		temp->next=NULL;
		return;
	}
	tail->next=temp;
	tail=temp;
	tail->next=NULL;
	return;

}
void duality::displayduality()
{
    DUALITY *temp=head;
	if(temp==NULL)
	{return;}
	while(temp->next!=NULL)
	{cout<<temp->num<<"   ";
	 if(!temp->value)
	 {cout<<'_'<<endl;}
	  else
	  {cout<<temp->value<<endl;}
	  temp=temp->next;
	}
	cout<<temp->num<<"   ";
		if(!temp->value)
			cout<<'_'<<endl;
		else
			cout<<temp->value<<endl;
}

void duality::displayduality(ofstream OutFile)
{
    DUALITY *temp=head;
	if(head==NULL)
	{return;}
	while(temp->next!=NULL)
	{OutFile<<temp->num<<"   ";
	 if(!temp->value)
	 {OutFile<<'_'<<'\n';}
	  else
	  {OutFile<<temp->value<<'\n';}
	  temp=temp->next;
	}
	OutFile<<temp->num<<"   ";
		if(!temp->value)
			OutFile<<'_'<<'\n';
		else
			OutFile<<temp->value<<'\n';
}
bool duality::writedualityfile()//将链表写入文件
{
	ofstream OutFile;
	OutFile.open("tokens.txt",ios::out);
	if(!OutFile)
	{
		cerr<<"can't open this file"<<endl;
		return false;
	}
    displayduality(OutFile);
    OutFile.close();
	return true;
}
void Getstackcontent(char tm[],stack &s)
{
	int n=0,i=0;
	char temp;
	while(s.Pop(temp))  //将字符全部出栈存入tm中
	{
		for(int n=i;n>0;n--)
		{tm[n]=tm[n-1];}
		tm[0]=temp;
		i++;
	}
	tm[i]='\0';
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -