📄 la.cpp
字号:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 50
static char zerobuffer[50]={""};
char firstbuffer[50]; //前半个缓冲区
char secondbuffer[50]; //后半个缓冲区
char buffer[50]; //存放取出的单词的缓冲区
char filename[30],fileout[30];//依次为输入文件和输出文件的文件名
char keyword[50][13]={ //关键字列表
"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","ture","try","void","volatile","while"};
int line_id=0,line_num=0,word_num=0,errornum=0;//依次为行号,所在行单词数,总单词数,总错误数
int lpos=0,B=0,F=0; //依次为在缓冲区中的当前位置,单词初始位置,单词结束位置
FILE *fin; //输入文件
FILE *fout; //输出文件
char ch=' ';
int type; //单词类型
int state; //当前状态
int k;
int keyflag,errorflag,backflag; //依次为关键字标识,错误标识
int ep,fp,lp,dp,xp,sp,en,fn,ln,dn,xn,sn; //判断数字常量用的标识号
void read_buffer();
void get_char();
void get_word();
void output();
void error();
void read_buffer() //把字符串读入缓冲区
{
int i=0;
if(lpos==0)
{
strcpy(firstbuffer,zerobuffer);
while(i<N)
{
firstbuffer[i]=getc(fin);
i++;
}
}
else if(lpos==N)
{
strcpy(secondbuffer,zerobuffer);
while(i<N)
{
secondbuffer[i]=getc(fin);
i++;
}
}
}
void get_char() //从缓冲区逐个字符扫描
{
if(lpos<N)
{
ch=firstbuffer[lpos];
lpos++;
}
else
if(lpos==N)
{
read_buffer();
ch=secondbuffer[0];
lpos++;
}
else
if(lpos>N && lpos<2*N)
{
ch=secondbuffer[lpos-N];
lpos++;
}
else
if(lpos==2*N)
{
lpos=0;
read_buffer();
ch=firstbuffer[0];
lpos++;
}
}
void get_word() //取出单词
{
strcpy(buffer,zerobuffer);
if(B<N && F<N)
{
for(k=B;k<=F;k++)
buffer[k-B]=firstbuffer[k];
}
if(B<N && F>=N)
{
for(k=B;k<N;k++)
buffer[k-B]=firstbuffer[k];
for(k=N;k<=F;k++)
buffer[k-B]=secondbuffer[k-N];
}
if(B>=N && F>=N)
{
for(k=B;k<=F;k++)
buffer[k-B]=secondbuffer[k-N];
}
if(B>=N && F<N)
{
for(k=B;k<2*N;k++)
buffer[k-B]=secondbuffer[k-N];
for(k=0;k<=F;k++)
buffer[k+2*N-B]=firstbuffer[k];
}
if(B<=F) buffer[F-B+1]='\0';
else buffer[2*N-B+F]='\0';
}
void output() //把单词及其属性写入指定文件,并显示出来
{
fprintf(fout,"0x%0x %s\n",type,buffer);
printf("0x%0x %s\n",type,buffer);
}
void IsAnotation()
{
}
void error() //处理错误
{
errornum++;
printf("There is a error at Line %d : %s \n",line_id+1,buffer);
}
void IsKey() //判断是关键字还是标识符
{
keyflag=0;
if(strlen(buffer)>13)
{
type=0x104;
}
for(k=0;k<50;k++)
{
if(strcmp(buffer,keyword[k])==0)
{
type=0x103;
keyflag=1;
break;
}
}
if(keyflag==0) type=0x104;
}
void IsNumber() //判断数字常量的类型,并作相应处理
{
for(k=0;k<(int)strlen(buffer);k++)
{
if(en==0 && (buffer[k]=='e'||buffer[k]=='E')) { ep=k;en++; }
else if(buffer[k]=='f'||buffer[k]=='F') { fp=k;fn++; }
else if(buffer[k]=='l'||buffer[k]=='L') { lp=k;ln++; }
else if(buffer[k]=='x'||buffer[k]=='X') { xp=k;xn++; }
else if(buffer[k]=='.') { dp=k;dn++; }
else if(buffer[k]=='-') { sp=k;if(k!=0)sn++; }
else if((buffer[k]>=71 && buffer[k]<=90)||(buffer[k]>=103 && buffer[k]<=122)||
buffer[k]=='$'||buffer[k]=='_'||en>1||ln>1||dn>1||xn>1||sn>1||
(buffer[0]!=48 && buffer[1]!='x' && buffer[1]!='X' &&((buffer[k]>=65 && buffer[k]<=70)||(buffer[k]>=97 && buffer[k]<=102)))||
(buffer[0]!='-' && buffer[1]!=48 && buffer[2]!='x' && buffer[1]!='X' &&((buffer[k]>=65 && buffer[k]<=70)||(buffer[k]>=97 && buffer[k]<=102))))
{
errorflag=1;
// if(buffer[0]==48 && xp==1 && ((buffer[k]>=65 && buffer[k]<=70)||(buffer[k]>=97 && buffer[k]<=102)))
break;
}
}
if(errorflag==1) error();
else if((en==0 && fn==0 && dn==0 && xn==0 && ln==0 && sn==0) //1234
||(en==0 && fn==0 && dn==0 && xn==0 && sn==0 && lp==strlen(buffer)-1) //123l
||(dn==0 && ln==0 && sn==0 && xp==1 && buffer[0]==48 && xp!=strlen(buffer)-1) //0x123
||(dn==0 && ln==0 && sn==0 && buffer[0]=='-' && xp==2 && buffer[1]==48 && xp!=strlen(buffer)-1))
{
type=0x107;
}
else if((en==0 && fn==0 && dn==1 && xn==0 && ln==0 && sn==0 ) //123.456
||(en==0 && ln==0 && dn==1 && xn==0 && sn==0 && fp==strlen(buffer)-1) //123.456f
||(en==1 && fn==0 && ln==0 && xn==0 && (dn==0|| (dn==1 && dp<ep) ||(sn==1 &&(sp-ep)==1) ) ) ) //12.3e56
{
type=0x108;
}
else
{
errorflag=1;
error();
}
}
void IsOperator()
{
}
void Number() //处理数字常量
{
// B=F=lpos-1;
ep=fp=lp=dp=xp=sp=101;
en=fn=ln=dn=xn=sn=0;
while((ch>=65 && ch<=90)||(ch>=97 && ch<=122)||(ch>=48 && ch<=57)||ch=='$'||ch=='_'||ch=='e'||ch=='E'||ch=='l'||ch=='L'||ch=='.'||ch=='f'||ch=='F'||ch=='-')
{
get_char();
if(ch=='-' && ((lpos<N && firstbuffer[(lpos-2)%50]!='e' && firstbuffer[(lpos-2)%50]!='E')||
(lpos>=N && secondbuffer[(lpos-2)%50]!='e' && secondbuffer[(lpos-2)%50]!='E'))){F=lpos-1;break;}
}
backflag=1;
if(sn!=1)F=lpos-2;
get_word();
IsNumber();
if(errorflag==0)
{
output();
line_num++;
}
state=0;
}
void scanner() //词法分析主函数
{int p=0,flag=0,n=0;
read_buffer();
get_char();
while(ch!=EOF)
{
backflag=0;
switch(state)
{
case 0:
errorflag=0;
if((ch>=65 && ch<=90)||(ch>=97 && ch<=122)||ch=='$'||ch=='_')
{
B=F=lpos-1;
get_char();
while((ch>=65 && ch<=90)||(ch>=97 && ch<=122)||(ch>=48 && ch<=57)||ch=='$'||ch=='_')
{
get_char();
}
backflag=1;
F=lpos-2;
get_word();
IsKey();
output();
line_num++;
state=0;
break;
}
else
{
if(ch>=48 && ch<=57)
{
B=F=lpos-1;
Number();
break;
}
else
if(ch==' ')
{
state=0;
break;
}
flag=0;
switch(ch)
{
case '"':
n=0;
B=F=lpos-1;
get_char();
while(ch!='"' && ch!='\n')
{
get_char();n++;
}
if(ch=='\n')
{
F=lpos-1;
get_word();
error(); //error!
}
else
{
F=lpos-1;
get_word();
type=0x109;
output();
line_num++;
}
state=0;
break;
case '\'':
B=F=lpos-1;
get_char();
if(ch=='\'')
{
state=0;
F=lpos-1;
get_word();
error(); //error!
break;
}
else
{
get_char();
if(ch=='\'')
{
F=lpos-1;
get_word();
type=0x106;
output();
line_num++;
state=0;
break;
}
F=lpos-1;
get_word();
error(); //error!
state=0;
break;
}
case '/':
get_char();
if(ch=='/')
{
n=0;
while(ch!='\n' && n<100)
{
get_char();
n++;
}
if(n==100) error(); //error!
line_id++;
word_num+=line_num;
printf("Line %2d : %d\n",line_id,line_num);
line_num=0;
state=0;
break;
}
if(ch=='*')
{
get_char();
while(ch!=EOF)
{
while(ch!='*' && ch!=EOF)
{
if(ch=='\n')
{
line_id++;
word_num+=line_num;
printf("Line %2d : %d\n",line_id,line_num);
line_num=0;
}
get_char();
}
get_char();
if(ch=='/')
{
state=0;
break;
}
}
break;
}
if(ch=='=')
{
state=0;
line_num++;
break;
}
else
{
F=B;
get_word();
type=0x11b;
output();
backflag=1;
line_num++;
state=0;
break;
}
case '{':
case '}':
B=F=lpos-1;
get_word();
type=0x121;
output();
line_num++;
state=0;
break;
case '[':
case ']':
case '(':
case ')':
case '.': //!!???
B=F=lpos-1;
get_word();
type=0x11d;
output();
line_num++;
state=0;
break;
case ';':
B=F=lpos-1;
get_word();
type=0x122;
output();
line_num++;
state=0;
break;
case ',':
B=F=lpos-1;
get_word();
type=0x120;
output();
line_num++;
state=0;
break;
case '+':
B=F=lpos-1;
get_char();
if(ch=='+')
{
state=0;
F=lpos-1;
get_word();
type=0x11c;
output();
line_num++;
break;
}
if(ch=='=')
{
state=0;
F=lpos-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -