语义分析实验报告

华 南 农 业 大 学 信 息 学 院

综合性、设计性实验成绩单

开设时间: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张三


相关内容

  • 认知心理学
  • 一.1.信息加工系统由感受器,效应器,记忆,加工器组成.功能:输入,输出,贮存,复制,建立符号结构和条件性迁移. 符号和符号系统是外部事物的内部表征. 2减法反应时实验:唐德斯:实验中安排两种不同的反应时作业,其中一种作业包含另一种作业所没有的某个心理过程,即所要测量的过程,这两种反应时的差即为该过 ...

  • 检索语言在医学信息管理与检索中的应用综述
  • 作者:陈永莉洪漪 图书情报知识 2015年09期 [中图分类号]G254.24:G354 [文献标识码]A [文章编号]1003-2797(2015)03-0072-08 DOI:10.13366/j.dik.2015.03.072 1 引言 近些年来,信息技术和网络技术的飞速发展大大推动了医学信息 ...

  • 编译原理 语义分析
  • 编译原理实验报告 姓名:闫梦丽班级:软件工程学号:日期: 语 义 分 析 器 0901 0908010101 2012年4月 1.题目要求: 1.1实验目的 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法. 1.2实验原理 采用递归下降语法制导 ...

  • 认知心理学试题库(不分套删除重复)
  • 认知心理学试题库 一.单选题(每题1分,共10分) 1( )是由有关知觉对象的一般知识开始的加工,由此可以形成期望或对知觉态度的假设,这种期望或假设制约着加工的所有阶段或水平. A.自下而上加工 B.局部加工 C.整体加工 D.自上而下加工 答案:D 2( )注意模型能够较好地解释"鸡尾酒 ...

  • 1记忆的加工水平实验报告
  • 记忆的加工水平实验报告 摘要: 本实验将通过再认测验和知觉辨认测验考察不同的加工水平对外显记忆和内隐记忆的影响,从而验证加工水平与记忆持久性的关系以及加工提取的一致性.根据前人的研究结果,预期本实验中,由于三种学习方式加工水平逐渐加深,再认率与虚报率之差(外显记忆量)会随之升高:而知觉辨认的旧词与新 ...

  • 认知心理学重点整理
  • 学习指导: 第一章:绪论 1.认知心理学的定义 认知心理学有广义和狭义两种涵义 广义的认知心理学主要探讨人类内部心理活动过程.个体认知的发生与发展,以及对人的心理事件.心理表征和信念.意向等心理活动的研究. 狭义的认知心理学,是以信息加工理论观点为核心的心理学,又被称为信息加工心理学.本书中的内容以 ...

  • stroop效应对记忆的影响
  • stroop 效应对记忆的影响 摘要:为了了解stroop 效应是否对记忆有影响,具体影响记忆加工的那个过程,对近代对stroop 效应的研究以及对记忆的研究进行分析. 关键词:stroop 效应.记忆.记忆加工 引言 1935年stroop 效应在颜色命名实验中被发现.整个记忆过程分为编码.储存. ...

  • 长时记忆的编码
  • 长时记忆的习得 识记是长时记忆习得信息的主要方式.常言说,欲忆必先记,只有对外界信息的感知或反复感知.思考.体验和操作,进行充分的和有一定深度的心理加工,才能在头脑中长时间地保持下来.依据主体有无明确的识记意图和目的,是否付出意志的努力,识记分为无意识记和有意识记. 1.无意识记与有意识记 无意识记 ...

  • 人对世界的认识-记忆
  • 第七章 记忆 本章目标 理解记忆的结构和过程. 了解心理学对记忆机制的研究. 理解感觉记忆.短时记忆.长时记忆之间的关系. 明白外显记忆和内隐记忆的关系. 有效利用遗忘规律,提高记忆效果. 第一节 一. 记忆的一般概念 什么是记忆? 在头脑中积累和保持个体经验的心理过程就是记忆. 从加 ...