📄 词法分析设计.cpp
字号:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define ID 12 //标识符
#define INT 13 //无符号整数
#define SIN 14 //单字符分界符
#define DOU 15 //双字节分界符
#define LT 16 //小于
#define EQ 17 //等于
#define GT 18 //大于
#define COLON 19 //冒号
#define SLASH 20 //斜竖
#define NULL 0
char *key[11]={"begin","end","if","then","else",
"for","do","while","and","or","not"}; //11个保留字,类别编码为1-11
char TOKEN[20]; //最大扫描字符数为20个
FILE *fp,*fp1;
int lookup(char);
void out(int,char);
void report_error(char);
void scanner_example(FILE*);
int lookup(char* ch)
//以TOKEN中的字符串查保留字表,若查到,就返回相应关键字的类别码,否则返回0
{
int i=0,j=0,len1=0,len2=0;
len1=strlen(ch);
for(i=0;i<11;i++) //查保留字表,大小写不敏感
{
len2=strlen(key[i]);
if(len1==len2)
{
for(j=0;j<len1;j++)
{
if((*(key[i]+j)-*(ch+j))==0||(*(key[i]+j)-*(ch+j))==32) //与保留关键字的每个字母进行比较
{continue;}
else goto label;
}
return (i+1);
}
label:continue;
}
return(0);
}
void out(int a,char* ch)
//输出二元式写到result中
{
fp1=fopen("result.txt","a");
fprintf(fp1,"(%d,%s)\n",a,ch);
}
void report_error(char ch)
//报告错误
{
if(ch!='\n')
printf("the letter '%c' is wrong,please check it out!\n",ch);
}
void scanner_example(FILE* fp)
//对扫描到的字母进行分析
{
char ch;
int i,c;
while(ch!=EOF){
ch=fgetc(fp);
if(isalpha(ch)) //对读到的首字母是a-z、A-Z的情况的分析
{
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isalnum(ch))
{
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
fseek(fp,-1,1);
c=lookup(TOKEN); //与关键字表进行匹配,匹配上返回关键字码,匹配不上返回零
if(c==0)
out(ID,TOKEN); // out(int a,char* ch) 将结果写到result 中
else
out(c,TOKEN);
}
else
if(isdigit(ch)) //对首字母是数字的情况的分析
{
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isdigit(ch))
{
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
fseek(fp,-1,1);
out(INT,TOKEN); //类别码+字符
}
else
switch(ch) //对其他情况的分析
{
case '+':out(SIN,"+");break;
case '-':out(SIN,"-");break;
case '*':ch=fgetc(fp);
if(ch=='/')
out(DOU,"*/");
else
{
fseek(fp,-1,1);
out(SIN,"*");
}
break;
case ';':out(SIN,";");break;
case '(':out(SIN,"(");break;
case ')':out(SIN,")");break;
case '<':ch=fgetc(fp);
if(ch=='=')
out(DOU,"<=");
else if(ch=='>')
out(DOU,"<>");
else
{
fseek(fp,-1,1);
out(LT,"<");
}
break;
case '=':out(EQ,"=");break;
case '>':ch=fgetc(fp);
if(ch=='=')
out(DOU,">=");
else
{
fseek(fp,-1,1);
out(GT,">");
}
break;
case ':':ch=fgetc(fp);
if(ch=='=')
out(DOU,":=");
else
{
fseek(fp,-1,1);
out(COLON,":");
}
break;
case '/':ch=fgetc(fp);
if(ch=='*')
{
out(DOU,"/*");
ch=fgetc(fp);
while(ch!=EOF) //对于注释部分不进行分析
{
if(ch=='*'&&fgetc(fp)=='/')
{
out(DOU,"*/");
break;
}
else
ch=fgetc(fp);
}
}
else
{
fseek(fp,-1,1);
out(SLASH,"/");
}
break;
default:if(ch!=' '&&ch!=EOF)
report_error(ch); //如果所扫描的字符不包括在所规定的语言单词符号中,则报告错误
break;
}
}
return;
}
void main()
{
if((fp=fopen("test.txt","r"))==NULL) //读取文件失败
printf("读取文件失败!\n");
else{
scanner_example(fp);
printf("程序运行完毕!请查看result文件.\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -