华 南 农 业 大 学 信 息 学 院
综合性、设计性实验成绩单
开设时间:2009学年第二学期
教师签名:
所分析语法结构的词法说明:
下面有提及,不再重复。
上下文无关文法描述:
不了解。
翻译模式:
只对表达式、赋值语句进行翻译。
单词的种别编码方案:
begin syn=1 if syn=2 then syn=3 while syn=4 do syn=5 end syn=6
letter(letter|digit)* syn=10 digit digit* syn=11 + syn=13 - syn=14 * syn=15 / syn=16 : syn=17 := syn=18 syn=21 syn=23 >= syn=24 = syn=25 ; syn=26 ( syn=27 ) syn=28 # syn=0
语法语义分析程序的主要算法思想:
所采用的语法语义分析方法的算法思想的详细描述:
(1) 设置语义过程:
1----------------- emit(char *result,char *ag1,char *op,char *ag2)
//该函数的功能是生成一个三地址语句送到四元式表中
void emit(char *result,char *ag1,char *op,char *ag2) { strcpy(quad[yy].result,result); strcpy(quad[yy].ag1,ag1); strcpy(quad[yy].op,op); strcpy(quad[yy].ag2,ag2); yy++;
}
//四元表的结构如下 struct { char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20];
2------------------------*newtemp()
//该函数回送一个新的临时变量名,临时变量名的产生顺序为T1,T2`````````` char *newtemp() { char *pe; char md[8]; pe=(char*)malloc(8); ko+=1; itoa(ko,md,10); //将十进制数字转换成字母的函数 strcpy(pe+1,md); pe[0]='t'; return(pe); }
(2)主程序示意图:
(2) 函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元
式序列。在实验中我们只对表达式、赋值语句进行翻译。
源程序:
#include #include #include
#include "conio.h" /*提供有关屏幕窗口操作函数*/ #include "ctype.h"
char prog[80]={'\0'}, token[8]; // prog是缓冲区,token是单词自身的字符串 char ch;
int syn, p, m, n, sum; // syn是单词种别码,p是缓冲区prog的指针,m是token的指针 char *rwtab[6] = {"begin", "if", "then", "while", "do", "end"};
void scaner();
int Irparser(); int yucu();
int statement(); char *expression(); char *term(); char *factor();
char *newtemp();
void emit(char *result,char *ag1,char *op,char *ag2); //void itoa(int a,char *b,int c);
int kk=0;
int yy=0;
//四元表的结构 struct { char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20];
int main() {
p=0;
printf("\nplease input string:\n"); do {
ch=getchar(); prog[p++]=ch; }while(ch!='#'); p=0; for(int j=0;j
do { scaner(); //调用scaner()读取下一个单词符号 Irparser(); //调用irparser() } while (syn != 0); for(int y=0;y
printf("(%d) %s = %s%c%s",y+1,quad[y].result,quad[y].ag1,quad[y].op[0],quad[y].ag2); printf("\n"); } return 0; }
//-------------------------------------------------------------------------------------------------------------------------------------------
char *factor() { char *fplace; fplace=(char *)malloc(12); strcpy(fplace," "); if(syn==10) //字符 { strcpy(fplace,token); //将标识符token的值赋给fplace scaner(); //调用scaner()读取下一个单词符号 } else if(syn==11) //数字 { itoa(sum,fplace,10);//?
scaner(); //调用scaner()读取下一个单词符号 } else if(syn==27) // (
{
scaner(); //调用scaner()读取下一个单词符号
fplace=expression();
if(syn==28) // )
scaner(); //调用scaner()读取下一个单词符号
else
{
printf("')' is error\n");
kk=1;
}
}
else
{
printf("error!");
kk=1;
}
return(fplace);
}
char *term()
{
char *tp,*ep2,*eplace,*tt;
tp=(char*)malloc(12);
ep2=(char*)malloc(12);
eplace=(char*)malloc(12);
tt=(char*)malloc(12);
strcpy(eplace," ");
strcpy(ep2," ");
strcpy(tt," ");
strcpy(ep2,factor()); //factor()
while(syn==15||syn==16) //*
{
if(syn==15)
{
tt[0]='*'; or /
tt[1]=' ';
}
else
{
tt[0]='/';
tt[1]=' ';
}
scaner(); //调用scaner()读取下一个单词符号
//printf("\n%s\n",eplace);
strcpy(eplace,factor());
strcpy(tp,newtemp());
// strcpy(eplace,quad[yy-1].result);
emit(tp,ep2,tt,eplace); //生成四元式送入四元式表
strcpy(ep2,tp);
}
// printf("\n%s\n",eplace);
return(ep2);
}
char *expression()
{
char *tp,*ep2,*eplace,*tt;
tp=(char*)malloc(12);
ep2=(char*)malloc(12);
eplace=(char*)malloc(12);
tt=(char*)malloc(12);
strcpy(eplace,term()); //term()
strcpy(tt," ");
while(syn==13||syn==14) //+ or -
{
if(syn==13)
{
tt[0]='+';
tt[1]=' ';
}
else
{
tt[0]='-';
tt[1]=' ';
}
scaner(); //调用scaner()读取下一个单词符号
strcpy(ep2,term());
strcpy(tp,newtemp());
emit(tp,eplace,tt,ep2); //生成四元式送入四元式表
strcpy(eplace,tp);
}
//printf("\n%s\n",eplace);
return(eplace);
}
int statement()
{
char tt[8],eplace[8];
int schain=0;
if(syn==10) //字符
{
strcpy(tt,token);
scaner(); //调用scaner()读取下一个单词符号
if(syn==18) //:=
{
scaner(); //调用scaner()读取下一个单词符号
strcpy(eplace,expression());
emit(tt,eplace," "," "); //生成四元式送入四元式表
schain=0;
}
else
{
printf("赋值错误\n");
kk=1;
}
}
else
{
printf("语句错误\n");
kk=1;
}
return(schain);
}
int yucu()
{
int schain=0;
schain=statement();
while(syn==26) // ;
{
scaner(); //调用scaner()读取下一个单词符号
schain=statement();
}
return (schain);
}
int Irparser()
{
int schain=0;
kk=0;
if(syn==1) // begin
{
scaner(); //调用scaner()读取下一个单词符号
schain=yucu();
if(syn==6) //end
{
scaner(); //调用scaner()读取下一个单词符号
if(syn==0&&(kk==0)) //#
printf("success!\n");
}
else if(kk!=1)
{
printf("缺end error!\n");
kk=1;
}
}
else
{
printf("'begin' error!\n");
kk=1;
}
return(schain);
}
//---------------------------------------------------------------------------------
void scaner(){
m=0;
sum=0;
for(n=0;n
token[n]='\0';
ch=prog[p++];
while(ch==' ')
ch=prog[p++];
if(isalpha(ch)) /*ch为字母字符*/{
while(isalpha(ch)||isdigit(ch)) /*ch 为字母字符或者数字字符*/{
token[m++]=ch;
ch=prog[p++];}
token[m++]='\0';
ch=prog[p--];
syn=10;
for(n=0;n
if(strcmp(token,rwtab[n])==0) /*字符串的比较*/{
syn=n+1;
break;}}
else
if(isdigit(ch)) /*ch是数字字符*/{
while(isdigit(ch)) /*ch是数字字符*/{
sum=sum*10+ch-'0';
ch=prog[p++];}
ch=prog[p--];
syn=11;}
else
switch(ch){
case'
if(ch=='>'){
syn=21;
token[m++]=ch;}
else if(ch=='='){
syn=22;
token[m++]=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;
ch=prog[p--];}
break;
case':':m=0;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=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;}}
//------------------------------------------------------------------------------------------------------------
int ko=0;
//该函数回送一个新的临时变量名,临时变量名的产生顺序为T1,T2``````````
char *newtemp()
{
char *pe;
char md[8];
pe=(char*)malloc(8);
ko+=1;
itoa(ko,md,10); //将十进制数字转换成字母的函数
strcpy(pe+1,md);
pe[0]='t';
return(pe);
}
//该函数的功能是生成一个三地址语句送到四元式表中
void emit(char *result,char *ag1,char *op,char *ag2)
{
strcpy(quad[yy].result,result);
strcpy(quad[yy].ag1,ag1);
strcpy(quad[yy].op,op);
strcpy(quad[yy].ag2,ag2);
yy++;
}
程序运行说明文件:
先输入begin,然后空格,再输入程序语句串,再输入“;”
接着输入你的下面的语句串,不过最后的那一条就不用加“;”了。
最后再输入“end #”即可
注意:因为没有设置输入任意键继续,所以程序一输出完毕即会结束,所以要看的
话建议把程序先编译再试!
测试数据:
1输入: begin a:=2+3*4; x:=(a+b)/c end #
输出:
2输入 begin a:=a+3*3*3 end #
输出:
3输入 begin a:=4+3-1*(t+1); b=a+2 end #
输出:
输入:begin h:=t-1;b:=a+3*5;h=h+t end #
输出:
上交时间: 第14周
上交内容:全部采用电子版,包括源程序、可执行程序、程序运行说明文件、测试数据、实验报告
每位同学用一个目录保存上述内容,目录名以学号+姓名的方式,如:2007201001张三
华 南 农 业 大 学 信 息 学 院
综合性、设计性实验成绩单
开设时间:2009学年第二学期
教师签名:
所分析语法结构的词法说明:
下面有提及,不再重复。
上下文无关文法描述:
不了解。
翻译模式:
只对表达式、赋值语句进行翻译。
单词的种别编码方案:
begin syn=1 if syn=2 then syn=3 while syn=4 do syn=5 end syn=6
letter(letter|digit)* syn=10 digit digit* syn=11 + syn=13 - syn=14 * syn=15 / syn=16 : syn=17 := syn=18 syn=21 syn=23 >= syn=24 = syn=25 ; syn=26 ( syn=27 ) syn=28 # syn=0
语法语义分析程序的主要算法思想:
所采用的语法语义分析方法的算法思想的详细描述:
(1) 设置语义过程:
1----------------- emit(char *result,char *ag1,char *op,char *ag2)
//该函数的功能是生成一个三地址语句送到四元式表中
void emit(char *result,char *ag1,char *op,char *ag2) { strcpy(quad[yy].result,result); strcpy(quad[yy].ag1,ag1); strcpy(quad[yy].op,op); strcpy(quad[yy].ag2,ag2); yy++;
}
//四元表的结构如下 struct { char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20];
2------------------------*newtemp()
//该函数回送一个新的临时变量名,临时变量名的产生顺序为T1,T2`````````` char *newtemp() { char *pe; char md[8]; pe=(char*)malloc(8); ko+=1; itoa(ko,md,10); //将十进制数字转换成字母的函数 strcpy(pe+1,md); pe[0]='t'; return(pe); }
(2)主程序示意图:
(2) 函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元
式序列。在实验中我们只对表达式、赋值语句进行翻译。
源程序:
#include #include #include
#include "conio.h" /*提供有关屏幕窗口操作函数*/ #include "ctype.h"
char prog[80]={'\0'}, token[8]; // prog是缓冲区,token是单词自身的字符串 char ch;
int syn, p, m, n, sum; // syn是单词种别码,p是缓冲区prog的指针,m是token的指针 char *rwtab[6] = {"begin", "if", "then", "while", "do", "end"};
void scaner();
int Irparser(); int yucu();
int statement(); char *expression(); char *term(); char *factor();
char *newtemp();
void emit(char *result,char *ag1,char *op,char *ag2); //void itoa(int a,char *b,int c);
int kk=0;
int yy=0;
//四元表的结构 struct { char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20];
int main() {
p=0;
printf("\nplease input string:\n"); do {
ch=getchar(); prog[p++]=ch; }while(ch!='#'); p=0; for(int j=0;j
do { scaner(); //调用scaner()读取下一个单词符号 Irparser(); //调用irparser() } while (syn != 0); for(int y=0;y
printf("(%d) %s = %s%c%s",y+1,quad[y].result,quad[y].ag1,quad[y].op[0],quad[y].ag2); printf("\n"); } return 0; }
//-------------------------------------------------------------------------------------------------------------------------------------------
char *factor() { char *fplace; fplace=(char *)malloc(12); strcpy(fplace," "); if(syn==10) //字符 { strcpy(fplace,token); //将标识符token的值赋给fplace scaner(); //调用scaner()读取下一个单词符号 } else if(syn==11) //数字 { itoa(sum,fplace,10);//?
scaner(); //调用scaner()读取下一个单词符号 } else if(syn==27) // (
{
scaner(); //调用scaner()读取下一个单词符号
fplace=expression();
if(syn==28) // )
scaner(); //调用scaner()读取下一个单词符号
else
{
printf("')' is error\n");
kk=1;
}
}
else
{
printf("error!");
kk=1;
}
return(fplace);
}
char *term()
{
char *tp,*ep2,*eplace,*tt;
tp=(char*)malloc(12);
ep2=(char*)malloc(12);
eplace=(char*)malloc(12);
tt=(char*)malloc(12);
strcpy(eplace," ");
strcpy(ep2," ");
strcpy(tt," ");
strcpy(ep2,factor()); //factor()
while(syn==15||syn==16) //*
{
if(syn==15)
{
tt[0]='*'; or /
tt[1]=' ';
}
else
{
tt[0]='/';
tt[1]=' ';
}
scaner(); //调用scaner()读取下一个单词符号
//printf("\n%s\n",eplace);
strcpy(eplace,factor());
strcpy(tp,newtemp());
// strcpy(eplace,quad[yy-1].result);
emit(tp,ep2,tt,eplace); //生成四元式送入四元式表
strcpy(ep2,tp);
}
// printf("\n%s\n",eplace);
return(ep2);
}
char *expression()
{
char *tp,*ep2,*eplace,*tt;
tp=(char*)malloc(12);
ep2=(char*)malloc(12);
eplace=(char*)malloc(12);
tt=(char*)malloc(12);
strcpy(eplace,term()); //term()
strcpy(tt," ");
while(syn==13||syn==14) //+ or -
{
if(syn==13)
{
tt[0]='+';
tt[1]=' ';
}
else
{
tt[0]='-';
tt[1]=' ';
}
scaner(); //调用scaner()读取下一个单词符号
strcpy(ep2,term());
strcpy(tp,newtemp());
emit(tp,eplace,tt,ep2); //生成四元式送入四元式表
strcpy(eplace,tp);
}
//printf("\n%s\n",eplace);
return(eplace);
}
int statement()
{
char tt[8],eplace[8];
int schain=0;
if(syn==10) //字符
{
strcpy(tt,token);
scaner(); //调用scaner()读取下一个单词符号
if(syn==18) //:=
{
scaner(); //调用scaner()读取下一个单词符号
strcpy(eplace,expression());
emit(tt,eplace," "," "); //生成四元式送入四元式表
schain=0;
}
else
{
printf("赋值错误\n");
kk=1;
}
}
else
{
printf("语句错误\n");
kk=1;
}
return(schain);
}
int yucu()
{
int schain=0;
schain=statement();
while(syn==26) // ;
{
scaner(); //调用scaner()读取下一个单词符号
schain=statement();
}
return (schain);
}
int Irparser()
{
int schain=0;
kk=0;
if(syn==1) // begin
{
scaner(); //调用scaner()读取下一个单词符号
schain=yucu();
if(syn==6) //end
{
scaner(); //调用scaner()读取下一个单词符号
if(syn==0&&(kk==0)) //#
printf("success!\n");
}
else if(kk!=1)
{
printf("缺end error!\n");
kk=1;
}
}
else
{
printf("'begin' error!\n");
kk=1;
}
return(schain);
}
//---------------------------------------------------------------------------------
void scaner(){
m=0;
sum=0;
for(n=0;n
token[n]='\0';
ch=prog[p++];
while(ch==' ')
ch=prog[p++];
if(isalpha(ch)) /*ch为字母字符*/{
while(isalpha(ch)||isdigit(ch)) /*ch 为字母字符或者数字字符*/{
token[m++]=ch;
ch=prog[p++];}
token[m++]='\0';
ch=prog[p--];
syn=10;
for(n=0;n
if(strcmp(token,rwtab[n])==0) /*字符串的比较*/{
syn=n+1;
break;}}
else
if(isdigit(ch)) /*ch是数字字符*/{
while(isdigit(ch)) /*ch是数字字符*/{
sum=sum*10+ch-'0';
ch=prog[p++];}
ch=prog[p--];
syn=11;}
else
switch(ch){
case'
if(ch=='>'){
syn=21;
token[m++]=ch;}
else if(ch=='='){
syn=22;
token[m++]=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;
ch=prog[p--];}
break;
case':':m=0;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=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;}}
//------------------------------------------------------------------------------------------------------------
int ko=0;
//该函数回送一个新的临时变量名,临时变量名的产生顺序为T1,T2``````````
char *newtemp()
{
char *pe;
char md[8];
pe=(char*)malloc(8);
ko+=1;
itoa(ko,md,10); //将十进制数字转换成字母的函数
strcpy(pe+1,md);
pe[0]='t';
return(pe);
}
//该函数的功能是生成一个三地址语句送到四元式表中
void emit(char *result,char *ag1,char *op,char *ag2)
{
strcpy(quad[yy].result,result);
strcpy(quad[yy].ag1,ag1);
strcpy(quad[yy].op,op);
strcpy(quad[yy].ag2,ag2);
yy++;
}
程序运行说明文件:
先输入begin,然后空格,再输入程序语句串,再输入“;”
接着输入你的下面的语句串,不过最后的那一条就不用加“;”了。
最后再输入“end #”即可
注意:因为没有设置输入任意键继续,所以程序一输出完毕即会结束,所以要看的
话建议把程序先编译再试!
测试数据:
1输入: begin a:=2+3*4; x:=(a+b)/c end #
输出:
2输入 begin a:=a+3*3*3 end #
输出:
3输入 begin a:=4+3-1*(t+1); b=a+2 end #
输出:
输入:begin h:=t-1;b:=a+3*5;h=h+t end #
输出:
上交时间: 第14周
上交内容:全部采用电子版,包括源程序、可执行程序、程序运行说明文件、测试数据、实验报告
每位同学用一个目录保存上述内容,目录名以学号+姓名的方式,如:2007201001张三