📄 ls.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define max_line 100
#define max_word 31
#define num_keyword 32
static FILE *fkeyword,*fidentifier,*flexci,*fsr;//作为外部变量
int line=1;
enum {err_zero=0,err_one,err_notdefined};
int identi_value=0;
int num_add=0;
typedef struct IDEN
{
int num;
struct IDEN * next;
char str[20];
}IDEN;
IDEN * head=NULL;
void Write_keyword(char **Reserve)//关键字写入文档
{
int i;
for(i=0;i<num_keyword;i++)
fprintf(fkeyword,"%d %s \n",i+1,Reserve[i]);
}
void Write_oper(char *s,char **arr_oper)//运算符放入文件,返回地址
{
int i;
char str[]="OPERATOR";//将其填入词法分析所得的程序中
for(i=0;i<13;i++)
if(strcmp(s,arr_oper[i])==0)
break;
fprintf(flexci,"%s",s);
}
void Write_sep(char c)//分隔符
{
char s[]="SEP";
if(c!=EOF&&c!='\n')
fprintf(flexci,"%c",c);
}
void Write_identi_to_lex(char *s,char *str,int value)//标识符写入lex,入口地址
{
char c='$';
fprintf(flexci,"%c",c);
}
int Double_or_not(char c,char **arr_oper)//运算符的操作
{
char next;
char s[3];
next=fgetc(fsr);
if(next==c)//处理==,++,--
{
s[0]=s[1]=c;
s[2]='\0';
Write_oper(s,arr_oper);
}
else if((c=='<'||c=='>'||c=='!')&&next=='=')//处理三个特殊的运算符<=,>=,!=
{
s[0]=c;
s[1]=next;
s[3]='\0';
Write_oper(s,arr_oper);
}
else
{
s[0]=c;
s[1]='\0';
Write_oper(s,arr_oper);
ungetc(next,fsr);//将fp回退一个指针
}
return 0;
}
char * Addtoken(char c, char *s)//加字符
{
int i=0;
while(s[i]!='\0') i++;
s[i]=c;
s[i+1]='\0';
return s;
}
int Seprator(char ch)//检查是否是界符
{
if(ch==','||ch=='('||ch==')'||ch==';'||ch=='#'||ch=='{'||ch=='['||ch==']'||ch=='\"')
return 1;
else if(ch=='<'||ch=='>'||ch=='.'||ch==' '||ch=='}'||ch==EOF||ch=='\n'||ch=='\''||ch=='\\')
return 1;
else
return 0;
}
int Operator(char ch)//检查是否是运算符
{
if(ch=='*'||ch=='/'||ch=='+'||ch=='-'||ch=='&'||ch=='^'||ch=='='||ch=='!'||ch=='%')
return 1;
else
return 0;
}
void Error_msg(int type)//简单的错误信息处理
{
switch(type)
{
case err_zero:printf("the file has not been opend!\n");break;//文件信息错误
case err_one:printf("the identifier is not legal in %5d line\n",line);break;
case err_notdefined:printf("undefined error int line %5d\n",line);break;//标识符不符合定义
default:break;
}
}
int Tra_ch_int_write(char *token)//将字符串转换为整数
{
FILE * fnum;
int value=0;
int i;
fnum=fopen("num.txt","a+");
if(fnum==NULL)
{
Error_msg(err_zero);
return 0;
}
for(i=0;token[i]!='\0';i++)//将字符串转换为整数
value=10*value+(int)token[i]-'0';
fprintf(fnum,"%2d %10d;\n",++num_add,value);
fclose(fnum);
return num_add;
}
int Tra_ch_float_write(char *token)//将字符串转换为浮点数
{
FILE * fnum;
float value=0;
char *pc,*p;
int val_int=0,i=-1;
pc=token;//处理浮点数的整数部分
while(*pc!='.')
pc++;
for(p=token;p<pc;p++)
val_int=10*val_int+(int)*p-'0';
p++;
while(*p!='\0')//处理浮点数的小数部分
{
value=(float)pow(10,i--)*((int)*p-'0')+value;
p++;
}
value+=val_int;
fnum=fopen("num.txt","a+");
if(fnum==NULL)
{
Error_msg(err_zero);
return 0;
}
fprintf(fnum,"%2d %8.2f\n",++num_add,value);//将数据写入常数文档
fclose(fnum);
return num_add;
}
void Digit(char c)//对数据处理
{
char ch;
char next;
char token[max_word]={'\0'};
int revalue=-1;
Addtoken(c,token);
next=fgetc(fsr);
while(isdigit(next))//浮点数的情况处理,科学计数法
{
Addtoken(next,token);//需要写函数,没有写完
next=fgetc(fsr);
}
if(next=='.')//浮点,读到小数点后所有数据形式
{
Addtoken(next,token);
next=fgetc(fsr);
while(isdigit(next))
{
Addtoken(next,token);
next=fgetc(fsr);
}
revalue=Tra_ch_float_write(token);
}
else if(isalpha(next))//错误的标识符
{
Error_msg(err_one);//非数据出错处理
while(1)//跳过一些项,直到下一个分隔符,继续处理
{
next=fgetc(fsr);
if(Seprator(next))break;
}
}
else if(Seprator(next)||Operator(next))//整数的情况
revalue=Tra_ch_int_write(token);
ungetc(next,fsr);
ch='$';
fprintf(flexci,"%c",ch);
}
int Check_iden(char *str)//检查是否是已有的标志符
{
IDEN* pid;
pid=head;
for(;pid!=NULL;pid=pid->next )
if(strcmp(str,pid->str )==0)
break;
if(pid!=NULL)
return pid->num ;
else return 0;
}
int Write_to_fidentifier(char *str)//写标识符
{
int i=0;
int checkvalue;
IDEN * newp;
checkvalue=Check_iden(str);
if(checkvalue!=0)
return checkvalue;
else
{
newp=(IDEN *)malloc(sizeof(IDEN));
newp->num =++identi_value;
strcpy(newp->str,str);
newp->next =head;
head=newp;//将新增加的标识符加入链表中
fprintf(fidentifier,"%4d %20s\n",identi_value,str);//写入标识符文件
return identi_value;
}
}
int Lookup(char *s,char **reserword)//检查是否是关键字
{
int i;
for(i=0;i<max_word;i++)
if(!strcmp(reserword[i],s))
return i+1;
return 0;
}
void Alpha(char c,char **reseword)//以字符打头的字母处理
{
char next;
char token[max_word]={'\0'};
int i=1;
int re_value,tag_re;
Addtoken(c,token);
next=fgetc(fsr);
while(isalpha(next)||isdigit(next)||next=='_')//标识符的情况处理
{
i++;
Addtoken(next,token);
next=fgetc(fsr);
}
if(!Seprator(next)&&!Operator(next)&&next!=EOF)//对结构体的.->看作是分隔符(运算符和界符)
{
Error_msg(err_notdefined);//在LEX中报错,并显示忽略一些字符
while(1)//忽视错误,继续处理
{
next=fgetc(fsr);
if(Seprator(next))break;
}
}
ungetc(next,fsr);
tag_re=Lookup(token,reseword);//是否关键字
if(tag_re!=0)
Write_identi_to_lex(token,"KEYWORD",tag_re);
else
{
re_value=Write_to_fidentifier(token);//返回地址入口,写入lex
Write_identi_to_lex(token,"IDENTIFIER",re_value);//写入词法分析程序
}
}
void Write_oper_to_txt(char **arr_oper)//将运算符写入文档
{
FILE *foper;
int i;
foper=fopen("operator.txt","w");
if(!foper)
{
Error_msg(err_one);
return ;
}
for(i=0;i<13;i++)
{
fprintf(foper,"%2d %10s\n",i+1,arr_oper[i]);
}
fclose(foper);
}
void Last_work()//对文件和动态释放的内存进行释放,回收
{
IDEN *pre;
fclose(fsr);
fclose(fidentifier);
fclose(flexci);
fclose(fkeyword);
pre=head;
while(head!=NULL)
{
head=head->next ;
free(pre);
pre=head;
}
}
void Explain(char ch,char **arr_oper)//对注释的处理
{
char next;
char token[max_word]={'\0'};
char after;
next=fgetc(fsr);
if(next=='*')//注释的情况,/* */的形式
{
next=fgetc(fsr);
after=fgetc(fsr);
while(next!='*'&&after!='/')
{
if(next=='\n')
line++;
next=after;
after=fgetc(fsr);
}
}
else if(next=='/')//单行注释的情况
{
next=fgetc(fsr);
while(next!='\n')
next=fgetc(fsr);
line++;
}
else//一般的运算
{
ungetc(next,fsr);
token[0]=ch;
token[1]='\0';
Write_oper(token,arr_oper);
}
}
void main()
{
char *Reser_word[num_keyword]={"auto","break","case","char","const","continue","default",
"do","double","else","enum","extern","float","for","goto","if","int",
"long","register","return","short","sizeof","static","struct","switch",
"typedef","union","unsigned","void","volatile","while"};
char ch,newc;
char *arr_oper[13]={"+","-","*","/","^","++","--","&&","||","!=","==","<=",">="};
Write_oper_to_txt(arr_oper);
fsr=fopen("fsr.txt","r");
fkeyword=fopen("fkeyword.txt","w");
flexci=fopen("flexci.txt","w");
fidentifier=fopen("fidentifier.txt","w");
if(fsr==NULL||fkeyword==NULL||flexci==NULL||fidentifier==NULL)
{
Error_msg(err_zero);
return ;
}
Write_keyword(Reser_word);//关键字写入关键字文件,一字一行
while(!feof(fsr))
{
ch=fgetc(fsr);
if(ch==' '||ch=='\t')
continue;
else if(ch=='\n')
{ line++;
newc='\n';
fprintf(flexci,"%c",newc);
continue;
}
else if(Operator(ch)&&ch!='/')//运算符的情况,注释的情况另外处理
Double_or_not(ch,arr_oper);
else if(Seprator(ch)&&ch!=' ')//分隔符的情况
Write_sep(ch);
else if(isdigit(ch))//常数的情况
Digit(ch);
else if(isalpha(ch))//标识符的情况
Alpha(ch,Reser_word);
else if(ch=='/')//除号的情况特殊处理,有可能是注释或乘
Explain(ch,arr_oper);
else if(ch==EOF)
printf("at the end of the file!");
else
Error_msg(err_notdefined);//出错处理,对输出格式会报错%2d
}
Last_work();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -