📄 词法分析程序.cpp
字号:
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# define LENGTH 61
# define N 100
/*******************************************************/
typedef struct token{
int label;
char name[30];
int code;
int addr;
}token;
typedef struct KeyWord{
char name[30];
int code;
}KeyWord;
typedef struct symble{
int number;
int type;
char name[30];
}symble;
/****************************************************/
char ch;
int var_count;
int error_count;
int label_count;
int code_count;
int addr_count;
int LineOfPro;
char filename[30];
FILE *KeyFin;
FILE *SourceFin;
FILE *TokenFout;
FILE *SymbleFout;
KeyWord key[LENGTH];
token CurrentToken;
symble CurrentSimble;
symble SymbleList[N];
/*****************************************************/
void Scanner();
void ScannerInit();
void IsAlpha();
void IsNumber();
void IsAnotation();
void IsChar();
void IsOther();
void OutPut();
void Error(int a);
int WordHave();
int strcmp(char *s,char *t) {
for(;*s==*t;s++,t++)
if(*s==0)return 0;
return 1;
}
/*****************************************************/
int main(){
int i=0,j=0;
code_count=0;
LineOfPro=0;
var_count=0;
addr_count=1;
label_count=1;
for(i=0;i<N;i++){
SymbleList[i].number=0;
SymbleList[i].type=0;
for(j=0;j<30;j++) SymbleList[i].name[j]='\0';
}
Scanner();
return 0;
}
/*************************************************/
void Scanner(){
int i=0;
error_count=0;
ScannerInit();
printf("*************************************************\n");
printf(" 语言词法分析器\n");
printf("*************************************************\n");
printf("输入源文件名:");
for(;;){
scanf("%c",&filename[i]);
if(filename[i]==10) break;
i++;
}
filename[i]='\0';
if((SourceFin=fopen(filename,"rt"))==NULL){
printf("无法打开文件 %s.\n",filename);
exit(1);
}
if((TokenFout=fopen("token.txt","wt+"))==NULL){
printf("无法打开文件 token.txt.\n");
exit(1);
}
if((SymbleFout=fopen("symble.txt","wt+"))==NULL){
printf("无法打开文件 symble.txt.\n");
exit(1);
}
ch=fgetc(SourceFin);
while(ch!=EOF){
for(i=0;i<30;i++)
CurrentToken.name[i]='\0';
if((ch>47)&&(ch<58))
IsNumber();
else{
if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_')
IsAlpha();
else{
if(ch=='/') IsAnotation();
else if(ch=='\'') IsChar();
else IsOther();
}
}
}
fclose(SourceFin);
fclose(TokenFout);
fclose(SymbleFout);
printf("分析完毕.\n");
}
/*********** 初始化 ********************************/
void ScannerInit() {
if((KeyFin=fopen("ni.txt","rt"))==NULL)
{printf("cannot open ni.txt.\n");
exit(1);
}
for(int i=0;i<60;i++)for(int k=0;k<30;k++)key[i].name[k]='\0';
for(i=1;i<60;i++){ /*读入编码表*/
fscanf(KeyFin,"%s %d",key[i].name,&key[i].code);
}
fclose(KeyFin);
}
/***********************************数字处理*************/
void IsNumber(){
int k=0;
int flag=0;
char ch1;
while(((ch>47)&&(ch<58))){
CurrentToken.name[k++]=ch;
ch=fgetc(SourceFin);
if(ch=='.'){flag=1;break;}
}
CurrentToken.code=28;
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
if(flag){
ch1=fgetc(SourceFin);
if((ch1>47)&&(ch1<58)) CurrentToken.name[k++]=ch;
else Error(2);
ch=ch1;
while((ch>47)&&(ch<58)){
CurrentToken.name[k++]=ch;
ch=fgetc(SourceFin);
}
CurrentToken.code=29;
if(ch=='.'){
Error(2);
ch=fgetc(SourceFin);
while((ch>47)&&(ch<58)) ch=fgetc(SourceFin);
}
if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))){
Error(2);
while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))){
ch=fgetc(SourceFin);
while((ch>47)&&(ch<58)) ch=fgetc(SourceFin);
}
}
}
OutPut();
}
/**************字母处理*********************/
void IsAlpha(){
int i,h;
h=0;i=0;
while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_'){
CurrentToken.name[i++]=ch;
ch=fgetc(SourceFin);
}
for(i=1;i<LENGTH;i++){ /*判断输入字符是否为保留字*/
h=strcmp(CurrentToken.name,key[i].name);
if(!h) break;
}
if(!h){
CurrentToken.code=key[i].code;
CurrentToken.addr=-1;
}
else{
CurrentToken.code=27;
CurrentToken.addr=addr_count++;
}
CurrentToken.label=label_count++;
OutPut();
}
/*******************注释处理*********************/
void IsAnotation(){
char ch1;
ch1=ch;
ch=fgetc(SourceFin);
if(ch=='*') for(;;){ch=fgetc(SourceFin);
if(ch==EOF){Error(3);break;}
if(ch=='*'){
ch1=ch;
ch=fgetc(SourceFin);
if(ch=='/'){ch=fgetc(SourceFin);break;}
}
}
else{
CurrentToken.name[0]='/';
CurrentToken.code=39;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
}
/***************字符串处理*******************/
void IsChar(){
int i=0;
for(;;){
ch=fgetc(SourceFin);
CurrentToken.code=30;
if(ch!='\'')CurrentToken.name[i++]=ch;
else break;
}
CurrentToken.addr=addr_count++;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
}
/******************其他情况处理****************/
void IsOther(){
char ch1;
int i;
for(i=0;i<30;i++) CurrentToken.name[i]='\0';
switch(ch){
case '(':CurrentToken.name[0]='(';
CurrentToken.code=32;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ')':CurrentToken.name[0]=')';
CurrentToken.code=33;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '*':CurrentToken.name[0]='*';
CurrentToken.code=34;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '+':CurrentToken.name[0]='+';
CurrentToken.code=35;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ',':CurrentToken.name[0]=',';
CurrentToken.code=37;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '-':CurrentToken.name[0]='-';
CurrentToken.code=36;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '.':CurrentToken.name[0]='.';
CurrentToken.code=38;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case ':':ch1=ch;
ch=fgetc(SourceFin);
if(ch!='='){
CurrentToken.name[0]=':';
CurrentToken.code=40;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
else{
CurrentToken.name[0]=':';
CurrentToken.name[1]='=';
CurrentToken.code=41;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
}
break;
case ';':CurrentToken.name[0]=';';
CurrentToken.code=42;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '<':ch1=fgetc(SourceFin);
if(ch1=='='){
CurrentToken.name[0]='<';
CurrentToken.name[1]='=';
CurrentToken.code=44;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
if(ch1=='>'){
CurrentToken.name[0]='<';
CurrentToken.name[1]='>';
CurrentToken.code=45;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
CurrentToken.name[0]='<';
CurrentToken.code=43;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
}
ch=ch1;
break;
case '=':CurrentToken.name[0]='=';
CurrentToken.code=46;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch=fgetc(SourceFin);
break;
case '>':ch1=fgetc(SourceFin);
if(ch1=='='){
CurrentToken.name[0]='>';
CurrentToken.name[1]='=';
CurrentToken.code=48;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
ch1=fgetc(SourceFin);
}
else{
CurrentToken.name[0]='>';
CurrentToken.code=47;
CurrentToken.addr=-1;
CurrentToken.label=label_count++;
OutPut();
}
ch=ch1;
break;
case 10:LineOfPro++;
ch=fgetc(SourceFin);
break;
case 13:LineOfPro++;
ch=fgetc(SourceFin);
break;
case ' ':ch=fgetc(SourceFin);
break;
case EOF:Error(4);break;
default :Error(1);ch=fgetc(SourceFin);
break;
}
}
/****************输出模块******************/
void OutPut(){
int flag,i=0;
int k;
/*查看符号表*/
if((CurrentToken.code==27)||(CurrentToken.code==30)||(CurrentToken.code==28)||(CurrentToken.code==29)){
CurrentSimble.number=CurrentToken.addr;
CurrentSimble.type=CurrentToken.code;
strcpy(CurrentSimble.name,CurrentToken.name);
flag=WordHave();
if(((CurrentToken.code==27)&&(flag==1))||(CurrentToken.code==30)||(CurrentToken.code==28)||(CurrentToken.code==29))
fprintf(SymbleFout,"%3d %3d %s\n",CurrentSimble.number,CurrentSimble.type,CurrentSimble.name);
}
/*输出到token表*/
for(;;) if(CurrentToken.name[i++]=='\0') break;
fprintf(TokenFout,"%3d %s",CurrentToken.label,CurrentToken.name);
printf("%3d %s",CurrentToken.label,CurrentToken.name);
for(k=20-i;k>0;k--){fprintf(TokenFout," ");printf(" ");}
fprintf(TokenFout,"%3d %3d\n",CurrentToken.code,CurrentToken.addr);
printf("%3d %3d\n",CurrentToken.code,CurrentToken.addr);
}
/**************出错处理***************/
void Error(int a){
error_count++;
switch(a){
case 1:printf("error %2d 非法字符于 %3d 行.\n",error_count,LineOfPro+1);break;
case 2:printf("error %2d 实常数出错于 %3d 行.\n",error_count,LineOfPro+1);break;
case 3:printf("error %2d 没有匹配的注释符 '*/' \n",error_count);break;
case 4:printf("error %2d 非正常结束! \n",error_count);break;
default :break;
}
return;
}
int WordHave(){
int flag,i=0;
for(i=0;i<var_count;i++){
flag=strcmp(CurrentSimble.name,SymbleList[i].name);
if(flag==0){
CurrentToken.addr=SymbleList[i].number;
return 0;
}
}
SymbleList[var_count].number=CurrentToken.addr;
SymbleList[var_count].type=CurrentToken.code;
strcpy(SymbleList[var_count].name,CurrentToken.name);
var_count++;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -