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

📄 程序2.cpp

📁 编译原理 语义分析 c++ vc6.0 可用作本科课程设计、毕业设计等
💻 CPP
字号:
// 用DFA产生Tocken序列.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdlib.h"
#include "iostream.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stack.h"

#define MAXCHILDREN 1000
#define MAXNODENUMBER 1000
#define MAXREG 1000
#define MAXkeynum 128
#define MAXkeylen 32
///////////////////////////////////////////////////////////////////////////////
const char keywords[MAXkeynum][MAXkeylen]=
{
	"else\0","if\0","int\0","return\0","void\0","while\0","for\0","cin\0","cout\0","\0"
};
///////////////////////////////////////////////////////////////////////////////
int  print(nfapoin *nfa)
{   // 输出 SEE SEE DFA
	if(nfa==NULL){return 0;}
	cout<<"结点总数是"<<nfa->nodenumber<<endl;
	cout<<"node children"<<endl;
	for(int i=0;nfa->nodetable[i]!=NULL;i++){
		if(nfa->nodetable[i]->state!='\0'){
			cout<<nfa->nodetable[i]->number<<nfa->nodetable[i]->state<<"  ";}
		else{cout<<nfa->nodetable[i]->number<<"   ";}
		for(int k=0;nfa->nodetable[i]->next[k]!=NULL;k++){
			cout<<" -"<<nfa->nodetable[i]->throught[k]<<"->";
			cout<<nfa->nodetable[i]->next[k]->number<<"    ";
		}
		cout<<endl;
	}//cout<<endl;
	return 1;
}
///////////////////////////////////////////////////////////////////////////////
char cases(int a)
{
	switch (a)
	{
		case 1: return '1';
		case 2: return '2';
		case 3: return '3';
		case 4: return '4';
		case 5: return '5';
		case 6: return '6';
		case 7: return '7';
		case 8: return '8';
		case 9: return '9';
		case 0: return '0';
	}
	return 'e';
}
///////////////////////////////////////////////////////////////////////////////
int charstoint(char *ch)
{
	//puts(ch);
	int i,j,k=1,inter=0;
    for(i=0;*(ch+i+1)!='\0';i++); // cout<<"i="<<i<<endl;system("pause");
	for(j=i;j>=0;j--){
        inter=inter+(*(ch+j)-48)*k;
		k=k*10;
	}
	//cout<<"inter="<<inter<<endl;system("pause");
	return inter;
}
///////////////////////////////////////////////////////////////////////////////
char *inttochars(int inter,char *ch)
{
	int i,j,k;
    for(i=0;inter>0;i++){
	    *(ch+i)=cases(inter%10);
		inter=inter/10;
	}for(k=i;k<10;k++){*(ch+k)='\0';}
	i--;
	for(j=0;j<i;j++,i--){
	    k=*(ch+j);
		*(ch+j)=*(ch+i);
		*(ch+i)=k;
	}
	return ch;
}
///////////////////////////////////////////////////////////////////////////////
nfapoin *readAutomata(nfapoin *dfa)
{   // 读取有穷自动机DFA
	int i,j,k;
	int inter=0,seq=0,intertmp;
	char num[10];for(k=0;k<10;k++){num[k]='\0';}
	char ch;

	FILE *fp=fopen("Automata.txt","r");
	if(fp==NULL){cout<<"error!(文件不存在)"<<endl;return NULL;}
	for(i=0;isdigit(ch=fgetc(fp));i++){
		//cout<<ch;
		num[i]=ch;
	}inter=charstoint(num);
    dfa->nodenumber=inter;// 读取结点总数	
	for(k=0;num[k]!='\0';k++){num[k]='\0';}//cout<<inter<<endl;system("pause");

    for(i=0;i<inter;i++)
	{   // 申请结点空间
		node *tmp=new node;
		initnode(tmp);
		dfa->nodetable[i]=tmp;
		dfa->nodetable[i]->number=i+1; // 结点编号
	}
	ch=fgetc(fp);//cout<<ch;printf("%d",ch);system("pause");
    for(i=0;i<inter;i++)
	{   
		if(i>=9){ch=fgetc(fp);}if(i>=99){ch=fgetc(fp);}
		ch=fgetc(fp);ch=fgetc(fp);//读取结点状态//cout<<ch<<endl;system("pause");
		if(ch!=' '){dfa->nodetable[i]->state=ch;} // 结点状态
		if(ch==' '){dfa->nodetable[i]->state='\0';}
		j=0;
		while(1){
		    ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);ch=fgetc(fp);//跳过空格
			if(ch==10||ch==EOF){break;}
			ch=fgetc(fp);//读取权值
			dfa->nodetable[i]->throught[j]=ch; // 边throught
			ch=fgetc(fp);ch=fgetc(fp);

			for(k=0;num[k]!='\0';k++){num[k]='\0';}
			for(k=0;isdigit(ch=fgetc(fp));k++){
				num[k]=ch;
			}intertmp=charstoint(num);//读取指向的结点编号
			for(k=0;num[k]!='\0';k++){num[k]='\0';}
            dfa->nodetable[i]->next[j]=dfa->nodetable[intertmp-1];  // child
			j++;
			ch=fgetc(fp);//cout<<ch<<endl;system("pause");
        }
	}//print(dfa);system("pause");
	fclose(fp);
    return dfa;
}
///////////////////////////////////////////////////////////////////////////////
int gettoken(nfapoin *dfa)
{
    char ch,tmp,c[10];int i,number=0,flag=0,line=1,found=0;
	for(i=0;i<10;i++){c[i]='\0';}
    FILE *fps=fopen("source.txt","r");// 打开源文件source
	if(fps==NULL){cout<<"error!(文件不存在)"<<endl;return NULL;}
    FILE *fpd=fopen("tokensequnce.txt","w+");// 打开源文件dis
    FILE *fpw=fopen("wrongs.txt","w+");// 打开源文件dis
	ch=fgetc(fps);
    while(ch!=EOF)
	{
		//printf("%c%d ",ch,ch);system("pause");
		//if(ch==' '){ch=fgetc(fps);}// 跳过空格
		if(ch==10){fputc(10,fpd);ch=fgetc(fps);line++;}// 跳过回车换行
		if(ch==EOF){break;}
		for(flag=0,i=0;dfa->nodetable[0]->throught[i]!='\0';i++)
		{   // 检查ch是否在DFA里
			if(dfa->nodetable[0]->throught[i]==ch){flag=1;break;}
		}
		if(flag==0)
		{   //cout<<"--------------------------------- "<<ch<<endl;
			if(ch!='.'&&ch!='|'&&ch!='*'&&ch!='('&&ch!=')'&&ch!='#'&&ch!=9&&ch!=10&&ch!=' '&&ch>=0)
			{   // 发现错误
				cout<<"input erorr! 第 "<<line<<" 行的 "<<ch<<" 是错误输入!"<<endl;
                fputs("input erorr! 第 ",fpw); // 把错误写到文件里
				inttochars(line,c);
                for(i=0;c[i]!='\0';i++){
					fputc(c[i],fpw);
					//fputc(c[i],fpa);
				}
                fputs(" 行的 ",fpw);
				fputc(ch,fpw);
			    fputs(" 是错误输入!",fpw);
				fputc(13,fpw);fputc(10,fpw);
				//printf("%d\n",ch);
			}
			fputc(ch,fpd);//cout<<ch<<endl;system("pause");
			tmp=ch;
			ch=fgetc(fps);
			if(tmp!=10&&tmp!=' '&&ch!=' '&&ch!=10&&ch>=0&&tmp>=0)
			{
				fputc(' ',fpd);	
			}
		}
		if(ch==EOF){break;}
		for(i=0,number=0;dfa->nodetable[number]->throught[i]!='\0';i++)
		{   // 遍历有穷自动机
			found=0;
			if(dfa->nodetable[number]->throught[i]==ch)
			{   // 在有穷自动机中找到了这个字符
				number=dfa->nodetable[number]->next[i]->number-1;
				fputc(ch,fpd);
				tmp=ch;
				ch=fgetc(fps);// 读取下一个字符
				i=-1;
				found=1;
			}
		}
		if(ch!=' '&&tmp!=10&&tmp>=0){
		    fputc(' ',fpd);//printf("%c %d ",ch,ch);system("pause");	
		}
	}
	fclose(fps);
	fclose(fpd);
	fclose(fpw);
    return 1;
}
///////////////////////////////////////////////////////////////////////////////
char *itc(int inter,char *ch)
{
	int i,j,k;
    for(i=0;inter>0;i++){
	    *(ch+i)=cases(inter%10);
		inter=inter/10;
	}for(k=i;k<15;k++){*(ch+k)='\0';}
	i--;
	for(j=0;j<i;j++,i--){
	    k=*(ch+j);
		*(ch+j)=*(ch+i);
		*(ch+i)=k;
	}
	for(i=0;*(ch+i)!='\0';i++);
	if(i>0){
		for(i=i+6;i>2;i--){
			*(ch+i)=*(ch+i-6);
		}
		*(ch+0)=*(ch+1)=*(ch+2)=' ';
		*(ch+3)='I';*(ch+4)='D';*(ch+5)='=';
	}
	return ch;
}
///////////////////////////////////////////////////////////////////////////////
int getattribute(nfapoin *dfa)
{
    char ch,c[15];int i,number=0,flag=0,al=0,wr=0;
	for(i=0;i<10;i++){c[i]='\0';}
    FILE *fpt=fopen("tokensequnce.txt","r");// 打开源文件source
	if(fpt==NULL){cout<<"error!(文件不存在)"<<endl;return NULL;}
    FILE *fpa=fopen("attribute.txt","w+");// 打开源文件dis
	ch=fgetc(fpt);
    while(ch!=EOF)
	{
		while(ch==' '&&ch==10&&ch==9){ch=fgetc(fpt);}// 跳过 空格 回车 tab
		if(ch==EOF){break;}
		for(flag=1,i=0;dfa->nodetable[0]->throught[i]!='\0';i++)
		{   // 检查ch是否在DFA里
			if(dfa->nodetable[0]->throught[i]==ch){flag=0;break;}
		}

		//fputs("   ID=",fpa);
		fputs(itc(number,c),fpa);


		if(flag==1)
		{   // 发现错误
			if(ch!=' '&&ch!=10&&ch!=9){fputc(ch,fpa);}
			if(ch!=10&&ch!=' '&&ch!=9&&ch!='.'&&ch!='|'&&ch!='*'&&ch!='#'&&ch!='('&&ch!=')'){
				fputs("   ID=0",fpa);//(错误输入)
				//printf("%d\n",ch);system("pause");
				wr=1;
			}
			if(ch=='.'){fputs("   ID=35",fpa);}
			if(ch=='|'){fputs("   ID=36",fpa);}
			if(ch=='*'){fputs("   ID=37",fpa);}
			if(ch=='('){fputs("   ID=38",fpa);}
			if(ch==')'){fputs("   ID=39",fpa);}
			if(ch=='#'){fputs("   ID=40",fpa);}

			ch=fgetc(fpt);
			if(ch!=' '&&ch!=10&&ch!=9)
			{
				if(wr!=1){
					//fputs("   ID=",fpa);
				    //fputs(inttochars(number,c),fpa);
				}
				wr=0;
				fputc(10,fpa);
				al=1;
			}
		}
		while(ch==' '&&ch==10&&ch==9){ch=fgetc(fpt);}// 跳过 空格 回车 tab
		if(ch==EOF){break;}
		for(i=0,number=0;dfa->nodetable[number]->throught[i]!='\0';i++)
		{   // 遍历有穷自动机
			if(dfa->nodetable[number]->throught[i]==ch)
			{   // 在有穷自动机中找到了这个字符
				number=dfa->nodetable[number]->next[i]->number-1;
				if(ch!=' '&&ch!=10&&ch!=9){fputc(ch,fpa);}
				ch=fgetc(fpt);// 读取下一个字符
				i=-1;
			}
		}
		if(ch!=' '&&ch!=10&&ch!=9&&al!=1)
		{
			fputc(10,fpa);
			al=0;
		}
	}
	fclose(fpt);
	fclose(fpa);
    return 1;
}
///////////////////////////////////////////////////////////////////////////////
int chaobushuangdeshuchu(nfapoin *dfa)
{
	int i,j,ke;
	char ch;
	char buff[MAXkeylen],tmp[MAXkeylen],dig[MAXkeylen];
	for(i=0;i<MAXkeylen;i++){buff[i]=tmp[i]=dig[i]='\0';}
    FILE *fpa=fopen("attribute.txt","r");// 打开源文件source
	if(fpa==NULL){cout<<"error!(文件不存在)"<<endl;return NULL;}
    FILE *fpc=fopen("chaobushuangdeshuchu.txt","w+");// 打开源文件dis
	i=0;
	while(1)
	{
		ch=fgetc(fpa);
		if(ch==EOF){break;}
		if(ch==10)
		{
			ch=fgetc(fpa);
			for(i=0;i<MAXkeylen;i++){tmp[i]=dig[i]='\0';}
            for(i=0;buff[i]!=' ';i++){tmp[i]=buff[i];}
			for(i=i;buff[i]!='=';i++);
			for(i=i+1,j=0;buff[i]!='\0';i++,j++){dig[j]=buff[i];}
			//puts(buff);puts(tmp);puts(dig);
			if(charstoint(dig)==1)
			{
				for(i=0,ke=0;keywords[i][0]!='\0';i++){
				    if(strcmp(keywords[i],tmp)==0){
						fputs("< 关键字 , ",fpc);
						fputs(tmp,fpc);
						fputs(" >",fpc);
						fputc(10,fpc);
						ke=1;
						break;
					}
				}
				if(ke==0){
					fputs("< 标识符 , ",fpc);
					fputs(tmp,fpc);
					fputs(" >",fpc);
					fputc(10,fpc);
				}
			}
			if(charstoint(dig)==2)
			{
				fputs("< 常数 , ",fpc);
				fputs(tmp,fpc);
				fputs(" >",fpc);
				fputc(10,fpc);
			}
			if(charstoint(dig)==0)
			{
				fputs("< 错误 , ",fpc);
				fputs(tmp,fpc);
				fputs(" >",fpc);
				fputc(10,fpc);
			}
			if(charstoint(dig)==37||strcmp(tmp,"+")==0||strcmp(tmp,"-")==0||strcmp(tmp,"/")==0||
				strcmp(tmp,".")==0||strcmp(tmp,">")==0||strcmp(tmp,"<")==0||strcmp(tmp,"=")==0||
				strcmp(tmp,"==")==0||strcmp(tmp,">=")==0||strcmp(tmp,"<=")==0||strcmp(tmp,"%")==0||
				strcmp(tmp,"&&")==0||strcmp(tmp,"||")==0||strcmp(tmp,"!")==0||strcmp(tmp,"!=")==0||
				strcmp(tmp,">>")==0||strcmp(tmp,"<<")==0||strcmp(tmp,"->")==0||strcmp(tmp,"++")==0||
				strcmp(tmp,"--")==0)
			{
				fputs("< 运算符 , ",fpc);
				fputs(tmp,fpc);
				fputs(" >",fpc);
				fputc(10,fpc);
			}
			if(charstoint(dig)==6)
			{
				fputs("< 注释符 , ",fpc);
				fputs(tmp,fpc);
				fputs(" >",fpc);
				fputc(10,fpc);
			}
			if(strcmp(tmp,"(")==0||strcmp(tmp,")")==0||strcmp(tmp,"[")==0||strcmp(tmp,"]")==0||
				strcmp(tmp,"{")==0||strcmp(tmp,"}")==0||strcmp(tmp,",")==0||strcmp(tmp,";")==0||
				strcmp(tmp,":")==0||(tmp[0]=='"'&&tmp[1]=='\0')||strcmp(tmp,"#")==0||strcmp(tmp,"'")==0||
				strcmp(tmp,"\\")==0||strcmp(tmp,"|")==0)
			{
				fputs("< 界符 , ",fpc);
				fputs(tmp,fpc);
				fputs(" >",fpc);
				fputc(10,fpc);
			}
			for(i=0;i<MAXkeylen;i++){buff[i]=tmp[i]=dig[i]='\0';}
			i=0;//system("pause");
		}
		buff[i]=ch;i++;
		if(ch==EOF){break;}
	}
	fclose(fpa);
	fclose(fpc);
    return 1;
}
///////////////////////////////////////////////////////////////////////////////
int main()
{
	nfapoin *dfa = new nfapoin;
	initpoin(dfa);
	dfa=readAutomata(dfa);
	//print(dfa);
	gettoken(dfa);
	getattribute(dfa);
	chaobushuangdeshuchu(dfa);
	cout<<"ok! Tocken 序列已生成!"<<endl;
	system("pause");
	return 1;
}

⌨️ 快捷键说明

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