语义分析实验报告(实验三)

语义分析实验报告(实验三)
语义分析实验报告(实验三)

编译原理语义分析实验报告

软工082班

兰洁

200831104044

一、实验内容

二、实验目的

三、实验要求

四、程序流程图

五、程序代码与主要过程说明

六、测试用例

七、输出结果

八、实验心得

一、实验内容

定义模拟的简单语言的语义成分,将语义分析程序编制成一个子程序,在实验2分析出个语法单位后,分析其含义,并将可执行语句或表达式翻译成四元式输出,并将错误信息输出。

二、实验目的

通过上机实验,加深对语义制导翻译原理的理解,掌握将语法分析所识别的语法成分变换成为中间代码的语义翻译方法。

三、实验要求

采用递归下降语法制导翻译方法,对算术表达式、赋值语句进行语义分析并生成四元式序列。

例如:对于语句串

Function

a=2+3*4;

x=(a+b)/c;

endfunc

#

输出的三地址指令如下

●t1=3*4

●t2=2+t1

●a=t2

●t3=a+b

●t4=t3/c

●x=t4

四、程序流程图

由于语义分析的的方法就是在语法分析过程中,根据每个产生式所对应的语义子程序进行翻译,为每个产生式配上一个翻译子程序,并在语法分析的同时执行这些子程序。所有对应的流程图与语法分析流程图大同小异,关于各类函数的流程图我已经在词法分析报告与语法分析报告中详细画出,所以这里只说明程序主要流程。

五、程序代码与主要过程说明

/*语义分析源代码*/

# include

# include

# include

# include

# include

struct quad // 四元式表{ char result[12];

char ag1[12];

char op[12];

char ag2[12];

};

struct quad quad[30];

int count=0;

char *expression(void);

char prog[200],token[9];

char ch;

int syn,p,m,n,sum=0;

int kk=0,k=0;

char *rwtab[6]={"function","if","then","while","do","endfunc"};

void scaner()

{ m=0;

for(n=0;n<8;n++)

token[n]='\0';

ch=prog[p++];

while(ch==' ')

ch=prog[p++];

if((ch>='a'&& ch<='z')||(ch>='A' && ch<='Z'))

{

while((ch>='a'&& ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'))

{ token[m++]=ch;

ch=prog[p++];

}//end of while

token[m++]='\0';

p--;

syn=10;

for(n=0;n<6;n++){

if(strcmp(token,rwtab[n])==0)

{ syn=n+1;

break;}

}//end of for

}

else if (ch>='0'&&ch<='9')

{ sum=0;

while(ch>='0'&&ch<='9')

{sum=sum*10+ch-'0';

ch=prog[p++];

}

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;

ch=prog[--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+1]=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;

}

}//end of scaner

}

void emit(char *result,char *ag1,char *op,char *ag2) //将三地址代码送到四元式表{ strcpy(quad[count].result,result);

strcpy(quad[count].ag1,ag1);

strcpy(quad[count].op,op);

strcpy(quad[count].ag2,ag2);

count++;

return;

}

char *newtemp() //返回临时变量t1,t2...

{ char *p;

char m[8];

p=(char *)malloc(8);

k++;

itoa(k,m,10); //功能将整数装换为字符串。并将值保存在m中。

10是基数表示将k的值转化为10进制数。

strcpy(p+1,m);

p[0]='t';

return(p);

}

char *factor()

{ char *fplace;

fplace=(char *)malloc(12);

strcpy(fplace," ");

if(syn==10)

{ strcpy(fplace,token);

scaner();

}

else if(syn==11)

{ itoa(sum,fplace,10);

scaner();

}

else if(syn==27)

{ scaner();

fplace=expression();

if(syn==28)

scaner();

else

{ printf("\n')'ERROR");

kk=1;

}

}

else

{ printf("\n'('ERROR");

kk=1;

}

return(fplace);

}

char *term(void)

{ char *tp,*ep2,*eplace,*tt;

tp=(char *)malloc(12);

ep2=(char *)malloc(12);

eplace=(char *)malloc(12);

tt=(char *)malloc(12);

strcpy(eplace,factor());

while(syn==15||syn==16)

{

if(syn==15)

{ tt[0]='*';

tt[1]='\0';}

else if(syn==16)

{ tt[0]='/';

tt[1]='\0';}

scaner();

strcpy(ep2,factor());

strcpy(tp,newtemp()); //tp为临时变量

emit(tp,eplace,tt,ep2); //将三地址代码送到四元式表

strcpy(eplace,tp);

}

return(eplace);

}

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());

while(syn==13||syn==14)

{ if(syn==13)

{ tt[0]='+';

tt[1]='\0';

}

else if(syn==14)

{ tt[0]='-';

tt[1]='\0';

}

scaner();

strcpy(ep2,term());

strcpy(tp,newtemp());

emit(tp,eplace,tt,ep2);//

strcpy(eplace,tp);

}

return(eplace);

}

statement()

{ char tt[8],eplace[8];

int schain=0;

switch(syn)

{case 10:

strcpy(tt,token);

scaner();

if(syn==18){

scaner();

strcpy(eplace,expression());

emit(tt,eplace," "," ");

schain=0;}

else

{ printf("\n缺少赋值语句\n");

kk=1;}

break;

}

return(schain);}

yucu()

{ int schain=0;

schain=statement(); //进行语句分析

while(syn==26) //一个语句识别结束,继续识别

{ scaner();

schain=statement();

}

return(schain);

}

irparser()//在原来语法分析的基础上插入相应的语义动作,据每个产生式所对应的语义子程序进行翻译,为每个产生式配上一个翻译子程序,并在语法分析

的同时执行这些子程序即将输入串翻译成四元式序列。

{ int schain=0;

kk=0;

if(syn==1)

{ scaner();

schain=yucu();

if(syn==6)

{ scaner();

if(syn==0 && kk==0)

printf("\n语法,语义分析成功");

}

else{

if(kk!=1)

{ printf("\n缺endfunc\n");

kk=1;}

}

}

else

{ printf("\n缺function\n");

kk=1;}

return(schain);

}

void main()

{ int i;

p=0;

printf("请输入语句(以#结束,不要换行):");

do

{ ch=getchar();

prog[p++]=ch;

}while(ch!='#');

p=0;

printf("种别码单词符号\n");

do

{ scaner();

switch(syn)

{

case 11: printf("%-3d %d\n",syn,sum);break;

case -1: printf("词法分析失败,程序终止!\n");return;

default:printf("%-3d %s\n",syn,token);

}

}while(syn!=0);

printf("词法分析成功,按任意键进行语法,语义分析");

getch();p=0;

scaner();

irparser();

if(kk!=0)

{ printf("词法分析失败,程序终止!");

return;

}

printf("\n三地址指令如下:\n");

for(i=0;i

{ printf("%s=",quad[i].result); //t1= //x= printf("%s",quad[i].ag1); //a //t1

printf("%s",quad[i].op); //+

printf("%s ",quad[i].ag2); //b

printf("\n");}

getch();

return;

}

六、测试用例

用例一

用例二

八、实验心得

通过编译原理实验三语义分析实验,使得自己对语义分析的语法制导翻译以及三地址代码的四元式表现方式有了更深刻的了解,虽然源代码并非由自己设计,但是在调试程序的过程中,逐步理解程序递归下降语法制导思想,也掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法,受益匪浅。通过试验结果可以看出,这个程序实现了输出为三地址指令形式的四元式序列。

编译原理语义分析实验报告——免费!

语义分析实验报告 一、实验目的: 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。 二、实验要求: 采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。 三、算法思想: 1、设置语义过程。 (1)emit(char *result,char *ag1,char *op,char *ag2) 该函数的功能是生成一个三地址语句送到四元式表中。 四元式表的结构如下: struct { char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20]; (2) char *newtemp() 该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,… char *newtemp(void) { char *p; char m[8]; p=(char *)malloc(8); k++; itoa(k,m,10); strcpy(p+1,m); p[0]=’t’; return(p); } 2、函数lrparser 在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。

四、源程序代码: #include #include #include #include struct { char result[12]; char ag1[12]; char op[12]; char ag2[12]; }quad; char prog[80],token[12]; char ch; int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针,m是token的指针char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner(); char *factor(void); char *term(void); char *expression(void); int yucu(); void emit(char *result,char *ag1,char *op,char *ag2); char *newtemp(); int statement(); int k=0; void emit(char *result,char *ag1,char *op,char *ag2) { strcpy(quad.result,result); strcpy(quad.ag1,ag1); strcpy(quad.op,op); strcpy(quad.ag2,ag2);

实验三 自下而上语法分析及语义分析

实验三自下而上语法分析及语义分析 一、实验目的: 通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。 二、实验学时: 4学时。 三、实验内容 根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。 对于正确的表达式,给出表达式的值。 对于错误的表达式,给出出错位置。 四、实验方法 采用LR分析法。 首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。 接下来给出LR分析表。 然后程序的具体实现: ●LR分析表可用二维数组(或其他)实现。 ●添加一个val栈作为语义分析实现的工具。 ●编写总控程序,实现语法分析和语义分析的过程。 注:对于整数的识别可以借助实验1。 五、文法定义 简单的表达式文法如下: E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 上式中,i 为整数。 六、处理程序例 例1: 正确源程序例: 23+(45+4)* 40分析结果应为:正确的表达式。其值为:1983 例2: 错误源程序例: 5+(56+)-24 分析结果应为:错误的表达式:出错位置为)

