编译原理真的学不通
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define max 6
char key [7][max]= {"main","int","char","while","if","else","for"};
int digit =0;
int CurPos_str=0;
char str [10]="";
void State0(char ch);
void State1(char ch);
void State3(char ch);
int Iskey (char ch[]);
bool IsDigit(char ch);
bool IsLetter(char ch);
int Iskey (char ch[])
{
for(int i=0; i<7; i++)
if(strcmp(key[i],ch)==0)
{
return i+1; //返回关键字序号,作为其种类编码
break;
}
return -1;
}
bool IsDigit(char ch) //判断字符是否为数字
{
if (ch>='0'&&ch<='9')
return true;
else
return false;
}
bool IsLetter(char ch) //判断是否为字母
{
if ((ch<='Z'&&ch>='a')||(ch <='Z'&&ch>='A'))
return true ;
else
return false ;
}
void State0( char ch )
{
while (ch==' ')
{
char C=getchar();
}
if(IsDigit(ch))
{
digit=10*digit+atoi(&ch);
ch=getchar();
State3(ch);
}
else if(IsLetter(ch))
{
str[CurPos_str++]=ch ;
ch=getchar();
State1(ch);
}
else if (ch=='(')
{
printf("(26,()\n");
ch=getchar();
State0(ch);
}
else if(ch=='+')
{
ch=getchar();
if (ch=='+')
{
printf("(44,++)\n");
ch=getchar();
State0(ch);
}
else
{
printf("(22,+)\n");
State0(ch);
}
}
}
void State1( char ch ) //分析标识符
{
while(IsDigit(ch)||IsLetter(ch))
{
strcat(str,&ch);
str[CurPos_str++]=ch;
ch=getchar();
}
int i=Iskey(str);
if(i>0)
printf("(%d,%s)\n",i,str);
else
printf("(20,%s)\n",str); //标识符分析结束,输出
for (int j=0;j<10;j++)
str[j]=0; //对str重新赋空值,以便存放下一个标识符
CurPos_str=0;
State0(ch); //进入状态0,重新进行下一轮的字符分析
}
void State3(char ch) //分析常数
{
while(IsDigit(ch))
{
digit=10*digit+atoi(&ch);
ch=getchar();
}
printf("(10,%d)\n",digit); //正常数分析结束
State0(ch);
}
void main ()
{
printf("请输入源代码:");
char ch ;
ch=getchar();
State0( ch );
}
参考GPT和自己的思路:
对于这个词法分析器,可以根据需求进行修改。以下是一些可能需要修改的方面:
关键字列表:代码中定义了一个关键字列表,如果需要新增或者修改关键字,需要在列表中进行修改。
种类编码:代码中定义了一些种类编码,例如变量名是20,常数是10。如果需要新增或者修改种类编码,需要在代码中进行修改。
状态转换函数:代码中定义了几个状态转换函数(State0、State1、State3),如果需要新增或者修改状态转换规则,需要在相应函数中进行修改。
输入方式:当前的代码是通过 getchar() 从控制台读取输入,如果需要从文件或者网络等其他方式读取输入,需要在代码中进行修改。
总的来说,这个词法分析器是一个比较简单的版本,可以根据具体情况进行灵活修改。如果需要更进一步的功能,例如支持正则表达式,可以考虑使用开源的词法分析器生成工具,例如 Flex。
调试输出下错误信息看看