. . . .
. . ..
编译原理语法分析实验报告
软工082班
兰洁
4
实验容
实验目的实验要求
程序流程图
主函数;
scanner();
irparser()函数
yucu() /*语句串分析*/
statement()/*语句分析函数*/
expression()/*表达式分析函数*/
term()/*项分析函数*/
factor()/*因子分析函数*/
程序代码
测试用例
输出结果
实验心得
一、实验容:
编写为一上下文无关文法构造其递归下降语法分析程序,并对任给的一个输入串进行语法分析检查。程序要求能对输入串进行递归下降语法分析,能判别程序是否符合已知的语法规则,如果不符合(编译出错),则输出错误信息。
二、实验目的:
构造文法的语法分析程序,要求采用递归下降语法分析方法对输入的字符串进行语法分析,实现对词法分析程序所提供的单词序列的语法检查和结构分析,进一步掌握递归下降的语法分析方法。
三、实验要求:
利用C语言编制递归下降分析程序,并对Training语言进行语法分析。
待分析的Training语言语法。
用扩充的表示如下:
<程序>-->function<语句串>endfunc
<语句串>--><语句>{;<语句>}
<语句>?<赋值语句>
<赋值语句>?ID?<表达式>
<表达式>?<项>{+<项>|-<项>}
<项>?<因子>{*<因子>|/<因子>}
<因子>?ID|NUM|(<表达式>)
备注:实验当中 我对程序进行了扩展,增加了程序识别if条件判断语句,while循环语句的功能
实验要求说明
输入单词串以“#”结束,如果是文确的句子,则输出成功信息,打印“success”,否则输出“error”。
四、程序流程图
主函数:
Scanner()函数:
irparser()函数
yucu() /*语句串分析*/
statement()/*语句分析函数*/
expression()/*表达式分析函数*/
term()/*项分析函数*/
factor()/*因子分析函数*/
五、程序代码:
递归下降分析文法:
<程序>-->function< 语句串 >endfunc
<语句串>--><语句>{ ;<语句> }
<语句>à<赋值语句> |<if条件语句> | <while循环语句>
<赋值语句>à <表达式>
<表达式>à<项>{ +<项> | -<项> }
<项>à<因子>{*<因子>|/<因子>}
<因子>àID | NUM | (<表达式>)
<if条件语句>?(<表达式>)| (ID) |(NUM)?<语句>
<while条件循环语句>?(<表达式>)| (ID) |(NUM)?<语句>
备注:红色字体部分为我对代码实现功能的主要修改与扩展部分。
/*语法分析源代码*/
#include<stdio.h>
#include<string.h>
char prog[80],token[8];
char ch;
int syn,p,m=0,n,sum,kk=0;
char *rwtab[6]={"function","if","then","while","do","endfunc"};
void yucu();
void expression();
void statement();
void factor();
void term();
void irparser();
void scaner()
{ for (n=0;n<8;n++)
token[n]=NULL;
while(ch==' ' || ch=='\n')
ch=prog[p++];
m=0;
if((ch<='z' && ch>='a') || (ch<='Z' && ch>='A'))
{while((ch<='z' && ch>='a') || (ch<='Z' && ch>='A') || (ch<='9' && ch>='0'))
{token[m++]=ch;
ch=prog[p++];
}
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{ syn=n+1;
break;
}
token[m++]='\0';}
else
if(ch<='9' && ch>='0')
{ sum=0;
while(ch<='9' && ch>='0')
{ sum=sum*10+ch-'0';
ch=prog[p++];
}
syn=11;
}
else
{ switch(ch)
{ case'<':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{syn=22;
token[m+1]=ch;}
else
{syn=20;ch=prog[--p];}
break;
case'>':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{ syn=24;
token[m++]=ch;
}
else
{syn=23;p--;
}
break;
case'=' :m= 0;token[m ++ ]=ch;
ch=prog[p++];
if(ch=='=')
{ syn= 25;
token[m++]= ch;
}
else
{syn=18;
ch=prog[--p];
}
break;
case'!':m=0; token[m++]= ch;
ch=prog[++p];
if(ch=='=')
{ syn=22;
token[m++]= ch;
}
else
syn=-1;
break;
case'+':syn=13; token[0]=ch;break;
case'-':syn=14; token[0]=ch;break;
case'*':syn=15; token[0]=ch;break;
case'/':syn=16; token[0]=ch;break;
case';':syn=26; token[0]=ch;break;
case'(':syn=27; token[0]=ch;break;
case')':syn=28; token[0]=ch;break;
case'#':syn=0; token[0]=ch;break;
default:syn=-1;//break;
}
ch=prog[p++];
} }
void irparser()
{ if(syn==1)
{ scaner();
yucu();/*语句串分析*/
if(syn==6) /*读到endfunc*/
{ scaner();
if(syn==0&&kk==0)/*程序分析识别完*/
printf("success");
}
else
{ if(kk!=1) /*没以endfunc结束*/
{ printf("error!need 'endfunc'");
kk=1;
}
}
}
else
{ printf("error!need'function'");
kk=1;
}
}
void yucu() /*语句串分析*/
{ statement();/*调用语句分析函数*/
while(syn==26)/*一个语句识别结束,继续识别*/
{ scaner();
statement();
}
return;
}
void statement()/*语句分析函数*/
{ if(syn==10)
{ scaner();
if(syn==18) //如果是赋值语句
{ scaner();
expression();
} //这个过程实现语法分析判断语句
else
{ printf("error!evaluate tag error");
kk=1;
}
}
else
if(syn==6)
return;
else
if(syn==2) //如果是条件判断语句 就判断条件表达式的语法!
{ scaner();
if(syn==27) //判断括号匹配
{do
{scaner(); //进入括号部进行表达式分析
expression();
}while(syn!=28);
}
else { printf("error! need another')'");
kk=1;
} //()判断完成 !
scaner(); //然后进行语句块分析!
statement();
} //到这里是实现判断if语句的语法分析
// 类似的往里添加 循环语句!
else
if(syn==4) //如果是循环语句 就判断条件表达式的语法!
{ scaner();//ch=prog[p++];
if(syn==27)
{ do
{scaner();
expression();
}while(syn!=28);
}
else {
printf("error! need another')'");
kk=1; } //()判断完成 !
scaner(); //然后进行语句块分析!
statement();
} //这里是实现判断while语句的语法分析
else
{ printf("error!the statement error!");
kk=1;
}
}
void expression()/*表达式分析函数*/
{ term();
while(syn==13||syn==14)
{ scaner();
term(); }
return;
}
void term()/*项分析函数*/
{ factor();
while(syn==15||syn==16)
{ scaner();
factor();}
return;
}
void factor()/*因子分析函数*/
{ if(syn==10||syn==11)
{ scaner(); }
else/*看是否是表达式*/
{ expression();
if(syn==27)
{ scaner();
expression();
if(syn==28)
{ scaner();}
else
{ printf("error! need another')'");
kk=1;
}
}
else
{ printf("error! expression error!");
}
}
}
void main()
{ p=0;
printf("\n please input the string:\n");
do
{ ch=getchar();
prog[p++]=ch;
} while(ch!='#');
p=0;
ch=prog[p++];
scaner();
irparser();
}
六、测试用例
测试用例1
输出结果
测试用例2
输出结果
测试用例3
输出结果
function
a=1;
b=2;
c=a+b;
endfunc
#
success
function
if(3>1)
a=1;
endfunc
#
success
function
if(a>b)
a=1;
while(a>1)
b=1;
endfunc
#
success
测试用例4
a=1
endfunc
#
输出结果
error!need'function'Press any key to continue
七、输出结果
测试用例1
测试用例2
测试用例4
测试用例3
八、实验心得
通过编译原理实验二语法分析实验,使得自己对语法分析的流程有了更深刻的了解,使得语法分析递归向下思想更加具体化,虽然源代码并非由自己设计,但是在调试程序的过程中,逐步理解程序递归下降思想,思路不断理清,不仅理解了程序分析赋值语句的算法,同时在这基础上,我对程序做了功能扩展,增加了语法分析条件判断语句和while条件循环语句,即是程序中红色字体部分。在调试与算法功能扩展的过程中,理清了语法分析程序的思路。从一开始对程序的陌生,到后来逐步了解程序的流程,当我耐心的一步一步理解程序思想,一次次的更改测试用例,一遍遍的调试,最终终于得到了预期的答案。这次实验使我对理论的语法分析递归下降的理解更加具体清晰,受益匪浅。
相关热词搜索: 实验 语法 报告 分析