附录:源程序 #include #include"string.h" #include using namespace std; #define R 30 #define C 20 typedef struct elem { char e[4]; }Elem; //ACTION表与GoTo表中的元素类型 Elem LR[R][C]; //存放ACTION表与GoTo表中的内容 typedef struct out { int order; //序号 int state[10]; //状态栈 char sign[30]; //符号栈 char grasen[20]; //产生式 char input[30]; //输入串 char explen[50]; //解释说明 }OutNode; //输出结果中每一行的类型 OutNode out[20]; //存放输出结果 char Sentence[20]; //存放文法的一个句子 char GramSent[10][20]; //存放文法的一组产生式

词法分析实验报告

编译原理实验一 姓名:朱彦荣 学号:20132184 专业:软件工程2 实验题目:词法分析完成语言:C/C++ 上级系统:VC++6.0 日期:2015/11/7

词法分析 设计题目:手工设计c语言的词法分析器 (可以是c语言的子集) 设计容: 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 设计目的: 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 结果要求:课程设计报告。 完成日期:第十五周提交报告

一.分析 要想手工设计词法分析器,实现C语言子集的识别,就要明白什么是词法分析器,它的功能是什么。词法分析是编译程序进行编译时第一个要进行的任务,主要是对源程序进行编译预处理(去除注释、无用的回车换行找到包含的文件等)之后,对整个源程序进行分解,分解成一个个单词,这些单词有且只有五类,分别是标识符、保留字、常数、运算符、界符。以便为下面的语法分析和语义分析做准备。可以说词法分析面向的对象是单个的字符,目的是把它们组成有效的单词(字符串);而语法的分析则是利用词法分析的结果作为输入来分析是否符合语法规则并且进行语法制导下的语义分析,最后产生四元组(中间代码),进行优化(可有可无)之后最终生成目标代码。可见词法分析是所有后续工作的基础,如果这一步出错,比如明明是‘<=’却被拆分成‘<’和‘=’就会对下文造成不可挽回的影响。因此,在进行词法分析的时候一定要定义好这五种符号的集合。下面是我构造的一个C语言子集。 第一类:标识符 letter(letter | digit)* 无穷集 第二类:常数 (digit)+ 无穷集 第三类:保留字(32) auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while 第四类:界符‘/*’、‘//’、 () { } [ ] " " ' 等 第五类:运算符 <、<=、>、>=、=、+、-、*、/、^、等 对所有可数符号进行编码:

PL 0 语言编译器分析实验报告

PL/0 语言编译器分析实验 一、实验目的 通过阅读与解析一个实际编译器(PL/0语言编译器)的源代码,加深对编译阶段(包括词法分析、语法分析、语义分析、中间代码生成等)和编译系统软件结构的理解,并达到提高学生学习兴趣的目的。 二、实验要求 (1)要求掌握基本的程序设计技巧(C语言)和阅读较大规模程序源代码的能力; (2)理解并掌握编译过程的逻辑阶段及各逻辑阶段的功能; (3)要求能把握整个系统(PL/0语言编译器)的体系结构,各功能模块的功能,各模块之间的接口; (4)要求能总结出实现编译过程各逻辑阶段功能采用的具体算法与技 三、实验报告 pl/0语言是pascal语言的一个子集,我们这里分析的pl/0的编译程序包括了对pl/0语言源程序进行分析处理、编译生成类pcode代码,并在虚拟机上解释运行生成的类pcode代码的功能。 pl/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。词法分析和代码生成作为独立的子程序供语法分析程序调用。语法分析的同时,提供了出错报告和出错恢复的功能。在源程序没有错误编译通过的情况下,调用类pcode 解释程序解释执行生成的类pcode代码。 词法分析子程序分析: 词法分析子程序名为getsym,功能是从源程序中读出一个单词符号(token),把它的信息放入全局变量sym、id和num中,语法分析器需要单词时,直接从这三个变量中获得。(注意!语法分析器每次用完这三个变量的值就立即调用getsym 子程序获取新的单词供下一次使用。而不是在需要新单词时才调用getsym过程。)getsym过程通过反复调用getch子过程从源程序过获取字符,并把它们拼成单词。getch过程中使用了行缓冲区技术以提高程序运行效率。 词法分析器的分析过程: 调用getsym时,它通过getch过程从源程序中获得一个字符。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把sym变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把sym 置为ident,把这个单词存入id变量。查保留字表时使用了二分法查找以提高效率。如果getch获得的字符是数字,则继续用getch获取数字,并把它们拼成一个整数,然后把sym置为number,并把拼成的数值放入num变量。如果识别出其它合

实验1-3 《编译原理》词法分析程序设计方案

实验1-3 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式; 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址 注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 三、实验要求 1.能对任何S语言源程序进行分析 在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。 2.能检查并处理某些词法分析错误 词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。 本实验要求处理以下两种错误(编号分别为1,2): 1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。 2:源程序文件结束而注释未结束。注释格式为:/* …… */ 四、保留字和特殊符号表

语义分析实验报告

实验三语法分析 309 科3 李君林 一.实验目的: 通过使用、剖析和扩充TINY语言的语义分析程序,掌握编译器的语义分析程序的构造方法。 二.实验内容 (一)运行TINY的语义分析程序 (二)扩充TINY的语法分析程序 提示: 考虑作用域(如:函数)和数组时可能需要修改符号表。 三.实验步骤 1.先读懂TINY语义程序(相关联的文件:) (1)buildSymtab(syntaxTree); 充TINY的语法分析程序 本次实验我首先将源程序实现的功能改成符合C_MINUS的符号表与类型检测 然后加入没申明调用与数组调用错误即数组没申明而调用数组类型。 四.实验结果 1.正确的测试程序 /**/ int gcd (int u,int v[]) { if(v==0) return u; else return gcd(v,u); } void main(void) { int x;int y; read x; x=y=2; while(x>0) y=y-1; write y; return (gcd(x,y)); }

/**/ 运行结果: 经检验测试程序代码无语义错误2.错误测试程序 /**/ int gcd (int u,int v[]) { if(v==0) return u; else return gcd(v,u); } void main(void) { int x;int y; read x; t=1; x=y=2; x[2]=2; while(x>0) y=y-1; write y; return (gcd(x,y)); } /**/ 实验结果:

河北工业大学语义分析实验报告

实验三语义分析程序实现 一、实验设计 在实现词法、语法分析程序的基础上,编写相应的语义子程序,进行语义处理,加深对语法制导翻译原理的理解,进一步掌握将语法分析所识别的语法范畴变换为某种中间代码(四元式)的语义分析方法。 基本实验题目:对文法G2[<算术表达式>]中的产生式添加语义处理子程序,完成运算对象是简单变量(标识符)和无符号数的四则运算的计值处理,将输入的四则运算转换为四元式形式的中间代码。 语法制导翻译模式是在语法分析的基础上,增加语义操作来实现的,实际上是对前后文无关文法的一种扩展。一般而言,首先需要根据进行的语义分析工作,完成对给定文法的必要拆分和语义动作的编写,从而为每一个产生式都配备相应的语义子程序,以便在进行语法分析的同时进行语义解释。即在语法分析过程中,每当用一个产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作之外,还要调用相应的语义子程序,以便完成生成中间代码、查填有关表格、检查并报告源程序中的语义错误等工作。每个语义子程序需指明相应产生式中各个符号的具体含义,并规定使用该产生式进行分析时所应采取的语义动作。这样,语法制导翻译程序在对源程序从左到右进行的一遍扫描中,既完成语法分析任务,又完成语义分析和中间代码生成方面的工作。本实验要求从编译器的整体设计出发,重点通过对实验二中语法分析程序的扩展,完成一个编译器前端程序的编写、调试和测试工作,形成一个将源程序翻译为中间代码序列的编译系统。 二、程序代码 在词法分析和语法分析的基础上,完成了语义的分析,同样采用了头文件的形式,在VC++6.0中运行 #include #include #include #include #include #include"cifa.h" #include"fenxibiao.h" # define PL 15 //+ # define MI 16 //-

编译原理实验三-自下而上语法分析及语义分析.docx

上海电力学院 编译原理 课程实验报告 实验名称:实验三自下而上语法分析及语义分析 院系:计算机科学和技术学院 专业年级: 学生姓名:学号: 指导老师: 实验日期: 实验三自上而下的语法分析 一、实验目的: 通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。 二、实验学时: 4学时。 三、实验内容

根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。 对于正确的表达式,给出表达式的值。 对于错误的表达式,给出出错位置。 四、实验方法 采用LR分析法。 首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。 接下来给出LR分析表。 然后程序的具体实现: ● LR分析表可用二维数组(或其他)实现。 ●添加一个val栈作为语义分析实现的工具。 ●编写总控程序,实现语法分析和语义分析的过程。 注:对于整数的识别可以借助实验1。 五、文法定义 简单的表达式文法如下: (1)E->E+T (2)E->E-T (3)E->T

(4)T->T*F (5)T->T/F (6)T->F (7)F->(E) (8)F->i 状态ACTION(动作)GOTO(转换) i + - * / ( ) # E T F 0 S5 S4 1 2 3 1 S6 S1 2 acc 2 R 3 R3 S7 S13 R3 R3 3 R6 R6 R6 R6 R6 R6 4 S 5 S4 8 2 3 5 R8 R8 R8 R8 R8 R8 6 S5 S4 9 3 7 S5 S4 10 8 S6 R12 S11 9 R1 R1 S7 S13 R1 R1 10 R4 R4 R4 R4 R4 R4 11 R7 R7 R7 R7 R7 R7 12 S5 S4 14 3 13 S5 S4 15 14 R2 R2 S7 S13 R2 R2 15 R5 R5 R5 R5 R5 R5 五、处理程序例和处理结果例 示例1:20133191*(20133191+3191)+ 3191#

语义分析实验报告.doc

实验三语法分析 20080810309 科3 李君林 一.实验目的: 通过使用、剖析和扩充TINY语言的语义分析程序,掌握编译器的语义分析程序的构造方法。 二.实验内容 (一)运行TINY的语义分析程序 (二)扩充TINY的语法分析程序 提示: 考虑作用域(如:函数)和数组时可能需要修改符号表。 三.实验步骤 1.先读懂TINY语义程序(相关联的文件:MAIN.C ANALYZE.C ANALYZE.H) (1)buildSymtab(syntaxTree); //根据语法树建立符号表 通过递归调用traverse(syntaxTree,insertNode,nullProc); 进行static void insertNode( TreeNode * t),这样将遇到与ID有关的Node信息通过void st_insert( char * name, int lineno, int loc,int len )加入到hashTable[h]数据结构中。 (2)接着调用typeCheck(syntaxTree);进行类型检测 通过递归调用traverse(syntaxTree,nullProc,checkNode);将语法树遍历,然后调用static void checkNode(TreeNode * t)对节点进行类型检测 2.扩充TINY的语法分析程序 本次实验我首先将源程序实现的功能改成符合C_MINUS的符号表与类型检测然后加入没申明调用与数组调用错误即数组没申明而调用数组类型。 四.实验结果 1.正确的测试程序 /**/ int gcd (int u,int v[]) { if(v==0) return u; else return gcd(v,u); } void main(void)

语义分析与中间代码生成程序的设计原理与实现技术__实验报告与源代码_北京交通大学

语义分析及中间代码生成程序设计原理与实现技术 XXX 1028XXX2 计科1XXX班 1.程序功能描述 完成以下描述赋值语句和算术表达式文法的语法制导生成中间代码四元式的过 程。 G[A]:A→V:=E E→E+T∣E-T∣ T→T*F∣T/F∣F F→(E)∣i V→i 说明:终结符号i 为用户定义的简单变量,即标识符的定义。 2. 设计要求 (1)给出每一产生式对应的语义动作;(2)设计中间代码四元式的结构(暂不与符号表有关)。(3)输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。输出为输入串的四元式序列中间文件。(4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。 3.主要数据结构描述: 本程序采用的是算符优先文法,文法以及算符优先矩阵是根据第四次实验来修改的,所以主要的数据结构也跟第四次差不多,主要为文法的表示,FirstVT集和LastVT 集以及算符优先矩阵:

算符优先矩阵采用二维字符数组表示的: char mtr[9][9]; //算符优先矩阵 4.程序结构描述: 本程序一共有8功能函数: void get(); //获取文法 void print(); //打印文法 void fun(); //求FirstVT 和LastVT void matrix(); //求算符优先矩阵 void test(); //测试文法 int cmp(char a,char b); 比较两个运算符的优先级 1 0 -1 void out(char now,int avg1,int avg2); //打印四元式 int ope(char op,int a,int b); //定义四元式计算方法 5.实验代码 详见附件 6.程序测试 6.1 功能测试 程序运行显示如下功能菜单:

编译原理实验报告-语义分析

编译原理课程实验报告实验3:语义分析

图2-1 本程序根据之前两个实验的结果进一步进行语义分析,主要是通过在第二个实验句法分析过程中添加语义分析功能完成的。 在代码编写之前,我将程序的功能模块分为界面及主控程序,实体类和工具类三大部分。 MyCompiler是整个程序运行的入口,是主控程序;ComplierFrame完成程序的界面,以及界面里事件的响应;Token是词法分析中词法单元的实体类;ErrorToken是错误的词法单元实体类;Symbol是句法分析中符号的实体类;Production是产生式的实体类;ErrorProduction是句法分析中产生错误的时候使用的产生式实体类;Id是标示符实体类,保存了语义分析后的标识符表;Node是语法分析树的节点类,帮助完成语法分析树的构造;LL类使用LL(1)分析法完成句法分析,同时完成语义分析;MyScanner完成了词法分析。

图2-2 得分 三、详细设计及实现 要求:对如下工作进行展开描述 (1)核心数据结构的设计 本程序使用了两个新的实体类,分别是Id和Node。 Id是标识符,里面也包含了该标识符在本程序中存储的地址和长度等信息。Id的属性如下: private String name; //名 private String type;//基本类型 private int offset;//起始地址 private int length;//长度

开始 输入 词法分析 读入Token 尝试匹配 是否错误存储错误记录,处理栈顶与Token 序列 是否为语义符号 存储产生式,处理栈顶与Token 序列 判断动作符号执行语义动作 是否读到Token 末尾 打印结果 结束

编译原理语义分析实验报告

实验3 语义分析实验报告 一、实验目的 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。 二、实验要求 采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。 三、算法思想 1、设置语义过程。 (1)emit(char *result,char *ag1,char *op,char *ag2) 该函数的功能是生成一个三地址语句送到四元式表中。 四元式表的结构如下: struct { char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20]; (2) char *newtemp() 该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,… char *newtemp(void) { char *p; char m[8]; p=(char *)malloc(8); k++; itoa(k,m,10); strcpy(p+1,m); p[0]=’t’; return(p); } 2、函数lrparser 在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。

四、源程序代码: #include #include #include #include struct { char result[12]; char ag1[12]; char op[12]; char ag2[12]; }quad; char prog[80],token[12]; char ch; int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针,m是token的指针char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner(); char *factor(void); char *term(void); char *expression(void); int yucu(); void emit(char *result,char *ag1,char *op,char *ag2); char *newtemp(); int statement(); int k=0; void emit(char *result,char *ag1,char *op,char *ag2) { strcpy(quad.result,result); strcpy(quad.ag1,ag1); strcpy(quad.op,op); strcpy(quad.ag2,ag2);

编译原理实验:语义分析实验

实验四:语义分析 一.实验目的:通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法 二.实验要求:采用的是递归下降语法制导翻译法,对算术表达式,赋值语进行语义分析并生成四元式序列。 1.实验的输入和输出分别为以下: 输入是语法分析后提供的正确的单词串,输出为三地址指令形式的四元式序列。 例如:对于语句串begin a:=2+3*4;x:=(a+b)/c end # 输出的三地址指令如下所示: (1)t1=3*4; (2)t2=2+t1; (3)a=t2; (4)t3=a+b; (5)t4=t3/c; (6)x=t4; 2.实验算法的思想为: (1)设置语义分析过程 这其中用到的几个重要的函数的功能和代码如下面所列出的: 1.emit (char *result ,char *ag1,char *op,char *ag2) 该函数的功能是生成一个三地址语句送到四元式表中。 四元式表的结构如下: Struct { Char result[8]; Char ag1[8]; Char op[8]; Char ag2[8]; }quad[20]; 2char *newtemp() 该函数的功能是回送一个新的变量名,临时变量的名称产生的顺序依次为T1, T2 ,…….. Char *newtemp() { Char *p; Char m[8]; P=(char *)malloc(8); K++; Iota(k,m,10); Strcpy(p+1,m); P[0]=’t’; Return (p); } (2)主程序的示意图如图所示:

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告

实验一 一、实验名称:词法分析器的设计 二、实验目的:1,词法分析器能够识别简单语言的单词符号 2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。 三、实验要求:给出一个简单语言单词符号的种别编码词法分析器 四、实验原理: 1、词法分析程序的算法思想 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。 2、程序流程图 (1 (2)扫描子程序

3

五、实验内容: 1、实验分析 编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。 2 实验词法分析器源程序: #include #include #include int i,j,k; char c,s,a[20],token[20]={'0'}; int letter(char s){ if((s>=97)&&(s<=122)) return(1); else return(0); } int digit(char s){ if((s>=48)&&(s<=57)) return(1); else return(0); } void get(){ s=a[i]; i=i+1; } void retract(){ i=i-1; } int lookup(char token[20]){ if(strcmp(token,"while")==0) return(1); else if(strcmp(token,"if")==0) return(2); else if(strcmp(token,"else")==0) return(3); else if(strcmp(token,"switch")==0) return(4); else if(strcmp(token,"case")==0) return(5); else return(0); } void main() { printf("please input string :\n"); i=0; do{i=i+1; scanf("%c",&a[i]);

实验1-3 《编译原理》词法分析程序设计方案讲课教案

实验1-3《编译原理》词法分析程序设 计方案

实验1-3 《编译原理》S语言词法分析程序设计方案 一、实验目的 了解词法分析程序的两种设计方法之一:根据状态转换图直接编程的方式; 二、实验内容 1.根据状态转换图直接编程 编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词的二元式,形成二元式(记号)流文件输出。在此,词法分析程序作为单独的一遍,如下图所示。 具体任务有: (1)组织源程序的输入 (2)拼出单词并查找其类别编号,形成二元式输出,得到单词流文件 (3)删除注释、空格和无用符号 (4)发现并定位词法错误,需要输出错误的位置在源程序中的第几行。将错误信息输出到屏幕上。 (5)对于普通标识符和常量,分别建立标识符表和常量表(使用线性表存储),当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则返回0并且填写符号表或常量表。 标识符表结构:变量名,类型(整型、实型、字符型),分配的数据区地址

注:词法分析阶段只填写变量名,其它部分在语法分析、语义分析、代码生成等阶段逐步填入。 常量表结构:常量名,常量值 三、实验要求 1.能对任何S语言源程序进行分析 在运行词法分析程序时,应该用问答形式输入要被分析的S源语言程序的文件名,然后对该程序完成词法分析任务。 2.能检查并处理某些词法分析错误 词法分析程序能给出的错误信息包括:总的出错个数,每个错误所在的行号,错误的编号及错误信息。 本实验要求处理以下两种错误(编号分别为1,2): 1:非法字符:单词表中不存在的字符处理为非法字符,处理方式是删除该字符,给出错误信息,“某某字符非法”。 2:源程序文件结束而注释未结束。注释格式为:/* …… */ 四、保留字和特殊符号表

语义分析实验报告

云南大学编译原理实验报告 实验题目:语义分析 学院:信息学院 专业:计算机科学与技术 学号: 064 姓名:刘继远

目录 一、实验目的 ..................... 错误!未定义书签。 二、实验内容 ..................... 错误!未定义书签。 三、源程序分析 ................... 错误!未定义书签。 1、程序采用的BNF .............. 错误!未定义书签。 2、根据语义要求得到对应的翻译模式错误!未定义书 签。 3、实现原理 ................... 错误!未定义书签。 4、文法的属性分析 ............. 错误!未定义书签。 5、过程设计 ................... 错误!未定义书签。 6、子程序说明 ................. 错误!未定义书签。 四、设计的基本思想(包括修改之后的属性文法、属性类型分析、翻译模式) ................. 错误!未定义书签。 1、增加除法运算 ............... 错误!未定义书签。 2、禁止同名重复声明 ........... 错误!未定义书签。 五、结果及分析 ................... 错误!未定义书签。

一、实验目的 进一步理解递归下降分析原理和实现方法,理解语义分析的基本机制,掌握语义子程序的构造方法。 二、实验内容 将带变量声明的表达式翻译为四元式序列,其中包括以下要求: 非终结符号D实现定义两种类型int, real变量的声明; 非终结符号S实现变量之间的*,+,: =(赋值运算) 两个关键字 int 和real 变量之间的*,+,: =(赋值) 运算只能使用声明过的变量,所以要检查使用的变量是否声明过。 对每个*,+,: =(赋值) 运算生成一条四元式如(*,A,B,T1),其中T1是临时变量 *优先级别高于+,*满足左结合规则

编译原理语义分析实验报告 免费

编译原理综合训练 语义分析实验报告 指导老师: 班级: 学生:zeadom 学号: 学生: 学号: 2011/6/29

目录 语言文法的形式化描述....................................................................................错误!未定义书签。语义规则............................................................................................................错误!未定义书签。运行环境介绍....................................................................................................错误!未定义书签。关键算法的流程图及文字解释........................................................................错误!未定义书签。 1、本编译器的总框架..............................................................................错误!未定义书签。 2、在语义分析中的主要函数介绍..........................................................错误!未定义书签。 3、产生布尔表达式..................................................................................错误!未定义书签。 4、While-do语句的语义分析..................................................................错误!未定义书签。 5、词法、语法和语义分析的衔接..........................................................错误!未定义书签。测试报告............................................................................................................错误!未定义书签。附录 ...................................................................................................................错误!未定义书签。

语义实验的报告材料

语义分析实验报告 一:实验内容:用bison工具生成一个PL/0语言的语义分析程序,对PL/0源程序进行语义分析,并输出归约时产生的指令序列,然后输出结果。 二:实验环境:语法分析器生成工具:bison ?编程语言:C 三:源程序格式: %{ 声明--可选 %} 辅助定义--可选 %% 语法规则--必须有 %% 用户子程序--可选 四:设计思想 A.要求输出规约时所用的语法规则,所以考虑用pl0语言的EBNF范式(具体范式略)作为规约式的参考。

B.语法规则里,对词法分析出来的符号串给与特定的标记,然后将这个标记传给yyparse(),以便在语法分析时作为终结符。 C.在语法文件里将词法分析生成的lex.yy.c包括进来即可。具体源码请查看test.l和test.y文件。 五:测试说明 测试文件test1.pl0。 结果如下: 指令集合: 0 jmp 0 8 1 jmp 0 2 2 int 0 3 3 lod 1 3 4 lit 0 10 5 opr 0 2 6 sto 1 4 7 opr 0 0 8 int 0 5 9 opr 0 16 10 sto 0 3 11 lod 0 3 12 lit 0 0

13 opr 0 9 14 jpc 0 24 15 cal 0 2 16 lit 0 2 17 lod 0 4 18 opr 0 4 19 opr 0 14 20 opr 0 15 21 opr 0 16 22 sto 0 3 23 jmp 0 11 24 opr 0 0 符号表: 6 const val=0 1 const val=0 2 const aval=10 3 var blev=0 addr=3 4 var clev=0 addr=4 5 procplev=0 adr=2 size=3 结果集:

实验三 自下而上语法分析报告及语义分析报告

实验三自下而上语法分析及语义分析一、实验目的: 通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。 二、实验学时: 4学时。 三、实验容 根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。 对于正确的表达式,给出表达式的值。 对于错误的表达式,给出出错位置。 四、实验方法 采用LR分析法。 首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。 接下来给出LR分析表。 然后程序的具体实现: ●LR分析表可用二维数组(或其他)实现。 ●添加一个val栈作为语义分析实现的工具。 ●编写总控程序,实现语法分析和语义分析的过程。 注:对于整数的识别可以借助实验1。

五、文法定义 简单的表达式文法如下: E->E+T|E-T|T T->T*F|T/F|F F->(E)|i 上式中,i 为整数。 六、处理程序例 例1: 正确源程序例: 23+(45+4)* 40分析结果应为:正确的表达式。其值为:1983 例2: 错误源程序例: 5+(56+)-24 分析结果应为:错误的表达式:出错位置为)

附录:源程序 #include #include"string.h" #include using namespace std; #define R 30 #define C 20 typedef struct elem { char e[4]; }Elem; //ACTION表与GoTo表中的元素类型 Elem LR[R][C]; //存放ACTION表与GoTo表中的容 typedef struct out { int order; //序号 int state[10]; //状态栈 char sign[30]; //符号栈 char grasen[20]; //产生式

编译原理实验三-自下而上语法分析及语义分析.docx演示教学

编译原理实验三-自下而上语法分析及语义 分析.d o c x

上海电力学院 编译原理 课程实验报告 实验名称:实验三自下而上语法分析及语义分析院系:计算机科学与技术学院 专业年级: 学生姓名:学号: 指导老师: 实验日期:

实验三自上而下的语法分析 一、实验目的: 通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。 二、实验学时: 4学时。 三、实验内容 根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。 对于正确的表达式,给出表达式的值。 对于错误的表达式,给出出错位置。 四、实验方法 采用LR分析法。 首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。 接下来给出LR分析表。 然后程序的具体实现: LR分析表可用二维数组(或其他)实现。

●添加一个val栈作为语义分析实现的工具。 ●编写总控程序,实现语法分析和语义分析的过程。 注:对于整数的识别可以借助实验1。 五、文法定义 简单的表达式文法如下: (1)E->E+T (2)E->E-T (3)E->T (4)T->T*F (5)T->T/F (6)T->F (7)F->(E) (8)F->i 五、处理程序例和处理结果例

示例1:20133191*(20133191+3191)+ 3191# 六、源代码 【cifa.h】 //cifa.h #include using namespace std; //单词结构定义 struct WordType{ int code; string pro; };

相关文档
最新文档