📄 java-scanner.cpp
字号:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXBUFFER 256 //缓冲区大小
#define LENGTH 50
typedef struct token
{
int label; //种类标签
char name[100];
int code; //编码
}token;
char filename[30];
char buffer[MAXBUFFER]; //缓冲区
int f=MAXBUFFER-1; //缓冲中当前指针位置
FILE *sourcefin; //源文件指针
FILE *tokenfout; //分析结果文件指针
int currentline=1; //当前行
int currentaddr=0; //当前行中单词位置
int err_count=0; //错误单词总数
int count=0; //单词总数
char *key[LENGTH]={"abstract","boolean","break","byte","case","catch","char","class","const","continue",
"default","do","double","else","extends","false","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","true","try","void","volatile","while"};
token currenttoken;
void load();
void scanner();
void isnumber();
void isalpha();
void isstring();
void ischar();
void isanotain();
void isesc();
void isother();
void output();
void error();
int main()
{
scanner();
printf(" ---------------------------------------\n");
printf(" 源文件单词个数: %d\n",count);
printf(" 源文件错误单词个数: %d\n",err_count);
printf(" ---------------------------------------\n");
printf(" 分析完成! o(∩_∩)o...哈哈!\n\n");
printf("词法分析结果已经写入 scanner_output.txt 请查看详情!\n");
return 0;
}
//---------------半缓冲读入-----------------
void load()
{
int i;
if(f==MAXBUFFER/2-1)
{
//fread(&buffer[f+1],MAXBUFFER/2,1,sourcefin);
for(i=128;i<256;i++) buffer[i]=fgetc(sourcefin);
f++;
}else if(f==MAXBUFFER-1)
{
// fread(buffer,MAXBUFFER/2,1,sourcefin);
for(i=0;i<128;i++) buffer[i]=fgetc(sourcefin);
f=0;
}
else f++;
}
//---------------主程序-----------------
void scanner()
{
printf("-------------------------\n");
printf(" java语言词法分析器\n");
printf("-------------------------\n");
printf("输入源文件名:");
scanf("%s",filename);
if((sourcefin=fopen(filename,"rt"))==NULL)
{
printf("无法打开文件%s.\n",filename);
exit(1);
}
if((tokenfout=fopen("scanner_output.txt","w"))==NULL)
{
printf("无法打开文件.\n");
exit(1);
}
load();
while(buffer[f]!=EOF&&buffer[f]!=NULL)
{
for(int i=0;i<30;i++) currenttoken.name[i]='\0';
if((buffer[f]>47)&&(buffer[f]<58))
isnumber();
if(((buffer[f]>64)&&(buffer[f]<90))||((buffer[f]>96)&&(buffer[f]<123))||buffer[f]=='_'||buffer[f]=='$')
isalpha();
else {
if(buffer[f]=='/') isanotain();
else if(buffer[f]=='\\') isesc();
else if(buffer[f]=='\"') isstring();
else if(buffer[f]=='\'') ischar();
else isother();
}
}
fclose(sourcefin);
fclose(tokenfout);
}
//---------------整型常量和实型常量处理----------------------
void isnumber(){
int i=0;
int flag=0;
char ch;
while((buffer[f]>47)&&(buffer[f]<58)||(buffer[f]=='e')||(buffer[f]=='E')||(buffer[f]=='F')||(buffer[f]=='X')||(buffer[f]=='x')||(buffer[f]=='L'))
{
currenttoken.name[i++]=buffer[f];
load();
if(buffer[f]=='.'||buffer[f]=='e'||buffer[f]=='E')
{
flag=1;
ch=buffer[f];
break;
}
}
currenttoken.label=7;
currenttoken.code=0x107;
if(flag==1)
{
load();
if((buffer[f]>47)&&(buffer[f]<58))
currenttoken.name[i++]=ch;
else error();
while((buffer[f]>47)&&(buffer[f]<58)||buffer[f]=='F')
{
currenttoken.name[i++]=buffer[f];
load();
}
currenttoken.label=8;
currenttoken.code=0x108;
if(buffer[f]=='.')
{
error();
load();
while((buffer[f]>47)&&(buffer[f]<58))
{
load();
}
}
if(((buffer[f]>64)&&(buffer[f]<90))||((buffer[f]>96)&&(buffer[f]<123)))
{
error();
while(((buffer[f]>64)&&(buffer[f]<90))||((buffer[f]>96)&&(buffer[f]<123)))
{
load();
while((buffer[f]>47)&&(buffer[f]<58)) load();
}
}
}
output();
}
//---------------关键字和标识符------------
void isalpha()
{
int i=0,h=0;
while(((buffer[f]>64)&&(buffer[f]<90))||((buffer[f]>96)&&(buffer[f]<123))||buffer[f]=='_'||buffer[f]=='$'||(buffer[f]>47)&&(buffer[f]<58))
{
currenttoken.name[i++]=buffer[f];
load();
}
for(i=0;i<LENGTH;i++)
{
h=strcmp(key[i],currenttoken.name);
if(h==0) break;
}
if(h==0)
{
currenttoken.code=0x103;
currenttoken.label=3; //关键字
}
else
{
if(!(strcmp("true",currenttoken.name))&&(strcmp("false",currenttoken.name)))
{
currenttoken.code=0x105;
currenttoken.label=5; //布尔型
}
else
{
currenttoken.code=0x104;
currenttoken.label=4; //标识符
}
}
output();
}
//--------------字符串处理----------------------
void isstring()
{
int i=0;
for(;;)
{
load();
currenttoken.code=0x109;
currenttoken.label=9;
for(;buffer[f]!='\"'&&buffer[f]!=EOF;load())
{
currenttoken.name[i++]=buffer[f];
}
if(buffer[f]==EOF)
{
error();
break;
}
else break;
}
output();
load();
}
//--------------字符处理----------------------
void ischar()
{
load();
if(buffer[f]!='\''&&buffer[f]!=EOF&&buffer[f]!=10)
{
currenttoken.name[0]=buffer[f];
}
if(buffer[f]=='\\')
{
isesc();
if(buffer[f]=='\'') load();
}
else
{
load();
if(buffer[f]=='\'')
{
currenttoken.code=0x106;
currenttoken.label=6;
}
else error();
output();
load();
}
}
//--------------注释处理及"/=","/"----------------------
void isanotain()
{
char ch;
ch=buffer[f];
load();
if(buffer[f]=='*') //注释/**/处理
{
for(;;)
{
load();
if(buffer[f]==EOF)
{
error();
break;
}
if(buffer[f]=='*')
{
ch=buffer[f];
load();
if(buffer[f]=='/')
{
load();
currenttoken.code=0x101;
currenttoken.label=1;
break;
}
}
}
}
else if(buffer[f]=='/') //注释//处理
{
currenttoken.code=0x101;
currenttoken.label=1;
for(;buffer[f]!='\n'&&buffer[f]!='\r'&&buffer[f]!=EOF;)
{
load();
}
}
else if(buffer[f]=='=') ///=处理
{
currenttoken.code=0x110;
currenttoken.label=12;
currenttoken.name[0]='/';
currenttoken.name[1]=buffer[f];
output();
load();
}
else
{
currenttoken.name[0]='/'; //除号
currenttoken.code=0x11b;
currenttoken.label=12;
output();
}
}
//--------------转义字符----------------------
void isesc()
{
int i=2,k=0;
currenttoken.name[0]='\\';
currenttoken.label=10;
load();
if(buffer[f]=='\''||buffer[f]=='\\'||buffer[f]=='r'||buffer[f]=='n'||buffer[f]=='f'||buffer[f]=='t'||buffer[f]=='b')
{
currenttoken.name[1]=buffer[f];
output();
load();
}
else if(buffer[f]=='u')
{
currenttoken.name[1]=buffer[f];
while(1)
{
load();
if((buffer[f]>47)&&(buffer[f]<58)||(buffer[f]>64)&&(buffer[f]<71)||(buffer[f]>96)&&(buffer[f]<103))
{
currenttoken.name[i++]=buffer[f];
k++;
}
else break;
}
if(k>4)
{
error();
output();
}
else output();
}
else
{
while(1)
{
load();
if((buffer[f]>47)&&(buffer[f]<56))
{
currenttoken.name[i++]=buffer[f];
k++;
}
else break;
}
if(k>3)
{
error();
output();
}
else output();
}
}
//--------------其他情况----------------------
void isother()
{
switch(buffer[f]) {
case'[':
currenttoken.code=0x11d;
currenttoken.label=11;
currenttoken.name[0]='[';
currenttoken.name[1]='\0';
load();
output();
break;
case']':
currenttoken.code=0x11d;
currenttoken.label=11;
currenttoken.name[0]=']';
currenttoken.name[1]='\0';
load();
output();
break;
case'(':
currenttoken.code=0x11d;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -