📄 程序2.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 + -