cin>>data;
p=0;w=0;j=0;//所有全局变量重新初始化
e=1;i=0;d=0;
//exit(0);
}
voiddeal(){
check(data[0]);//判断输入的首字母是否是数字
deal_integer(data[i]);//处理识别符的整数部分
if(data[i]=='.')
{deal_point(data[++i]);//用来处理小数部分
if(data[i]=='e'||data[i]=='E')//如果是e或E时
deal_index(data[++i]);//用来处理指数部分
elseif(data[i]!
='\0')
{error();//错误处理程序
deal();//处理函数主体
}
elses_next();//确定实型
}
else{if(data[i]=='e'||data[i]=='E')//如果是e或E时
{deal_index(data[++i]);//用来处理指数部分
//CJ1="整型";
}
elseif(data[i]!
='\0'){//非结束标志
error();//错误处理程序
deal();//处理函数主体
}
else
z_next();//确定整型
}
}
四.实验结果截图:
本科实验报告
课程名称:
编译原理
实验项目:
逆波兰式生成程序
实验地点:
迎西校区4506机房
专业班级:
学号:
学生姓名:
指导教师:
2012年5月
一.实验内容
掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序。
二.实验要求
将非后缀式用来表示的算术表达式转换为用逆波兰式来表示的算术表达式。
三.实验过程
1、逆波兰式生成的实验设计思想及算法
(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:
将该字符与运算符栈顶的运算符的优先关系相比较。
如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。
(5)重复上述操作
(1)-
(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
2.实验的源程序代码如下:
#include
#include
#definemax100
charex[max];/*存储后缀表达式*/
voidtrans(){/*将算术表达式转化为后缀表达式*/
charstr[max];/*存储原算术表达式*/
charstack[max];/*作为栈使用*/
charch;
intsum,i,j,t,top=0;
printf("*****************************************\n");
printf("*输入一个求值的表达式,以#结束。
*\n");
printf("******************************************\n");
printf("算数表达式:
");
i=0;/*获取用户输入的表达式*/
do{
i++;
scanf("%c",&str[i]);
}while(str[i]!
='#'&&i!
=max);
sum=i;
t=1;i=1;
ch=str[i];i++;
while(ch!
='#'){
switch(ch){
case'(':
/*判定为左括号*/
top++;stack[top]=ch;
break;
case')':
/*判定为右括号*/
while(stack[top]!
='('){
ex[t]=stack[top];top--;t++;
}
top--;
break;
case'+':
/*判定为加减号*/
case'-':
while(top!
=0&&stack[top]!
='('){
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case'*':
/*判定为乘除号*/
case'/':
while(stack[top]=='*'||stack[top]=='/'){
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case'':
break;
default:
while(ch>='0'&&ch<='9'){/*判定为数字*/
ex[t]=ch;t++;
ch=str[i];i++;
}
i--;
ex[t]='#';t++;
}
ch=str[i];i++;
}
while(top!
=0){
ex[t]=stack[top];t++;top--;
}
ex[t]='#';
printf("\n\t原来表达式:
");
for(j=1;jprintf("%c",str[j]);
printf("\n\t后缀表达式:
",ex);
for(j=1;jprintf("%c",ex[j]);
}
voidcompvalue(){/*计算后缀表达式的值*/
floatstack[max],d;/*作为栈使用*/
charch;
intt=1,top=0;/*t为ex下标,top为stack下标*/
ch=ex[t];t++;
while(ch!
='#'){
switch(ch){
case'+':
stack[top-1]=stack[top-1]+stack[top];
top--;
break;
case'-':
stack[top-1]=stack[top-1]-stack[top];
top--;
break;
case'*':
stack[top-1]=stack[top-1]*stack[top];
top--;
break;
case'/':
if(stack[top]!
=0)
stack[top-1]=stack[top-1]/stack[top];
else{
printf("\n\t除零错误!
\n");
exit(0);/*异常退出*/
}
top--;
break;
default:
d=0;
while(ch>='0'&&ch<='9'){
d=10*d+ch-'0';/*将数字字符转化为对应的数值*/
ch=ex[t];t++;
}
top++;
stack[top]=d;
}
ch=ex[t];t++;
}
printf("\n\t计算结果:
%g\n",stack[top]);
}
main(){
trans();
compvalue();
}
3.程序的运行结果如下:
四.实验总结(心得)
通过本实验的学习,主要掌握了逆波兰式算法的含义,结合书本知识,让我更加清楚此算法实现的主要过程,以及使用该算法的好处,通过对程序实现的分析,对于逆波兰式算法的细节了解的更加清楚,从中学到了很多的东西。
本科实验报告
课程名称:
编译原理
实验项目:
语法分析程序的设计
实验地点:
迎西校区4506机房
专业班级:
学号:
学生姓名:
指导教师:
2012年5月
一、实验目的与要求
通过设计、编制、调试一个典型的语法分析程序(任选有代表性的语法分析方法,如算符优先法、递归下降法、LL
(1)、SLR
(1)、LR
(1)等,作为编制语法分析程序的依据),对扫描器所提供的单词序列进行语法检查和结构分析,实现并进一步掌握常用的语法分析方法。
二、实验内容
选择对各种常见高级程序设计语言都较为通用的语法结构作为分析对象,给出其文法描述(注意应与所采用的语法分析方法比较贴近),设计并实现一个完整的语法分析程序。
输入:
源程序以文件的形式输入。
输出:
对于所输入的源程序,如果输入符号串是给定文法定义的合法句子,则输出“RIGHT”,并且给出每一步归约的过程;如果不是句子,即输入串有错误,则输出“ERROR”,并且显示已经归约出的各个文法符号。
三、基本实验题目
以如下文法G1所定义的算术表达式的赋值语句作为分析对象,编写并调试一个语法分析程序。
G1[<赋值语句>]:
<赋值语句>→<变量>:
=<算术表达式>
<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项>
<项>→<因式>|<项>*<因式>|<项>/<因式>
<因式>→<变量>|<常数>|(<算术表达式>)
<变量>→<标识符>
<标识符>→<标识符><字母>|<标识符><数字>|<字母>
<常数>→<整数>|<浮点数>
<整数>→<数字>|<数字><整数>
<浮点数>→•<整数>|<整数>•<整数>
<字母>→A|B|C|…|X|Y|Z|a|b|c|…|x|y|z
<数字>→0|1|2|…9
四、源程序
#include
usingnamespacestd;
#include
#include
#defineMAX150//词法分析表的最大容量
#defineMAXBUF255//缓冲区的最大缓冲量
voidterm();
voidlrparser();
voidstatement();
voidyucu();
voidexpression();
voidfactor();
charprog[MAXBUF],token[MAX];
charch;
intsyn,p,m,n,sum,kk;
char*rwtab[6]={"begin","if","then","while","do","end"};
//////////////////////////////////////////////////////////
/*词法扫描程序:
*/
voidscaner()
{
for(m=0;mtoken[m]=NULL;
m=0;sum=0;
ch=prog[p++];
while(ch=='')ch=prog[p++];
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++];//读取下一个字符
}
token[m++]='\0';
ch=prog[--p];
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;//给出syn值
break;
}
}
else
if((ch<='9'&&ch>='0'))
{
sum=0;
while((ch<='9'&&ch>='0'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
ch=prog[--p];
syn=11;
}
else
switch(ch)
{
case'<':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else
if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
ch=prog[--p];
}
break;
case'>':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
ch=prog[--p];
}
break;
case':
':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
ch=prog[--p];
}
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=18;token[0]=ch;break;
case'<>':
syn=21;token[0]=ch;break;
case'<=':
syn=22;token[0]=ch;break;
case'>=':
syn=24;token[0]=ch;break;
case'=':
syn=25;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;
}
}
///////////////////////////////////////////////////////
voidstatement()
{
if(syn==10)
{
scaner();//读下一个单词符号
if(syn==18)
{
scaner();//读下一个单词符号
expression();//调用expression函数
}
else
{
printf("error!
");
kk=1;
}
}
else
{
printf("error!
");
kk=1;
}
return;
}
////////////////////////////////////////////////////////
voidexpression()
{
term();
while(syn==13||syn==14)
{
scaner();
term();
}
return;
}
///////////////////////////////////////////////////////
voidterm()
{
factor();
while(syn==15||syn==16)
{
scaner();
factor();
}
return;
}
//////////////////////////////////////////////////////
voidlrparser()
{
if(syn==1)//begin
{
scaner();
yucu();
if(syn==6)//end
{
scaner();
if(syn==0&&kk==0)printf("success\n");
}
else
{
if(kk!
=1)printf("error,lose'end'!
\n");
kk=1;
}
}
else
{
printf("error,lose'begin'!
\n");
kk=1;
}
return;
}
/////////////////////////////////////////////////////
voidyucu()
{
statement();
while(syn==26)//;
{
scaner();
statement();
}
return;
}
/////////////////////////////////////////////////////
voidfactor()
{
if(syn==10||syn==11)scaner();//为标识符或整常数时,读下一个单词符号
elsei