📄 cpp1.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
char set[100000],str[100000],strtoken[30];
char sign[50][10],constant[50][10];
char ch;
int sr,to,id=0,st=0;
void writo()
{
FILE *fp;
if((fp=fopen("analysis.txt","a"))==NULL)
{
printf("cannot write file. \n");
getch();
exit(0);
}
fputs(strtoken,fp);
fputs("\n",fp);
fclose(fp);
}
void buildfile()
{
FILE *fp;
if((fp=fopen("analysis.txt","w"))==NULL)
{
printf("cannot create file. \n");
getch();
exit(0);
}
fclose(fp);
}
typedef struct keytable /*放置关键字*/
{
char name[20];
int kind;
}
KEYTABLE;
KEYTABLE keyword[]={ /*设置关键字*/
{"void",0},
{"int",1},
{"float",2},
{"char",3},
{"if",4},
{"else",5},
{"for",6},
{"while",7},
{"do",8},
{"switch",9},
{"case",10},
{"break",11},
{"default",12},
{"return",13},
{"continue",14},
{"double",15},
{"enum",16},
{"extern",17},
{"long",18},
{"sizeof",19},
{"struct",20},
{"typedef",21},
{"union",22},
{"short",23},
{"auto",24},
{"signed",25},
{"unsigned",26},
{"union",27},
{"static",28},
{"main",29},
{"printf",30},
{"scanf",31},
};
void openfile() /*打开文件*/
{
FILE *fp;
char a,filename[10];
int n=0;
printf("Input the filename:");
gets(filename);
if((fp=fopen(filename,"r"))==NULL)
{
printf("cannot open file.\n");
getch();
exit(0);
}
else
while(!feof(fp)) /*文件不结束,则循环*/
{
a=getc(fp); /*getc函数带回一个字符,赋给a*/
set[n]=a; /*文件的每一个字符都放入set[]数组中*/
n++;
}
fclose(fp); /*关闭文件*/
set[n-1]='\0';
printf("\n=======================源代码==========================\n");
puts(set);
printf("\n=======================================================\n");
}
void reflesh() /*清空strtoken数组*/
{
to=0; /*全局变量to是strtoken的指示器*/
strcpy(strtoken," ");
}
void prearrange1() /*预处理程序1*/
{
int i,a,b,n=0;
do
{
if(set[n]=='/' && set[n+1]=='*')
{
a=n; /*记录第一个注释符的位置*/
while(!(set[n]=='*' && set[n+1]=='/'))
n++;
b=n+1; /*记录第二个注释符的位置*/
for(i=a;i<=b;i++) /**/
set[i]=' '; /*把注释的内容换成空格,等待第二步预处理*/
}
n++;
}while(set[n]!='\0');
}
void prearrange2() /*预处理程序2*/
{
int j=0;
sr=0; /*全局变量sr是str[]的指示器*/
do
{
if(set[j]==' ' || set[j]=='\n')
{
while(set[j]==' '|| set[j]=='\n') /*扫描到有连续的空格或换行符*/
j++;
str[sr]=' '; /*用一个空格代替扫描到的连续空格和换行符放入str[]*/
sr++;
}
else
{
str[sr]=set[j]; /*若当前字符不为空格或换行符就直接放入str[]*/
sr++;
j++;
}
}while(set[j]!='\0');
str[sr]='\0';
}
char getachar() /*把字符读入全局变量ch中,指示器sr前移*/
{
ch=str[sr];
sr++;
return(str[sr-1]);
}
void getbc() /*开始读入符号,直至第一个不为空格*/
{
while(ch==' ')
{
ch=getachar();
}
}
void conacat() /*把ch中的字符放入strtoken[]*/
{
strtoken[to]=ch;
to++; /*全局变量to是strtoken的指示器*/
strtoken[to]='\0';
}
int isletter() /*判断是否为字母*/
{
if((ch>=65 && ch<=90)||(ch>=97 && ch<=122))
return(1);
else return(0);
}
int isdigit() /*判断是否为数字*/
{
if(ch>=48 && ch<=57)
return(1);
else return(0);
}
int raserve() /*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/
{
int i,k=0;
for(i=0;i<=30;i++)
{
if(strcmp(strtoken,keyword[i].name)==0)
{ k=1;
return(keyword[i].kind);
}
}
if(k!=1)
return(-1);
}
void retur() /*指示器sr回调一个字符位置,把ch置为空*/
{
sr--;
ch=' ';
}
void analysis()
{
int value;
reflesh(); /*清空strtoken数组*/
prearrange1(); /*预处理,使注释内容换成单个空格,放回set[]中*/
prearrange2(); /*预处理,使set[]中连续的空格置换成单个空格,并把set[]的内容放到str[]中*/
sr=0;
getachar();
getbc(); /*读取第一个字符*/
while(ch!='\0') /*当不等于结束符,继续执行*/
{
if(isletter() || ch=='_')
{
while(isletter() || isdigit() || ch=='_') /*若第一个是字符,继续读取,直到出现空格*/
{
conacat();
getachar();
}
if(ch=='.')
{
conacat();getachar();
while(isletter() || isdigit())
{
conacat();
getachar();
}
}
retur(); /*指示器sr回调一个字符位置,把ch置为空*/
value=raserve(); /*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/
if(value==-1) /*如果返回值是-1,那就是变量,把它输出*/
{
writo();
printf("\n'%s':2'",strtoken);
getch();
}
else /*否则就是关键字,也输出*/
{
writo();
printf("\n'%s' : 1",strtoken);
getch();
}
reflesh();
}
else if(isdigit())
{
while(isdigit()) /*否则,若第一个是数字,继续读取,知道出现空格*/
{
conacat();
getachar();
}
if(ch=='.')
{
conacat();
getachar();
while(isdigit())
{
conacat();
getachar();
}
}
retur();
writo();
printf("\n'%s':3",strtoken);
getch();
reflesh();
}
else
switch(ch) /*否则,若是下面的符号,就直接把它输出*/
{
case ',':
case ';':
case '(':
case ')':
case '{':
case '}':
case '[':
case ']':
case '~':
case '#':
case ':':
case '^':
case '"':
case '.':
{
conacat();
writo();
printf("\n'%s':5",strtoken);
getch();
reflesh();
break;
}
default:
{
if(ch==' ') break;
else if(ch=='&' || ch=='|' ) /*如果是这些符号,继续读取下一个*/
{
conacat(); /*判断是否为&&,||的情况*/
getachar();
if(ch==strtoken[0])
conacat();
else
retur();
writo();
printf("\n'%s':4",strtoken);
getch();
reflesh();
break;
}
else if( ch=='*' || ch=='%' || ch=='/') /*如果是这些符号,继续读取下一个*/
{
conacat(); /*判断是否为/=,*=,%=的情况*/
getachar();
if(ch=='=')
conacat();
else
retur();
writo();
printf("\n'%s:4'",strtoken);
getch();
reflesh();
break;
}
else if(ch=='+' ) /*如果是这些符号,继续读取下一个*/
{
conacat(); /*判断是否为+=,++,+的情况*/
getachar();
switch(ch)
{
case '=':{
conacat();
writo();
printf("\n'%s:4'",strtoken);
getch();
reflesh();
break;
}
case '+':{
conacat();
writo();
printf("\n'%s:4'",strtoken);
getch();
reflesh();
break;
}
default:{
retur();
writo();
printf("\n'%s':4",strtoken);
getch();
reflesh();
break;
}
}
break;
}
else if(ch=='-') /*如果是这些符号,继续读取下一个*/
{
conacat();
getachar();
switch(ch) /*判断是否为-=,--,-的情况*/
{
case '=':{
conacat();
writo();
printf("\n'%s:4'",strtoken);
getch();
reflesh();
break;
}
case '-':{
conacat();
writo();
printf("\n'%s:4'",strtoken);
getch();
reflesh();
break;
}
default:{
retur();
writo();
printf("\n'%s':4",strtoken);
getch();
reflesh();
break;
}
}
break;
}
else if(ch=='<') /*如果是这些符号,继续读取下一个*/
{
conacat();
getachar();
switch(ch) /*判断是否为<<,<=,<的情况*/
{
case '=':{
conacat();
writo();
printf("\n'%s:6'",strtoken);
getch();
reflesh();
break;
}
case '<':{
conacat();
writo();
printf("\n'%s:4'",strtoken);
getch();
reflesh();
break;
}
default:{
retur();
writo();
printf("\n'%s':6",strtoken);
getch();
reflesh();
break;
}
}
break;
}
else if(ch=='>') /*如果是这些符号,继续读取下一个*/
{
conacat();
getachar();
switch(ch) /*判断是否为>>,>=,>的情况*/
{
case '=':{
conacat();
writo();
printf("\n'%s':6",strtoken);
getch();
reflesh();
break;
}
case '>':{
conacat();
writo();
printf("\n'%s':4",strtoken);
getch();
reflesh();
break;
}
default:{
retur();
writo();
printf("\n'%s:6'",strtoken);
getch();
reflesh();
break;
}
}
break;
}
else if(ch=='=' || ch=='!' ) /*如果是这些符号,继续读取下一个*/
{
conacat(); /*判断是否为==,!=的情况*/
getachar();
if(ch==strtoken[0])
conacat();
else
retur();
writo();
printf("\n'%s':4",strtoken);
getch();
reflesh();
break;
}
else
{
break;
}
}
}
getachar();
getbc();
}
}
main()
{
buildfile();
openfile();
analysis();
printf("\n词法分析完毕 !");
printf("\n词法分析结果已保存在analysis.txt中\n");
getch();
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -