编译原理词法分析与语法分析实验报告.docx
《编译原理词法分析与语法分析实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析与语法分析实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
![编译原理词法分析与语法分析实验报告.docx](https://file1.bdocx.com/fileroot1/2023-4/21/dc266aed-1116-4637-b1c3-f05c01bbdfee/dc266aed-1116-4637-b1c3-f05c01bbdfee1.gif)
编译原理词法分析与语法分析实验报告
实验三词法分析与语法分析程序设计
实验日期:
2011年11月11日评分
批阅教师签字
一、实验目的
基本掌握计算机语言的词法分析程序和语法分析程序的设计方法
二、实验内容
实验要求:
1.根据以下的正规式,画出状态图;
标识符:
<字母>(<字母>|<数字字符>)*
关键字:
ifthenelsewhiledo
十进制整数:
0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*
运算符和分隔符:
+-*/><=();
2.根据状态图,设计词法分析函数intscan(),从键盘读入数据,分析出一个单词。
3.对于只含有+、*运算的算术表达式的如下文法,编写相应的语法分析程序,要求用LL
(1)分析表实现,并以id+id*id为例进行测试:
E—>TE′
E′—>+TE′|ε
T—>FT′
T′—>*FT′|ε
F—>(E)|id
实验步骤
1 根据状态图,设计词法分析算法
2 采用C++语言,实现该算法
3 调试程序:
输入一组单词,检查输出结果。
4编制给定文法的非递归的预测分析程序,并加以测试。
三、实验环境
计算机、Windows操作系统、VisualC++程序集成环境。
四、实验原理(或程序框图)及步骤
LL
(1)中的第一个L表示从左到右扫描输入,第二个L表示产生最右推导,而‘1’则表示在每一步中只需要向前看一个输入符号来决定语法分析动作。
构造一个预测分析表如下:
输入:
文法G
输出:
预测分析表M
方法:
对于文法G的每个产生式A→α,进行如下处理:
1):
对于FIRST(α)中的每个终结符a,将A→α加入到M[A,α]中。
2):
如果ε在FIRST(α)中,那么对于FOLLOW(A)中的每个终结符b,将A→α加入到M[A,α]中。
如果ε在FIRST(α)中,且$在FOLLOW(A)中,也将A→α加入到M[A,$]中。
完成上面操作之后,如果M[A,α]中没有产生式,那么将M[A,α]设置为error。
五、程序源代码
词法分析函数:
structkey_kord{
char*word;
intid;
};
key_wordkeyword[]={
{"if",1},
{"then",2},
{"else",3},
{"while",4},
{"do",5},
{"integer",16}
};
voidscan(FILE*ftp)
{
chartemp_char;
inti,c;
while(!
feof(ftp)){
temp_char=fgetc(ftp);
if(isalpha(temp_char)){
TOKEN[0]=temp_char;
temp_char=fgetc(ftp);
i=1;
while(isalnum(temp_char)){
TOKEN[i]=temp_char;
i++;
temp_char=fgetc(ftp);
}
TOKEN[i]='\0';
fseek(ftp,-1,1);
c=lookup(TOKEN);
if(c==0)
out(ID,TOKEN);
else
out(c,"");
}
elseif(isdigit(temp_char)){
TOKEN[0]=temp_char;
temp_char=fgetc(ftp);
i=1;
while(isdigit(temp_char)){
TOKEN[i]=temp_char;
i++;
temp_char=fgetc(ftp);
}
TOKEN[i]='\0';
fseek(ftp,-1,1);
out(INT,TOKEN);
}
else
switch(temp_char){
case'<':
temp_char=fgetc(ftp);
if(temp_char=='=')
out(LE,"");
elseif(temp_char=='>')
out(NE,"");
else{
fseek(ftp,-1,1);
out(LT,"");
}
break;
case'=':
out(EQ,"");break;
case'>':
temp_char=fgetc(ftp);
if(temp_char=='=')
out(GE,"");
else{
fseek(ftp,-1,1);
(GT,"");
}
break;
case':
':
temp_char=fgetc(ftp);
if(temp_char=='=')
out(FZ,"");
else{
fseek(ftp,-1,1);
report_error(temp_char);
}
break;
case'/':
temp_char=fgetc(ftp);
if(temp_char=='/'){
do{
temp_char=fgetc(ftp);
}while(temp_char!
='\n');
graphnum++;
}
else{
fseek(ftp,-1,1);
out(DEV,"");
}
break;
case'':
break;
case'\n':
graphnum++;break;
case'':
break;
case-1:
break;
default:
report_error(temp_char);
break;
}
}
return;
}
LL
(1)算法实现:
#defineMAXSYMBOL30
temp_chararNT[]={'E','A','T','B','F'};
temp_chararTE[]={'i','+','*','(','(',')'};
temp_charar*analysisTable[MAXSYMBOL][3]={
{"E","i","TG"},{"E","+",""},{"E","*",""},{"E","(","TG"},{"E",")",""},{"E","#",""},
{"A","i",""},{"A","+","+TA"},{"A","*",""},{"A","(",""},{"A",")","$"},{"A","#","$"},
{"T","i","FB"},{"T","+",""},{"T","*",""},{"T","(","FB"},{"T",")",""},{"T","#",""},
{"B","i",""},{"B","+","$"},{"B","*","*FB"},{"B","(",""},{"B",")","$"},{"B","#","$"},
{"F","i","i"},{"F","+",""},{"F","*",""},{"F","(","(E)"},{"F",")",""},{"F","#",""},
};
intStack_Count(HEADSTACK*head)
{
intcount=0;
if(head->stackHead==NULL)
return0;
TEMP_CHARARSTACK*currentNode=head->stackHead;
while(currentNode!
=NULL)
{
currentNode=currentNode->nextNode;
count++;
}
returncount;
}
HEADSTACK*Stack_Init()
{
HEADSTACK*headNode=(HEADSTACK*)malloc(sizeof(HEADSTACK));
headNode->stackHead=NULL;
returnheadNode;
}
voidStack_Push(HEADSTACK*head,temp_charartemp_char)
{
TEMP_CHARARSTACK*currentNode,*tail;
tail=(TEMP_CHARARSTACK*)malloc(sizeof(TEMP_CHARARSTACK));
tail->temp_char=temp_char;
tail->nextNode=NULL;
if(head->stackHead==NULL)
{
head->stackHead=tail;
return;
}
currentNode=head->stackHead;
while(currentNode->nextNode!
=NULL)
{
currentNode=currentNode->nextNode;
}
currentNode->nextNode=tail;
currentNode=tail;
currentNode->nextNode=NULL;
}
TEMP_CHARARSTACKStack_Pop(HEADSTACK*head)
{
TEMP_CHARARSTACK*currentNode,*tail,popNode;
if(head->stackHead==NULL)
{
printf("Error:
TheStackdoesnothasnode\n");
returnpopNode;
}
currentNode=tail=head->stackHead;
if(tail->nextNode==NULL)
{
popNode.temp_char=tail->temp_char;
popNode.nextNode=NULL;
head->stackHead=NULL;
returnpopNode;
}
while(tail->nextNode!
=NULL)
{
tail=tail->nextNode;
if(tail->nextNode==NULL)
{
currentNode->nextNode=NULL;
popNode.temp_char=tail->temp_char;
popNode.nextNode=tail->nextNode;
returnpopNode;
}
currentNode=currentNode->nextNode;
}
}
boolIsNT(temp_charartemp_char)
{
for(inti=0;i{
if(temp_char==NT[i])
returntrue;
}
returnfalse;
}
boolIsTE(temp_charartemp_char)
{
for(inti=0;i{
if(temp_char==TE[i])
returntrue;
}
returnfalse;
}
temp_charar*GetMatrixValue(temp_chararNT,temp_chararTE)
{
temp_chararnt[2],te[2];
nt[0]=NT;
nt[1]='\0';
te[0]=TE;
te[1]='\0';
for(inti=0;i{
if((strcmp(nt,analysisTable[i][0])==0)&&(strcmp(te,analysisTable[i][1])==0)&&(analysisTable[i][2]!
=""))
{
returnanalysisTable[i][2];
}
}
return"";
}
boolIsCorrectSentence(temp_chararstr[])
{
intpos=0;
boolFlag=true;
temp_chararX;
temp_charar*conclude;
HEADSTACK*head;
head=Stack_Init();
Stack_Push(head,'#');
Stack_Push(head,'E');
while(Flag)
{
X=Stack_Pop(head).temp_char;
if(IsTE(X))
{
if(X==str[pos])
{
pos++;
}
else
{
returnfalse;
}
}
elseif(X=='#')
{
if(X==str[pos])
Flag=false;
else
returnfalse;
}
elseif(strcmp((conclude=GetMatrixValue(X,str[pos])),"")!
=0)
{
if(strcmp(conclude,"$")==0)
{
continue;
}
for(intj=strlen(conclude)-1;j>-1;j--)
{
Stack_Push(head,conclude[j]);
}
}
else
{
returnfalse;
}
}
returntrue;
}
}六、实验数据、结果分析
通过实验记录可知,程序的输出结果与实际的结果一致,程序能正确实现LL
(1)文法。
通过本次试验,我初步掌握基本掌握计算机语言的词法分析程序和语法分析程序的设计方法,并且对词法分析与语法分析的联系有了更深入的理解,对文法的理解,应用领域更加了解,这对于以后我将他们应用于更多地方有很多帮助。
同时通过上机编程锻炼了我的动手能力。