📄 scanner.c
字号:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "ctype.h"
#define Half 512
#define Y 1
#define N 0
///////////////////////////////////////////////////////////
FILE *fp;
char FileName[50];
char Buffer1[Half]; // 半缓冲区一
char Buffer2[Half]; // 版缓冲区二
char WordBuffer[512]; // 单词缓冲区
FILE *fp_read; // 读文件指针
FILE *fp_write; // 写文件指针
int point_find; // 向前搜索指针
int point_begin; // 单词开始指针
int word_row; // 每行单词数
int line; // 行数
int word_total; // 文件单词总数
////////////////////////////////////////////////////////////
FILE * OpenFile() // 打开文件,fp是指向文件的指针变量
{
if( ( fp = fopen( FileName,"r") )==NULL )
{
printf("Can not open the file!");
exit(0);
}
else
{ printf("Open file successfully!\n");
return fp;
}
}
CloseFile() // 关闭文件
{
fclose(fp);
}
//////////////////////////////////////////////////////////////
PassLetter(FILE *fp)
{ // 把文件读到半缓冲区一
int i;
fp_read = fp;
fp_write = NULL;
point_find = -1;
point_begin = 0;
word_row = 0;
line = 1;
word_total = 0;
for(i = 0; i < Half; i++)
{ // 清空缓冲区
Buffer1[i] = '\0';
Buffer2[i] = '\0';
}
fread(Buffer1,sizeof(Buffer1),1,fp_read); // 读数据块函数
}
/////////////////////////////////////////////////////////////////
NextChar()
{ // 寻找一个字母
int i;
if (point_find == Half - 1)
{
for(i = 0; i < Half; i++)
{ //清空缓冲区
Buffer2[i] = '\0';
}
if(!feof(fp_read))
{ // 如果没有到达文件尾
fread(Buffer2,sizeof(Buffer2),1,fp_read);
}
else return NULL;
point_find++;
}
else if( point_find >= 2 * Half - 1 )
{
for(i = 0; i < Half; i++)
{ //清空缓冲区
Buffer1[i] = '\0';
}
if(!feof(fp_read))
{
fread(Buffer1,sizeof(Buffer1),1,fp_read);
}
else return NULL;
point_find = 0;
}
else
{
point_find++;
}
if(point_find < Half)
{
return Buffer1[point_find];
}
else
{
return Buffer2[point_find - Half];
}
}
///////////////////////////////////////////////////////////////////
BackSpace(char *char1 )
{ // 相会倒退一个字母
if (point_find <= 0)
point_find = 2 * Half -1;
else point_find --;
if(point_find < Half)
{
*char1 = Buffer1[point_find];
}
else
{
*char1 = Buffer2[point_find - Half];
}
}
///////////////////////////////////////////////////////////////////////
SendWord()
{ // 将分析得到的单词存入单词缓冲区
int i, j = 0, e;
for (i = 0; i < 512; i++) // 清空单词缓冲区
WordBuffer[i] = '\0';
if (point_begin > point_find)
e = point_find + 2 * Half; // e为单词的结束点
else
e = point_find;
i = point_begin;
while (i <= e)
{
if (i < Half && Buffer1[i] != '\n')
{
WordBuffer[j] = Buffer1[i];
j++;
}
else if (i < 2 * Half && Buffer2[i-Half] != '\n')
{
WordBuffer[j] = Buffer2[i - Half];
j++;
}
else if (Buffer2[i-Half] != '\n')
{
WordBuffer[j] = Buffer1[i - 2 * Half];
j++;
}
i++;
}
point_begin = point_find + 1;
}
/////////////////////////////////////////////////////////////////////////////
MakeSure()
{ //检查是否为关键字
char *KeyWord[] = {"abstract","boolean","break","byte","case","catch","char",
"class","const","continue","default","do","double","else","extends",
"final","finally","float","for","goto","if","implements","import",
"instanceof","int","interface","long","native","new","null","package",
"private","protected","public","return","short","static","super","switch",
"synchronized","this","throw","throws","transient","try","void","volatile","while"};
int i,value,flag = 0;
SendWord(); // 将分析得到的单词存入单词缓冲区
for (i = 0 ; i < 48; i++)
{
if (strcmp(WordBuffer,KeyWord[i]) == 0)
{ // 是关键字
value = 0x103;
flag = 1;
break;
}
}
if (((strcmp(WordBuffer,"true") == 0) || (strcmp(WordBuffer,"false") == 0)) && flag == 0)
value = 0x105; // 是布尔型
else if (flag ==0) value = 0x104; // 是标识符
WriteFile(value);
word_row++; //每行单词数加一
}
////////////////////////////////////////////////////////////////////////////////////////////
WriteFile(int t)
{ // 把属性值写入文件
if (fp_write == NULL)
{
if((fp_write = fopen("scanner_output.txt","w")) == NULL)
{
printf("cannot write to the file!\n");
exit(0);
}
}
fprintf(fp_write,"< 0x%x , %s >\n",t,WordBuffer);
printf("< 0x%x , %s >\n",t,WordBuffer);
}
////////////////////////////////////////////////////////////////////////////////////////////
AtLast(int value, char *char1, int option)
{ // 分析完每个单词后收尾工作
int i;
SendWord();
if (option == 1)
{
WriteFile(value); // 写入文件同时显示在屏幕上
word_row++;
for (i = 0; i < 512; i++)
WordBuffer[i] = '\0';
}
*char1 = NextChar();
}
/////////////////////////////////////////////////////////////////////////////////////////////
WriteLine()
{ //每行结束时,输出行号,及该行字符数
if (fp_write == NULL)
{
if((fp_write = fopen("scanner_output.txt","w")) == NULL)
{
printf("cannot write to the file!\n");
exit(0);
}
}
fprintf(fp_write," Line:%d, Sum of words in this line is:%d.\n",line,word_row); //把行号和每行字符数写文件
fprintf(fp_write,"******************************************************\n");
printf(" Line:%d, Sum of words in this line is:%d.\n",line,word_row);
printf("*****************************************************\n");
word_total += word_row;
word_row = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
Analysis() {
char char1;
int state = 0, value, ct;
char1 = NextChar();
while (char1 != NULL)
{
switch(state)
{
case 0:
if (isalpha(char1) || char1=='$' || char1=='_')
{
state = 1;
break;
} // 标志符,关键字
else if (char1 == '*')
{
state = 3;
break;
} // *,*=
else if (char1 == '>')
{
state = 6;
break;
} // >,>=,>>,>>=,>>>,>>>=
else if (char1 == '%')
{
state = 15;
break;
} // %,%=
else if (char1 == '<')
{
state = 18;
break;
} // <,<=,<<,<<=
else if (char1 == '~')
{
state = 24;
break;
} // ~
else if (char1 == '|')
{
state = 25;
break;
} // |,||,|=
else if (char1 == '&')
{
state = 29;
break;
} // &,&&,&=
else if (char1 == '^')
{
state = 33;
break;
} // ^,^=
else if (char1 == '=')
{
state = 36;
break;
} // =,==
else if (char1 == '!')
{
state = 39;
break;
} // !,!=
else if (char1 == '?' || char1 == ':')
{
state = 41;
break;
} // ?:
else if (char1 == '/')
{
state = 43;
break;
} // /,/=,//注释,/*注释
else if (char1 == ',')
{
state = 51;
break;
} // ,
else if (char1 == ';')
{
state = 52;
break;
} // ;
else if (char1 == '{' || char1 == '}')
{
state = 53;
break;
} // {,}
else if (char1 == '[' || char1 == ']' || char1 == '(' || char1 == ')')
{
state = 54;
break;
} // [,],(,)
else if (char1 == '"')
{
state = 55;
break;
} // 字符串
else if (char1 == '\'')
{
state = 57;
break;
} //字符
else if (char1 == '+')
{
state = 60;
break;
} //+,++,+=
else if (char1 == '-')
{
state = 64;
break;
} //-,--,-=
else if (char1 == '0')
{
state = 68;
break;
} // 整数,浮点数
else if (char1 >= '1' && char1 <= '9')
{
state = 75;
break;
} // 整数,浮点数
else if (char1 == '.')
{
state = 83;
break;
} // .,整数,浮点数
else if (char1 == '\n')
{
if (word_row != 0)
WriteLine();
line++;
AtLast(0,&char1,0);
break;
} // 换行符
else if (char1 == ' ' || char1 == '\t')
{
state = 0;
AtLast(0,&char1,0);
break;
} // 空格/\t
else {
state = 100;
break;
} // 错误
case 1:
while (isalnum(char1) || char1 == '_' || char1 == '$') // isalnum检查字符是否为英文字母或数字
char1 = NextChar();
state = 2;
BackSpace(&char1); //退会一个字符
break;
case 2: // 0x103
state = 0;
MakeSure();
char1 = NextChar();
break; // 关键字,标志符
case 3:
char1 = NextChar();
if (char1 == '=')
state = 5;
else
{
state = 4;
BackSpace(&char1);
}
break;
case 4: case 16: case 44: // 0x11b
state = 0;
value = 0x11b;
AtLast(value,&char1,1); // 写文件
break; // *,%,/
case 5: case 11: case 14: case 17: case 23: case 28: case 32: case 35: case 37: case 45: case 63: case 67: //0x110
state = 0;
value = 0x110;
AtLast(value,&char1,1);
break; // *=,>>=,>>>=,%=,<<=,|=,&=,^=,=
case 6:
char1 = NextChar();
if (char1 == '=')
state = 8;
else if (char1 == '>')
state = 9;
else
{
state = 7;
BackSpace(&char1);
}
break;
case 7: case 8: case 19:case 20: //0x118
state = 0;
value = 0x118;
AtLast(value,&char1,1);
break; // >,>=,<,<=
case 9:
char1 = NextChar();
if (char1 == '=')
state = 11;
else if (char1 == '>')
state = 12;
else
{
state = 10;
BackSpace(&char1);
}
break;
case 10: case 13: case 22: //0x119
state = 0;
value = 0x119;
AtLast(value,&char1,1);
break; // >>,>>>,<<
case 12:
char1 = NextChar();
if (char1 == '=')
state = 14;
else
{
state = 13;
BackSpace(&char1);
}
break;
case 15:
char1 = NextChar();
if (char1 == '=')
state = 17;
else
{
state = 16;
BackSpace(&char1);
}
break;
case 18:
char1 = NextChar();
if (char1 == '=')
state = 20;
else if (char1 == '<')
state = 21;
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -