学过编译原理的同学一定知道词法分析,那么词法分析如何用c语言实现呢?
精力有限,做的词法分析器只能分析以下几种
编写程序前需要状态表
#include<stdio.h>
#include<string.h>#include<stdlib.h>
#include<stdbool.h>
int main()
{
int ipos=0;//当前存储位置
int istate=1;//当前状态
int nextistate=0;//下一状态
bool tag=true;
char *buffer;//指向单词缓冲区的指针
int textab[6][4]={{},{2,4,-1},{2,-1,3},{4,-1,-1},{4,4,-1}};\\转换表
char code[1000];//存输入的字符串
char put[100][100];//存入得出的结果
char ch;//获得输入字符串的一个字符
int i=0,j=0,k=0,p,m=0,n=0;
char chucun[100];//存取出的值eg int i=5;先将int取出来存入
printf("////////////////////小型词法分析器////////////////////////\n");
printf("请输入程序,程序以#结束\n");
while((ch=getchar())!='#')
{
code[i]=ch;//7.9e+8-\0 ipos=6
i++;
}
code[i]='\0';
while(ipos<strlen(code)&&tag!=0)
{
*buffer=code[ipos];//将源程序当前字符加入缓冲区 int a08ui=3.14;
if(code[ipos]!='\0')
{
if((code[ipos]>='a'&&code[ipos]<='z')||(code[ipos]>='A'&&code[ipos]<='Z')||(code[ipos]>='0'&&code[ipos]<='9')||(code[ipos]=='.'))
{
chucun[j]=code[ipos];
j=j+1;
if(code[ipos]>='0'&&code[ipos]<='9')
{
nextistate=textab[istate][0];
}
else if((code[ipos]>='a'&&code[ipos]<='z')||(code[ipos]>='A'&&code[ipos]<='Z'))
{
nextistate=textab[istate][1];
}
else if(code[ipos]=='.')
{
nextistate=textab[istate][2];
}
if(nextistate==-1)
{
printf("%s输入形式错误\n",code);
//tag=false;
break;
}
else if(nextistate>0)
{
istate=nextistate;
}
}
else
{
istate=1;
if(j!=0)
{
j=j-1;
if(strcmp(chucun,"main")==0)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:1 属性:关键字");
}
else if(strcmp(chucun,"int")==0)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:2 属性:关键字");
}
else if(strcmp(chucun,"float")==0)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:3 属性:关键字");
}
else
{
for(p=0;p<=j;p++)
{
if((chucun[p]>='a'&&chucun[p]<='z')||(chucun[p]>='A'&&chucun[p]<='Z'))
{
if(p!=0)
{
printf("%s格式错误\n",chucun);
//tag=false;
break;
}
else
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:4 属性:标识符");
break;
}
}
else if(chucun[p]=='.')
{
i=6;
}
else
{
if(p==j)
{
if(i==6)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:6 属性:实常数");
}
else
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:5 属性:整常数");
}
}
}
}
}
memset(chucun,0,sizeof(chucun));
j=0;
}
if(code[ipos]=='+')
{
strcpy(put[k++],"+");
strcpy(put[k++],"词类编码:8 属性:运算符");
}
else if(code[ipos]=='-')
{
strcpy(put[k++],"-");
strcpy(put[k++],"词类编码:9 属性:运算符");
}
else if(code[ipos]=='=')
{
strcpy(put[k++],"=");
strcpy(put[k++],"词类编码:7 属性:运算符");
}
else if(code[ipos]==';')
{
strcpy(put[k++],";");
strcpy(put[k++],"词类编码:10 属性:分界符");
}
else if(code[ipos]=='(')
{
strcpy(put[k++],"(");
strcpy(put[k++],"词类编码:13 属性:分界符");
m=m+1;
}
else if(code[ipos]==')')
{
strcpy(put[k++],")");
strcpy(put[k++],"词类编码:14 属性:分界符");
m=m+1;
}
else if(code[ipos]=='{')
{
strcpy(put[k++],"{");
strcpy(put[k++],"词类编码:11 属性:分界符");
n=n+1;
}
else if(code[ipos]=='}')
{
strcpy(put[k++],"}");
strcpy(put[k],"词类编码:12 属性:分界符");
n=n+1;
}
else if(code[ipos]==' ')
{
}
else if(code[ipos]=='\n')
{
}
else
{
printf("%c输入错误\n",code[ipos]);
//tag=false;
break;
}
}
*buffer=NULL;
}
ipos++;
}
if(j!=0)
{
j=j-1;
if(strcmp(chucun,"main")==0)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:1 属性:关键字");
}
else if(strcmp(chucun,"int")==0)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:2 属性:关键字");
}
else if(strcmp(chucun,"float")==0)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:3 属性:关键字");
}
else
{
for(p=0;p<=j;p++)
{
if((chucun[p]>='a'&&chucun[p]<='z')||(chucun[p]>='A'&&chucun[p]<='Z'))
{
if(p!=0)
{
printf("%s格式错误\n",chucun);
//tag=false;
break;
}
else
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:4 属性:标识符");
break;
}
}
else if(chucun[p]=='.')
{
i=6;
}
else
{
if(p==j)
{
if(i==6)
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:6 属性:实常数");
}
else
{
strcpy(put[k++],chucun);
strcpy(put[k++],"词类编码:5 属性:整常数");
}
}
}
}
}
memset(chucun,0,sizeof(chucun));
}
if(tag!=0)
{
if(((n%2)==0)&&((m%2)==0))
{
for(i=0;i<k;i++)
{
printf("%s\n",put[i]);
if(i%2==1)
{
printf("\n");
}
}
}
else if((n%2)!=0)
{
printf("分界符{}不完整");
}
else if((m%2)!=0)
{
printf("分界符()不完整");
}
}
return 0;
}