C语言词法分析器.docx
《C语言词法分析器.docx》由会员分享,可在线阅读,更多相关《C语言词法分析器.docx(29页珍藏版)》请在冰豆网上搜索。
![C语言词法分析器.docx](https://file1.bdocx.com/fileroot1/2023-1/23/b52bc4c2-c020-4222-9801-34b3a7c9a306/b52bc4c2-c020-4222-9801-34b3a7c9a3061.gif)
C语言词法分析器
南华大学
计算机科学与技术学院
实验报告
(2016~2017学年度第二学期)
课程名称
程序设计语言与编译
实验名称
C语言词法分析器的设计与实现
姓名
何星佑
学号
20154340220
专业
树媒
班级
2
地点
教师
罗江琴
1.实验目的及要求
软件、硬件环境
Codeblocks13.12及以上版本
Windowsxp及以上版本
2.实验步骤
明确语言的词法规则,根据具体情况选取C语言的一个适当大小的子集,写出基本保留字、标识符、常数、运算符、分隔符和程序例。
初步编制好程序。
3.实验内容
流程图、程序
程序
Main.cpp
#include"global.h"
#include
intmain()
{
charfname[FSIZE];
error=fopen("error.txt","w+");
if(error==NULL)
{
printf("cannotcreateerror.txt!
\n");
}
out=fopen("out.txt","w+");
if(out==NULL)
{
printf("cannotcreateout.txt!
\n");
}
printf("pleaseinputfilename:
\n");
scanf("%s",fname);
in=fopen(fname,"r");
if(in==NULL)
{
printf("error:
cannotopenfile%s\n",fname);
return-1;
}
headCh=predeal(in);
while(fgets(buf,BSIZE,in)!
=NULL)
{
head=headCh;
intlen=strlen(buf);
buf[len-1]='\0';
start=0;
while(headCh!
='\0')
{
while(buf[start]==''&&headCh=='')
{
start++;
}
if(headCh=='')
{
if(buf[start]=='\0')break;
headCh=buf[start++];
}
if(isalpha(headCh))
{
dealAlpha();
}
elseif(isdigit(headCh))
{
dealDigit();
}
elseif(headCh=='/')
{
if(dealNotation()==-1)
{
printf("notationtoolongtoanalyze,skipthisline...\n");
fputc('\n',out);
break;
}
}
elseif(isBorder(headCh))
{
dealBorder();
}
elseif(headCh=='\''||headCh=='"')
{
dealChar(headCh);
}
else
{
fprintf(error,"L%d\tcannotanalyse%c\n",line,headCh);
headCh=buf[start];
}
start++;
}
line++;
flag=0;
headCh=goBlank(in);
if(isNotation==0)
{
fprintf(out,"%c%s\n",head,buf);
}
isNotation=0;
}
puts("Everythinghasdone...");
writeToken();
writeVarTable();
writeConTable();
fclose(in);
fclose(out);
fclose(error);
printf("错误日志\t\t\terror.txt\n");
printf("Token文件\t\t\ttoken.txt\n");
printf("无注释头文件的源文件日志\tout.txt\n");
printf("常量符号表\t\t\tconTable.txt\n");
printf("变量符号表\t\t\tvarTable.txt\n");
return0;
}
/**预处理**/
charpredeal(FILE*in)
{
charch;
ch=goBlank(in);
while(ch=='#')
{
fgets(buf,BSIZE,in);
dealInclude(buf);
line++;
fputc('\n',out);
ch=goBlank(in);
}
printf("headersdone...\n");
returnch;
}
/**dealheaders,like#include<...>**/
voiddealInclude(char*buf)
{
charinclude[15];
charch;
inti=9;
strncpy(include,buf,9);
include[9]='\0';
if(strcmp(include,"include<")==0)
{
while((ch=buf[i])!
='>')
{
i++;
if(ch=='\n')
{
fprintf(error,"L%d\theadersendwithout'>'\n",line);
break;
}
}
}
else
{
fprintf(error,"L%d\theadersformaterror\n",line);
}
}
/**stepblanksandcountlinenumber**/
chargoBlank(FILE*in)
{
charch;
do
{
ch=fgetc(in);
if(ch=='\n')
{
line++;
fputc('\n',out);
}
}
while(ch==''||ch=='\n'||ch=='\t');
returnch;
}
/**dealbeginwithalpha**/
voiddealAlpha()
{
intsymbol;
intid;
charword[100];
Tokentoken;
VarTablevarTable;
inti;
word[0]=headCh;
for(i=start;isdigit(buf[i])||isalpha(buf[i]);i++)
{
word[i-start+1]=buf[i];
}
word[i-start+1]='\0';
start=i;
headCh=buf[start];
symbol=isKeyword(word);
/**notkeyword**/
if(symbol==-1)
{
varTable.id=varTableNum;
strcpy(varTable.name,word);
varTableArray[varTableNum]=varTable;
varTableNum++;
token.symbol=IDN;
sprintf(token.attr,"%d",varTable.id);
strcpy(token.name,word);
tokenArray[tokenNum]=token;
tokenNum++;
}
/**iskeyword**/
else
{
token.symbol=symbol;
strcpy(token.name,word);
strcpy(token.attr,"--");
tokenArray[tokenNum]=token;
tokenNum++;
}
}
/**判断是否是关键字**/
intisKeyword(char*word)
{
inti;
for(i=0;keywordList[i][0];i++)
{
if(strcmp(word,keywordList[i])==0)
{
returni+256;
}
}
return-1;
}
/**将token数组写入文件**/
voidwriteToken()
{
FILE*ftoken;
inti=0;
ftoken=fopen("token.txt","w+");
if(ftoken==NULL)
{
printf("cannotcreatefiletoken.txt!
\n");
}
for(i=0;i{
fprintf(ftoken,"%s\t\t(%d,%s)\n",tokenArray[i].name,tokenArray[i].symbol,tokenArray[i].attr);
}
fclose(ftoken);
}
/**将变量符号表写入文件**/
voidwriteVarTable()
{
FILE*fvarTable;
inti=0;
fvarTable=fopen("varTable.txt","w+");
if(fvarTable==NULL)
{
printf("cannotcreatefilevarTable.txt!
\n");
}
for(i=0;i{
fprintf(fvarTable,"%s\t\t%d\n",varTableArray[i].name,varTableArray[i].id);
}
fclose(fvarTable);
}
/**将常量符号表写入文件**/
voidwriteConTable()
{
FILE*fconTable;
inti=0;
fconTable=fopen("conTable.txt","w+");
if(fconTable==NULL)
{
printf("cannotcreatefileconTable.txt!
\n");
}
for(i=0;i{
fprintf(fconTable,"%s\t\t%d\n",conTableArray[i].name,conTableArray[i].id);
}
fclose(fconTable);
}
/**dealwithdigit**/
voiddealDigit()
{
intsymbol;
intid;
charword[100];
Tokentoken;
ConTableconTable;
inti;
word[0]=headCh;
for(i=start;isdigit(buf[i]);i++)
{
word[i-start+1]=buf[i];
}
if(buf[i]=='.')
{
if(!
isdigit(buf[++i]))
{
start=i;
headCh=buf[start];
fprintf(error,"L%d\tunavailabefloat\n",line);
return;
}
word[i-start]='.';
for(;isdigit(buf[i]);i++)
{
word[i-start+1]=buf[i];
}
word[i-start+1]='\0';
start=i;
headCh=buf[start];
id=isInConTable(word);
/**不在常量表里,新加项**/
if(id==-1)
{
conTable.id=conTableNum;
strcpy(conTable.name,word);
conTableArray[conTableNum]=conTable;
conTableNum++;
id=conTable.id;
}
token.symbol=FNUM;
sprintf(token.attr,"%d",id);
strcpy(token.name,word);
tokenArray[tokenNum]=token;
tokenNum++;
}
else
{
word[i-start+1]='\0';
start=i;
headCh=buf[start];
id=isInConTable(word);
/**不在常量表里,新加项**/
if(id==-1)
{
conTable.id=conTableNum;
strcpy(conTable.name,word);
conTableArray[conTableNum]=conTable;
conTableNum++;
id=conTable.id;
}
token.symbol=INUM;
sprintf(token.attr,"%d",id);
strcpy(token.name,word);
tokenArray[tokenNum]=token;
tokenNum++;
}
}
/**处理界符**/
voiddealBorder()
{
Tokentoken;
chars[3];
inti;
s[0]=headCh;
s[1]=buf[start];
s[2]='\0';
if(s[1]!
='\0')
{
for(i=0;borderList[i][0];i++)
{
if(strcmp(s,borderList[i])==0)
{
strcpy(token.name,s);
token.symbol=i+400;
strcpy(token.attr,"--");
tokenArray[tokenNum++]=token;
start++;
headCh=buf[start];
return;
}
}
}
/**处理单界符**/
s[1]='\0';
for(i=0;borderList[i][0];i++)
{
if(strcmp(s,borderList[i])==0)
{
strcpy(token.name,s);
token.symbol=i+400;
strcpy(token.attr,"--");
tokenArray[tokenNum++]=token;
headCh=buf[start];
return;
}
}
}
intisBorder(charch)
{
inti;
for(i=0;borderList[i][0];i++)
{
if(ch==borderList[i][0])
{
return1;
}
}
return0;
}
/**处理注释**/
intdealNotation()
{
charch=buf[start];
inti;
intnotationLen=0;
Tokentoken;
/**除号处理**/
if(ch!
='/'&&ch!
='*')
{
strcpy(token.name,"/");
strcpy(token.attr,"--");
token.symbol=DIV;
tokenArray[tokenNum++]=token;
start++;
headCh=buf[start];
return0;
}
if(ch=='/')
{
fputc('\n',out);
isNotation=1;
headCh='\0';
return0;
}
elseif(ch=='*')
{
for(i=start+1;;i++)
{
if(buf[i]=='\0')
{
fgets(buf,BSIZE,in);
line++;
fputc('\n',out);
start=0;
headCh='\0';
i=-1;
}
else
{
while(!
(buf[i]=='*'&&buf[i+1]=='/'))
{
i++;
if(++notationLen==LIMIT_NOTATION)
{
fprintf(error,"L%d\tnotationtoolong\n",line);
isNotation=1;
return-1;
}
if(buf[i+1]=='\0')
{
fgets(buf,BSIZE,in);
line++;
fputc('\n',out);
i=0;
}
}
fputc('\n',out);
isNotation=1;
start=i+2;
headCh=buf[start];
return0;
}
}
}
}
/**处理字符常量**/
voiddealChar(charch)
{
Tokentoken;
ConTableconTable;
inti=start;
intid;
intj;
charword[100];
word[0]=ch;
if(ch=='\'')
{
if(buf[i]=='\\')
{
for(j=0;j<12;j++)
{
if(buf[i+1]==changeList[j])
{
word[1]='\\';
word[2]=buf[i+1];
word[3]='\'';
word[4]='\0';
strcpy(token.name,word);
strcpy(token.attr,"--");
token.symbol=j+500;
tokenArray[tokenNum++]=token;
start=i+3;
headCh=buf[start];
return;
}
}
/**error:
转义字符不合法**/
if(j==12)
{
fprintf(error,"L%d\tunavailablechangechar\n",line);
}
}
elseif(buf[i+1]!
='\'')
{
fprintf(error,"L%d\tthelengthofconstcharisunavailabe\n",line);
for(i=i+2;buf[i]!
='\'';i++);
start=i+1;
headCh=buf[start];
return;
}
else
{
word[1]=buf[i];
word[2]='\'';
word[3]='\0';
id=isInConTable(word);
/**不在常量表里,新加项**/
if(id==-1)
{
conTable.id=conTableNum;
strcpy(conTable.name,word);
conTableArray[conTableNum++]=conTable;
id=conTable.id;
}
token.symbol=CCHAR;
sprintf(token.attr,"%d",id);//changeinttostring
strcpy(token.name,word);
tokenArray[tokenNum++]=token;
start=i+2;
headCh=buf[start];
return;
}
}
elseif(ch=='"')
{
for(;buf[i]!
='"';i++)
{
word[i-start+1]=buf[i];
}
word[i-start+1]='"';
word[i-start+2]='\0';
id=isInConTable(word);
/**不在常量表里**/
if(id==-1)
{
conTable.id=conTableNum;
strcpy(conTable.name,word);
conTableArray[conTableNum++]=conTable;
id=conTable.id;
}
token.symbol=CSTR;
sprintf(token.attr,"%d",id);
strcpy(token.name,word);
tokenArray[tokenNum++]=token;
start=i+1;
headCh=buf[start];
}
}
/**判断是否在变量符号表中,返回位置,不在返回-1**/
intisInVarTable(char*name)
{
inti;
for(i=0;i{
if(strcmp(name,varTableArray[i].name)==0)
{
returnvarTableArray[i].id;
}
}
return-1;
}
/**判断是否在常量符号表中,返回位置,不在返回-1**/
intisInConTable(char*name)