📄 词法分析器.cpp
字号:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define length 42
#define MAX 2048
char *keytable[]={"include","static","auto","double","int","struct", "break","else",
"long","switch","case","return","union","const","float","short",
"unsigned","printf","stdio","typedef","char","extern","long",
"continue","for","signed","void","default","goto","sizeof","define",
"volatile","do","if","static","while","main","malloc","\\n","\\r","\\t","\\0"};
struct linklist { //建立链表
char data[MAX];
struct linklist *next;
};
struct hashlink{ //创建哈希表
int id;
struct linklist *link;
}hashlist[MAX];
struct charstring //创建字符串结构
{
char s[MAX];
}w[MAX];
struct record{ //记录字符的机内码
int ip;
char string[MAX];
}hashrecord[MAX];
int l=0;
//***************************************************************************************************
void initrecord()//record结构初始化
{ int i;
for(i=0;i<MAX;i++)
{ hashrecord[MAX].ip=-1; }
}
//***************************************************************************************************
charstring chartable(FILE *fp) /*字符串表*/
{
char c;
struct charstring q,p;
int i=0,k=1;
if(!feof(fp))
{
q.s[i]=fgetc(fp);
if(q.s[i]==' '||q.s[i]=='\n')
{
while((c=fgetc(fp))==' '||c=='\n'||c=='\r'||c=='\0');
q.s[i]=c;
}
switch(q.s[i])
{
case '#':case ';':case '?':case '"':case ':':case'\'':
case '(':case ')':case '[': case ']':case '{':case '}':
break;
case '\\':
if((c=fgetc(fp))=='n'||c=='t'||c=='r'||c=='0')
{ q.s[++i]=c; break; }
else{
fseek(fp,-1,1);
break;
}
case'.':
if((c=fgetc(fp))=='0'||c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'||c=='8'||c=='9')
{ q.s[++i]=c;
fseek(fp,-1,1);
c=fgetc(fp);
goto l;
}
else{ fseek(fp,-1,1); break; }
case '!':if((c=fgetc(fp))=='=')
{
q.s[++i]=c;
break;
}
else {fseek(fp,-1,1);break;}
case '*':if((c=fgetc(fp))=='='||c=='/')
{
q.s[++i]=c;
break;
}
else
{ fseek(fp,-1,1);break;}
case '&':if((c=fgetc(fp))=='&')
{
q.s[++i]=c;
break;
}
else {fseek(fp,-1,1);break;}
case '/': if((c=fgetc(fp))=='*')//1
{
q.s[++i]=c;
while(c=fgetc(fp))
{
if(c=='*')//2
if((c=fgetc(fp))=='/')//3
{
fseek(fp,-2,1);
break;
}
else fseek(fp,-1,1);
}//while
break;
}//if1
else
if(c=='/')
{
q.s[++i]=c;
fgets(p.s,MAX-1,fp);//读入一行字符;
break;
}
else
{
fseek(fp,-1,1);
break;
}
case '+': if((c=fgetc(fp))=='='||c=='+')
{
q.s[++i]=c;
break;
}
else
{fseek(fp,-1,1);
if((c=fgetc(fp))=='0'||c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'||c=='8'||c=='9')
{ q.s[++i]=c;
fseek(fp,-1,1);
c=fgetc(fp);
goto l;
}//正数.......
else
{ fseek(fp,-1,1);break;}
}
case '-':if((c=fgetc(fp))=='='||c=='-')
{
q.s[++i]=c;
break;
}
else
{ /* fseek(fp,-1,1);
if((c=fgetc(fp))=='>')
{ q.s[i++];
break;
}
else
{ */fseek(fp,-1,1);
if((c=fgetc(fp))=='0'||c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'||c=='8'||c=='9')
{ q.s[++i]=c;
fseek(fp,-1,1);
c=fgetc(fp);
goto l;
}//负数......
else {fseek(fp,-1,1);break;}
}
case '|':if((c=fgetc(fp))=='|')
{
q.s[++i]=c;
break;
}
else {fseek(fp,-1,1);break;}
case '%':if((c=fgetc(fp))=='d'||c=='f'||c=='l'||c=='s'||c=='c')
{
q.s[++i]=c;
break;
}
else {fseek(fp,-1,1);break;}
case '<':
if((c=fgetc(fp))=='='||c=='<')
{
q.s[++i]=c;
break;
}
else {fseek(fp,-1,1);break;}
case '>':if((c=fgetc(fp))=='='||c=='>')
{
q.s[++i]=c;
break;
}
else {fseek(fp,-1,1);break;}
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V':
case 'W': case 'X': case 'Y': case 'Z': case '_':
while(!feof(fp))
{
c=fgetc(fp);
switch(c)
{
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p':
case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V':
case 'W': case 'X': case 'Y': case 'Z': case '_': q.s[++i]=c; break;
default : fseek(fp,-1,1); k=0; break;
}
if(k==0) break;
}//???????????????????????!!!!!!!!!!!!!!!!!!!!!!!!!!
l: case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
while(!feof(fp))
{
c=fgetc(fp);
switch(c)
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6':case '7': case '8': case '9':
q.s[++i]=c; break;
case'.': q.s[++i]=c; break;
case'E':case'e':
if(((c=fgetc(fp))=='+'||c=='-')&&((c=fgetc(fp))=='0'||c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'||c=='8'||c=='9'))
{ fseek(fp,-3,1);
c=fgetc(fp);
q.s[++i]=c;
c=fgetc(fp);
q.s[++i]=c;
c=fgetc(fp);
q.s[++i]=c;
goto l;
fseek(fp,1,1);
}//科学计数法................
else { fseek(fp,-2,1);break; }
default : fseek(fp,-1,1); k=0;break;
}
if(k==0) break;
}
default : break;
}
q.s[++i]='\0';//其他字符的处理
}
return q;
}
//****************************************************************************************************
int chartype(char *p)/*找字符串的类型*/
{
int q,i; char c;
for(i=0;i<length;i++)
if((strcmp(p,keytable[i]))==0)
{ q=1; break; }
if(i>=length)
{
c=*p;
switch(c)
{
case '>':case '<':case '=':case '#':case '(':
case ')':case '{':case '}':case '[':case ']':case '$':
case '%':case '&':case '|':case '?':case '!':case '~':
q=2; break;
case '-': c=*(p+1);
if(c=='>') q=3;/*->的类型的判断*/
if(c=='0'||c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'||c=='8'||c=='9'||c=='.') q=5;
else q=2; //科学计数法
break;
case'+': c=*(p+1);
if(c=='0'||c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7'||c=='8'||c=='9'||c=='.') q=5;
else q=2; //科学计数法
break;
case '/': c=*(p+1);
if(c=='*')q=3;
else q=2; break;
case '*':c=*(p+1);
if(c=='/') q=3;
else q=2; break; /*注释的类型*/
case ';':case '"':case ',':case ':':case '.':case '\'':
q=4; break;
case '0':case '1':case '2':case '3':case '4':case '5':case '6': case '7':case '8':case '9':
q=5; break;
default : q=6;
}
}
return q;
}
//****************************************************************************************************
void creatlinklist()//链表初始化
{ int i;
for(i=0;i<=MAX;i++)
{
hashlist[i].id=-1;
hashlist[i].link=NULL;
}
}
//****************************************************************************************************
int hash(char *p)
{
int i,k,g;
k=0;
char a[MAX];
i=0;
strcpy(a,p);
while(a[i]!=NULL)
{ k+=a[i];
i++;
}
g=k%2039;
return g;
}
//****************************************************************************************************
int searchhash(char *p)/*hash表的查找*/
{
int w,t;
w=hash(p);
t=chartype(p);
if(hashlist[w].link==NULL)
{
return -1;
}
else
{
struct linklist *x;
x=hashlist[w].link;
while(x->next!=NULL&&(strcmp(x->data,p)!=0))
x=x->next;
if(strcmp(x->data,p)==0)
{
return 0;
}
else
{
return -1;
}
}
}
//****************************************************************************************************
void creathash(char *p)//哈希插入
{ int w,v;
w=hash(p);
v=chartype(p);
struct linklist *q;
q=(struct linklist *)malloc(sizeof(struct linklist));
strcpy(q->data,p);
q->next=NULL;
if(hashlist[w].link==NULL)
{ hashlist[w].id=v;
hashlist[w].link=q;
}
else
{
struct linklist *p2;
p2=hashlist[w].link;
while(p2->next!=NULL) p2=p2->next;
p2->next=q;
}
strcpy(hashrecord[l].string,p);
hashrecord[l].ip=w;
l++;
}
//*****************************************************************************************************
/*void tdisplay(charstring c)
{
int i,j;
struct charstring *p;
j=1;
p=&c;
i=0;
while(p->s[i]!=NULL)
{
printf("%c",p->s[i]);
j++;
++i;
}
printf("\n");
}*/
//*****************************************************************************************************
void display()
{
int i/*,j*/;
struct linklist *p;
//j=0;
for(i=0;i<MAX;i++)
{
p=hashlist[i].link;
while(p!=NULL)
{ // if(j%5==0){ printf("\n"); }
printf(" (%s,%d)",p->data,hashlist[i].id);
if(p->next!=NULL)
{ printf("->");}
else
{ printf("\n"); }
p=p->next;
// j++;
}
}
}
//*****************************************************************************************************
void qdisplay()
{ int i,j;
for(i=0;i<l;i++)
{
if(hashrecord[i].ip!=-1)
{ if(j%5==0){ printf("\n"); }
printf(" (%s,%d) ",hashrecord[i].string,hashrecord[i].ip);
j++;
}
}
}
//*****************************************************************************************************
void print()
{
printf("1:关键字 2:运算符 3:指针 4:界限符 5:数字 6:字符串");
}
//*****************************************************************************************************
void print();
void display();
void creathash(char *p);
int searchhash(char *p);
int chartype(char *p);
charstring chartable(FILE *fp);
void creatlinklist();
//*****************************************************************************************************
void main ()
{
FILE *fp;
char ch;
int i,k,r;
i=0;
printf("**********************************词法分析器************************************");
if ((fp=fopen("2.txt","r"))==NULL)
printf("源程序无法打开!\n");
else
{
printf("\n************************************源程序**************************************");
while((ch=fgetc(fp))!=EOF)
{
printf("%c",ch);
}
fclose(fp);
printf("\n");
printf("********************************************************************************");
fp=fopen("2.txt","r");
creatlinklist();
initrecord();
while(!feof(fp))
{
w[i]=chartable(fp);
r=searchhash(w[i].s);
if(r=-1)
creathash(w[i].s);
++i;
}
printf("分析结果:\n");
display();
/*int j=0;
for(j=0;j<=i;j++)
tdisplay(w[j]);
*/
printf("********************************************************************************");
printf("是否查看帮助文件?:**是—键入'1'**否键入—'0'**:");
scanf("%d",&k);
if(k==1) print();
printf("\n********************************************************************************");
printf("(符号串,机内码):");
qdisplay();
}
printf("\n***********************************词法分析器结束*******************************");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -