📄 词法分析.c
字号:
#include "stdio.h"
#include "conio.h"
#define NOL 500
#define NUL '\0'
#define LENGTH 200
FILE *fp1,*fp2;
int row=1; /*row表示行号*/
int first_of_series=0; /*first_of_series表示连续空格或者TAB的第一个的标记,0表示不是,1则是*/
char ch;
int symbol=0; /*symbol=0表示此位不是符号位,1表示是*/
int more=1; /*more=1表示运行到结束符还可以再多循环一次*/
int list_separator=0; /*如果list_separator=0表示cache[0]不是分隔符、运算符、空格或者TAB,1表示是,2表示已经不是每行第一个字符*/
char cache[NOL]; /*缓冲区*/
char string[LENGTH]; /*缓冲区中2间隔符间的字符串*/
int i;
int p=0;
char c1='\0'; /*c1记录第一个运算符号,'\0'表示还没记录*/
char c;
int left=0; /*left表示单词左边的分隔符,为0表示单词左边还没有分隔符*/
int right=0; /*right表示单词右边的分隔符,为0表示单词右边还没有分隔符*/
int leftnumber=999; /*leftnumber记录左边分隔符在缓冲区中的下标*/
int rightnumber=999; /*rightnumber记录右边分隔符在缓冲区中的下标*/
/*********************************************************/
void strncopy(char *str1,char *str2,int n,int front) /*以front为开头下标的n个字符串str2复制str1串的前n个位置*/
{
int k;
if(n==0) return;
for(k=0;k<n;k++)
{
str1[k]=str2[front+k];
}
}
/*********************************************************/
void initialization_string()
{
int k;
for(k=0;k<LENGTH;k++)
{
string[k]=NUL;
}
}
/*********************************************************/
void initialization_cache() /*对存储行元素的缓冲区初始化*/
{
int k;
for(k=0;k<NOL;k++)
{
cache[k]=NUL;
}
}
/*********************************************************/
void cmpkwd()
{
int t;
if(left==0)
{
left=1;
leftnumber=p;
}
else if(right==0)
{
right=1;
rightnumber=p;
strncopy(string,cache,rightnumber-leftnumber-1,leftnumber+1);
if(strcmp(string,"if")==0)
{fprintf(fp2,"<①, if>━━━━━━%d行\n",row);printf("<①, if>━━━━━━%d行\n",row);}
else
if(strcmp(string,"int")==0)
{fprintf(fp2,"<①, int>━━━━━━%d行\n",row);printf("<①, int>━━━━━━%d行\n",row);}
else
if(strcmp(string,"for")==0)
{fprintf(fp2,"<①, for>━━━━━━%d行\n",row);printf("<①, for>━━━━━━%d行\n",row);}
else
if(strcmp(string,"while")==0)
{fprintf(fp2,"<①, while>━━━━━━%d行\n",row); printf("<①, while>━━━━━━%d行\n",row);}
else
if(strcmp(string,"do")==0)
{fprintf(fp2,"<①, do>━━━━━━%d行\n",row);printf("<①, do>━━━━━━%d行\n",row);}
else
if(strcmp(string,"return")==0)
{fprintf(fp2,"<①, return>━━━━━━%d行\n",row);printf("<①, return>━━━━━━%d行\n",row);}
else
if(strcmp(string,"break")==0)
{fprintf(fp2,"<①, break>━━━━━━%d行\n",row);printf("<①, break>━━━━━━%d行\n",row);}
else
if(strcmp(string,"continue")==0)
{fprintf(fp2,"<①, continue>━━━━━━%d行\n",row);printf("<①, continue>━━━━━━%d行\n",row);}
else
if((string[0]>='0')&&(string[0]<='9'))
{
fprintf(fp2,"<③, ");printf("<③, ");
for(t=0;t<strlen(string);t++)
{
fprintf(fp2,"%c",string[t]);printf("%c",string[t]);
}
fprintf(fp2,">━━━━━━%d行\n",row);printf(">━━━━━━%d行\n",row);
if(symbol==0)
{
rightnumber=rightnumber-1; /*若是数字串后面紧接着标识符*/
}
}
else
{
fprintf(fp2,"<②, ");printf("<②, ");
for(t=0;t<strlen(string);t++)
{
fprintf(fp2,"%c",string[t]);printf("%c",string[t]);
}
fprintf(fp2,">━━━━━━%d行\n",row);printf(">━━━━━━%d行\n",row);
}
initialization_string();
right=0;
leftnumber=rightnumber;
rightnumber=999;
}
}
/*********************************************************/
void analyseline()
{
list_separator=0;
p=0;
left=0;
right=0;
leftnumber=999;
rightnumber=999;
c1='\0';
more=1;
first_of_series=0;
while(((c=cache[p])!=NUL)||(more==1))
{
symbol=0;
if(leftnumber==(strlen(cache)-1))
{
break;
}
if(cache[p]==NUL)
{
more=0;
c=' ';
}
if((c=='/')&&(cache[p+1]=='*')) /*屏蔽掉注释*/
{
break;
}
if((c!=' ')&&(c!=9)) /*字符如果不等于空格或者tab*/
{
switch(c)
{
case ',': ;
case ';': ;
case '{': ;
case '}': ;
case '(': ;
case ')':
symbol=1;
cmpkwd();
fprintf(fp2,"<⑤, %c>━━━━━━%d行\n",c,row);printf("<⑤, %c>━━━━━━%d行\n",c,row);c1='\0';
if(p==0)
{
list_separator=1;
}
if(c1!='\0')
{
fprintf(fp2,"<④, %c>━━━━━━%d行\n",c1,row);printf("<④, %c>━━━━━━%d行\n",c1,row); c1='\0';
}
p++;break;
case '+': ;
case '-': ;
case '*': ;
case '/': ;
case '=': ;
case '<': ;
case '>': ;
case '!':
symbol=1;
if(c1=='\0')
{
c1=c;
if(p==0)
{
list_separator=1;
}
}
else /*如果前一个是运算符号,则说明是双符运算符*/
{
fprintf(fp2,"<④, %c%c>━━━━━━%d行\n",c1,c,row);printf("<④, %c%c>━━━━━━%d行\n",c1,c,row); c1='\0';
if(p==0)
{
list_separator=1;
}
}
if(leftnumber==(p-1))
{
leftnumber=p;
}
else
{
cmpkwd();
}
p++;
break;
default:
if(c1!='\0')
{
fprintf(fp2,"<④, %c>━━━━━━%d行\n",c1,row);printf("<④, %c>━━━━━━%d行\n",c1,row); c1='\0';
}
if(list_separator==0)
{
list_separator=2;left=1;leftnumber=p-1;
}
if((cache[p-1]>='0')&&(cache[p-1]<='9')&&((cache[p]<'0')||(cache[p]>'9')))
{
cmpkwd();
}
p++;
}
}
else
{
if(((c==' ')||(c==9))&&((cache[p-1]==' ')||(cache[p-1]==9)))
{
first_of_series=1;
}
if(((c==' ')||(c==9))&&((cache[p+1]==' ')||(cache[p+1]==9))) /*如果此位是空格或者tab并且下一位也一样的话,则跳过*/
{
if((left==1)&&(first_of_series=1)&&(leftnumber!=(p-1)))
{
cmpkwd();
first_of_series=0;
}
left=1;
leftnumber=p;
p++;
continue;
}
if(c1!='\0')
{
fprintf(fp2,"<④, %c>━━━━━━%d行\n",c1,row);printf("<④, %c>━━━━━━%d行\n",c1,row); c1='\0';
}
if(p==0)
{
list_separator=1;
}
cmpkwd();
p++;
}
}
}
/*********************************************************/
void main()
{
char file_in[20],file_out[20];
printf("input source file:");
scanf("%s",file_in);
if((fp1=fopen(file_in,"r"))==NUL) /*打开文件*/
{
printf("can not open the file");
getch();
exit(0);
}
printf("input the outfile:");
scanf("%s",file_out);
if((fp2=fopen(file_out,"w"))==NUL)
{
printf("can not open the file");
getch();
exit(0);
}
i=0;
while(!feof(fp1))
{
if(EOF==fscanf(fp1,"%c",&ch))
{
analyseline();
break;
}
else if(ch!=10)
{
cache[i]=ch;
i++;
}
else
{
analyseline();
initialization_cache(); /*重置缓冲区*/
row++;
i=0; /*重新再读一行*/
}
}
fclose(fp1);
fclose(fp2);
getch();
}
/*********************************************************/
/*********************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -