📄 checkopenfiles.c
字号:
/* Note:Your choice is C IDE */
#include "stdio.h"
#include "string.h"
#include "malloc.h"
#include "my_conio.h"
//全局变量定义
FILE *fp_source;//源文件
FILE *fp_output;//输出文件
char DoubleOperand[3];//长度为2的运算符的第一个字符集合
int wordCount=35;//单词编码个数
int doubleop_count=3;
int code_ident=17;//标示符
int code_const=18;//常数
int code_crlf=35;//回车
int line_count=1;//行计数器
int word_count=0;//字符计数器
typedef struct //单词编码数据结构
{
char name[20];
int type;
}WORDITEM;
typedef struct //输出项数据结构
{
char name[50];
int type;
}OUTITEM;
WORDITEM p_wordlist[35]; //定义单词编码数组
#define BUFFERSIZE 100
typedef struct //缓冲队列数据结构
{
char data[BUFFERSIZE];
int front,rear;
}BUFFERQUEUE;
BUFFERQUEUE bufferqueue;
int empty(BUFFERQUEUE *bq) //判空
{
if(bq->rear==bq->front)
return 1;
else
return 0;
}
int enqueue(BUFFERQUEUE *bq,char x) //入队
{
int r;
if(bq->front==(bq->rear+1)%BUFFERSIZE)
{
r=0;
}
else
{
bq->rear=(bq->rear+1)%BUFFERSIZE;
(bq->data)[bq->rear]=x;
r=1;
}
return r;
}
char dequeue(BUFFERQUEUE *bq) //出队
{
char v;
if(empty(bq))
{
v=NULL;
}
else
{
bq->front=(bq->front+1)%BUFFERSIZE;
v=(bq->data)[bq->front];
}
return v;
}
void LoadFileToBuffer(FILE *fp) //加载文件内容至缓冲队列
{
char readchar;
int eof_f;
eof_f=feof(fp);
while(eof_f!=16)
{
fread(&readchar,sizeof(char),1,fp);
if(enqueue(&bufferqueue,readchar)==0)
{
fseek(fp,-1,1); //回退一个字符
break;
}
eof_f=feof(fp);
//发现每次文件结尾处的缓冲队列总是多读入一个相同的字符
if(eof_f==16)
{
if(bufferqueue.rear!=0)
bufferqueue.rear-=1;
else
bufferqueue.rear=BUFFERSIZE-1;
}
}
}
char ReadBuffer(FILE *fp) //取缓冲队列中的一个字符
{
if(empty(&bufferqueue))
{
LoadFileToBuffer(fp);
}
return dequeue(&bufferqueue);
}
void backfront(BUFFERQUEUE *bq) //回退操作
{
//if(empty(&bufferqueue)!=1)
//{
if(bq->front!=0)
bq->front-=1;
else
bq->front=BUFFERSIZE-1;
//}
}
int BufferEmpty()
{
return empty(&bufferqueue);
}
//打开文件指针
int checkOpenFiles(int count,char** vars)
{
fp_source=fopen("test.pas","rb");
fp_output=fopen("output","wb");
return 0;
if(count!=3)
{
printf("错误:请将参数输入完整\n");
return 4;
}
else
{
if((fp_source=fopen(vars[1],"rb"))==NULL)
{
printf("错误:不能打开源程序文件\n");
return 1;
}
if((fp_output=fopen(vars[2],"wb"))==NULL)
{
printf("错误:不能打开单词输出文件\n");
return 2;
}
return 0;
}
}
//初始化
void initiate()
{
int i;
strcpy(p_wordlist[0].name,"program");
strcpy(p_wordlist[1].name,"var");
strcpy(p_wordlist[2].name,"procedure");
strcpy(p_wordlist[3].name,"begin");
strcpy(p_wordlist[4].name,"end");
strcpy(p_wordlist[5].name,"if");
strcpy(p_wordlist[6].name,"then");
strcpy(p_wordlist[7].name,"else");
strcpy(p_wordlist[8].name,"while");
strcpy(p_wordlist[9].name,"do");
strcpy(p_wordlist[10].name,"for");
strcpy(p_wordlist[11].name,"step");
strcpy(p_wordlist[12].name,"until");
strcpy(p_wordlist[13].name,"call");
strcpy(p_wordlist[14].name,"read");
strcpy(p_wordlist[15].name,"write");
strcpy(p_wordlist[16].name,"ident");
strcpy(p_wordlist[17].name,"const");
strcpy(p_wordlist[18].name,"+");
strcpy(p_wordlist[19].name,"-");
strcpy(p_wordlist[20].name,"*");
strcpy(p_wordlist[21].name,"/");
strcpy(p_wordlist[22].name,":=");
strcpy(p_wordlist[23].name,"=");
strcpy(p_wordlist[24].name,"<>");
strcpy(p_wordlist[25].name,">");
strcpy(p_wordlist[26].name,">=");
strcpy(p_wordlist[27].name,"<");
strcpy(p_wordlist[28].name,"<=");
strcpy(p_wordlist[29].name,"(");
strcpy(p_wordlist[30].name,")");
strcpy(p_wordlist[31].name,",");
strcpy(p_wordlist[32].name,";");
strcpy(p_wordlist[33].name,".");
strcpy(p_wordlist[34].name,"\n");
for(i=0;i<35;i++)
{
p_wordlist[i].type=i+1;
}
DoubleOperand[0]=':';
DoubleOperand[1]='<';
DoubleOperand[2]='>';
}
void Retract() //回退一个字符
{
word_count--;
backfront(&bufferqueue);
}
char getChar(FILE *fp) //从缓冲区内读取一个字符
{
word_count++;
return ReadBuffer(fp);
}
void trim_bc(char *ch,FILE *fp) //清除空白字符
{
if(*ch==' ' || *ch=='\t')
{
if(*ch=='\t') word_count+=7;
while(((*ch=getChar(fp))==' ')||*ch=='\t')
{
if(*ch=='\t')
word_count+=7;
}
}
}
int lookupwordlist(char *word) //在单词编码表中查找关键字或操作符
{
int loop_i;
for(loop_i=0;loop_i<wordCount;loop_i++)
{
if(strcmp(word,(p_wordlist+loop_i)->name)==0)
return (p_wordlist+loop_i)->type;
}
return 0;
}
int isLetter(char ch)
{
if((ch>=65 && ch<=90) || (ch>=97 && ch <=122))
return 1;
else
return 0;
}
int isDigit(char ch)
{
if(ch>=48 && ch<=57)
return 1;
else
return 0;
}
int isdoubleop(char ch) //是否为两个字符操作符的首符,如:=中的:,<>中的<,>=中的>
{
int loop_i;
for(loop_i=0;loop_i<doubleop_count;loop_i++)
{
if(*(DoubleOperand+loop_i)==ch)
return 1;
}
return 0;
}
int lookupoperand(char ch) //查找单个字符的操作符
{
char tmp[2]={ch,'\0'};
return lookupwordlist(tmp);
}
void Concat(char ch,char *str) //连接字符串
{
int len=strlen(str);
*(str+len)=ch;
}
void out_screen_pause(char *str,int code)
{
static int screen_count=1;
if(screen_count>19)
{
printf("按任意键继续...");
getch();
clrscr(); //此函数最终调用WINAPI实现清除Console的屏幕
screen_count=0;
}
printf("{%s,%d}\n",str,code);
screen_count++;
}
void outword(char *str,int code,FILE *fp) //输出单词
{
static OUTITEM out_item; //定义为static,一是可以用默认值初始化char[],二是此函数会被多次调用,static可以只分配一次空间
strcpy(out_item.name,str);
out_item.type=code;
fwrite(&out_item,sizeof(OUTITEM),1,fp);
out_screen_pause(str,code);
}
void error_screen(char *msg,char ch)
{
printf(msg,ch);
printf("行:%d, 列:%d\n",line_count,word_count);
}
void error(char *msg,char ch) //出错处理
{
error_screen(msg,ch);
}
void scan(FILE *fp,FILE *fp_out) //拼读一个单词
{
char strToken[33]="";
char ch=getChar(fp);
int code;
trim_bc(&ch,fp);
if(isLetter(ch)) //字母开头
{
while(isLetter(ch) || isDigit(ch))
{
Concat(ch,strToken);
ch=getChar(fp);
}
if(ch!=0) //如果读出来的字符为0,则说明缓冲区为空并且文件已经结束了
{
Retract();
code=lookupwordlist(strToken);
if(code!=0)
{
outword(strToken,code,fp_out);
}
else
{
code=code_ident;
outword(strToken,code,fp_out);
}
}
}
else if(isDigit(ch)) //数字开头
{
while(isDigit(ch))
{
Concat(ch,strToken);
ch=getChar(fp);
}
if(ch!=0)
{
Retract();
outword(strToken,code_const,fp_out);
}
}
else if(doubleop_count!=0 && isdoubleop(ch))
{
char second;
Concat(ch,strToken);
second=getChar(fp);
if(ch!=0)
{
Concat(second,strToken);
if(code=lookupwordlist(strToken))
{
outword(strToken,code,fp_out);
}
else if(code==lookupoperand(ch))
{
char tmp[2]={ch,'\0'};
outword(tmp,code,fp_out);
Retract();
}
else
{
//error
error("错误:遇到非法运算符 \"%c\"\n",ch);
Retract();
}
}
}
else if(code=lookupoperand(ch))
{
char tmp[2]={ch,'\0'};
outword(tmp,code,fp_out);
}
else if(ch==13) //对回车换行进行特别处理
{
char lf=getChar(fp);
if(ch!=0)
{
line_count++;
word_count=0;
if(lf==10)
{
outword("newline",code_crlf,fp_out);
}
else
{
Retract();
outword("newline",code_crlf,fp_out);
}
}
}
else
{
//error
error("错误:错误的字符 \"%c\"\n",ch);
}
}
void lexsan(int count, char **vars)
{
char em;
int f_eof;
printf("\n");
if(checkOpenFiles(count,vars)!=0)
return;
initiate();
// fclose(fp_wordList);
LoadFileToBuffer(fp_source);
em=BufferEmpty();
f_eof=feof(fp_source);
while(em!=1 || f_eof!=16)
{
scan(fp_source,fp_output);
em=BufferEmpty();
f_eof=feof(fp_source);
}
printf("词法分析已完.\n");
getchar();
//关闭打开的文件指针
fclose(fp_source);
fclose(fp_output);
}
//#include "BuildWordListFile.h"
main(int count,char** vars)////////主调用函数
{
lexsan(count,vars);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -