📄 lexicalanalyzer.cpp
字号:
//CMM语言词法分析器
//BY 高旭 学号200632580318 武汉大学国际软件学院06级10班
//祝为我批改作业的来时身体健康,心情愉快,工作顺利
#include <iostream>
#define N 20
#define keywordSum 7
using namespace std;
//保留字表
char *keyword[keywordSum]={"if","else","int","real","write","read","while"};
//判断一个字段是整数或者是浮点数
//传入的参数为一个字符串的地址
//返回值是2时不是合法的数据
//返回值是1时为整数
//返回值是2时为浮点数
int isIntOrReal(char *str)
{
int k,j=0;
for(k=0;str[k]!='#'&&str[k]!='\0';k++)
{
switch(j)
{
case 0:
{
if(k==0&&str[k]>='0'&&str[k]<='9') j=1;
else return(0);
break;
}
case 1:
{
if(str[k]>='0'&&str[k]<='9') j=1;
else if(str[k]=='.') j=2;
else return(0);
break;
}
case 2:
{
if(str[k]>='0'&&str[k]<='9') j=3;
else return(0);
}
case 3:
{
if(str[k]>='0'&&str[k]<='9') j=3;
else return(0);
}
}
}
if(j==1) return 1;//返回值是1时为整数
else if(j==3) return 2;//返回值是2时为浮点数
else return 0;
}
//判断是否是标识符
//传入的参数为一个字符串的地址
//返回值为1是是合法的标识符或者是关键字
int isID(char *str)
{
int k,j=0;
for(k=0;str[k]!='#'&&str[k]!='\0';k++)
{
switch(j)
{
case 0:
{
if((k==0&&str[k]>='a'&&str[k]<='z')||(str[k]>='A'&&str[k]<='Z')) j=3;
else return 0;
break;
}
case 1:
{
if((str[k]>='0'&&str[k]<='9')||(str[k]>='a'&&str[k]<='z')||(str[k]>='A'&&str[k]<='Z')) j=2;
else if (str[k]=='_') j=1;
else return 0;
break;
}
case 2:
{
if((str[k]>='a'&&str[k]<='z')||(str[k]>='0'&&str[k]<='9')||(str[k]>='A'&&str[k]<='Z')) j=2;
else if (str[k]=='_') j=1;
else return 0;
break;
}
case 3:
{
if((str[k]>='a'&&str[k]<='z')||(str[k]>='0'&&str[k]<='9')||(str[k]>='A'&&str[k]<='Z')) j=2;
else if(str[k]=='_') j=1;
else return 0;
break;
}
case 4:
{
if((str[k]>='a'&&str[k]<='z')||(str[k]>='0'&&str[k]<='9')||(str[k]>='A'&&str[k]<='Z')) j=2;
else if(str[k]=='_') j=1;
else return 0;
break;
}
}
}
if(j==2||j==3) return 1;//返回值为1是是合法的标识符
else return 0;
}
//判断特殊符号
//输入是一个字符串
//返回值是0时是非法符号
//返回值是1时字段是一个运算符号
//返回值是2时字段是一个关系符号
int isSign(char *str)
{
int k,j=0;
for(k=0;str[k]!='#'&&str[k]!='\0';k++)
{
switch(j)
{
case 0:
{
if((k==0)&&(str[k]=='+'||str[k]=='-'||str[k]=='*'||str[k]=='/'||str[k]=='('||str[k]==')'||str[k]=='{'||str[k]=='}'||str[k]==';'||str[k]=='>'))
j=1;
else if(str[k]=='='||str[k]=='<') j=2;
//else if(str[k]=='/') j=4;
else return 0;
break;
}
case 1:
{
j=1;
return 0;
break;
}
case 2:
{
if(str[k]=='='||str[k]=='>') j=3;
else j=0;
break;
}
}
}
if(j==1||j==2||j==4||j==7) return 1;
else if (j==3) return 2;
else return(0);
}
main ()
{
//k是判断其字段类型的序号
//i是想屏幕上写字符的序号
//n是判断是否属于保留字的时的序号
//LineNum是行号
int k,i,n,h=0,LineNum=1;
//用于暂时保存字段的字符串
char str[N];
//读出的单个字符
int ch;
FILE *fin;
char Scanin[300];
while(1){
//从控制台键入输入的文件路径
printf("\nPlease input the path of file:\n");
scanf("%s",Scanin);
//判断输入的文件格式是否正确,是否存在要读取的文件
if((fin=fopen(Scanin,"r"))==NULL)
{
printf("Can't find the file wanted!");
return 1;
}
//读取第一个字符
ch=getc(fin);
//输出第一行的行号
printf("Line: %d",LineNum);
while(ch!=EOF){ //在文件结束之前
while(ch=='\n'||ch=='\r')
{
ch=getc(fin); //读取下一个字符
LineNum++; //遇到换行或者回车符号就行号加1
printf("\nLine: %d",LineNum); //输出当前行号
}
while(ch==' '||ch=='\t'||ch=='\n'||ch=='\r') ch=getc(fin); //滤过回车,换行,制表,空格
while(ch!=' '&&ch!='\n'&&ch!='\r'&&ch!='\t'&&ch!=EOF) //读取一个字段,将其以字符串形式赋值
{
str[h++]=ch;
ch=getc(fin);
}
str[h++]='\0'; //清空字符串中其余部分
if(str[0]!='\0')
{
//若字段以数字开头,则判断其是否是合法的数据类型:整数或浮点数
if(str[0]>='0'&&str[0]<='9')
{
if(isIntOrReal(str)==1) printf("\nint:\t");//是整数
else if(isIntOrReal(str)==2) printf("\nreal:\t");//是浮点数
else printf("\ninvalidNUM:\t");//不符合词法的数据类型
for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段
}
//若字段以字母开头,则判断其是否是合法的标识符
else if((str[0]>='a'&&str[0]<='z')||(str[0]>='A'&&str[0]<='Z'))
{
n=0;
//判断是否是保留字
while((n<keywordSum)&&(strcmp(str,keyword[n]))) n++;
if(n>=keywordSum)//此时不是保留字
{
if(isID(str)==1) printf("\nvalidID:\t");//符合命名规范的标识符
else printf("\ninvalidID:\t");//不符合命名规范的标识符
for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段
}
else//此时是保留字
{
printf("\nkeyword:\t");
for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段
}
}
//若以上都不是,判断其是否是特殊符号
else
{
if(isSign(str)==1) printf("\nMathemetics or Separate Symbol:\t");//是数学符号或者单分隔符
else if(isSign(str)==2) printf("\nLogic Symbol:\t");//是逻辑关系符号
else printf("\ninvalid:\t");//是不符合CMM语言文法规范的符号
for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段
}
}
h=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -