int parser (FILE *fp) {
if (IsLowerThan(stack[j],r)||IsEqualTo(stack[j],r))
int i, k, r, NewVn; /* NewVn holds left side of a production */ i=0; k=0; /* i, k is index of a[ ] and stack[ ] separately */ int sj; stack[0]=9; do {
int j;
if (IsVt(stack[k]))
j=k; j=k-1; else
printf(\中内容为(自底向上):\); for(sj=0;sj<=j;sj++)
changinttochar(stack[sj]); printf(\当前扫描字串为:\); r=changchartoint(fp); //a[i++]=r;
if(r==20&&stack[k]!=9)return report_error(8);
if(r>=0&&r<=3&&stack[k]>=0&&stack[k]<=3)return report_error(4);
//printf(\
while (IsHigherThan(stack[j],r)) {
int q; do {
NewVn=Reduce(j+1,k,r); for(sj=j+1;sj<=k;sj++)
stack[sj]=0;
k=j+1;/* reduce the leftmost prime phrase */
stack[k]=NewVn;/* it is stack[j+1] stack[j+2] ?stack[k] */ printf(\堆栈指针移动到k=%d\\n\,k);
q=stack[j];
if (IsVt(stack[j-1]))
j--; j-=2; else
}while(!IsLowerThan(stack[j],q));
} /*end of while*/
}
{ } else
return ERROR; stack[++k]=r;
//printf(\新结点入栈,堆栈指针移进k=%d\\n\
//printf(\为:\
// printf(\栈顶节点为:\
}while (r!=9); return RIGHT;
int IsHigherThan(int a,int b) { }
int IsLowerThan(int a,int b) { }
int IsEqualTo(int a,int b) { }
int Reduce(int a,int b,int c) {
char gl='F'; printf(\); for(;a<=b;a++){
changinttochar(stack[a]);
if(stack[a]==1||(stack[a])==0)gl='E'; if(stack[a]==2||(stack[a])==3)gl='T'; if(table[a][b]==0)
return RIGHT; return ERROR; else
if(table[a][b]==-1)
return RIGHT; return ERROR; else
if(table[a][b]==1)
return RIGHT;
return report_error(table[a][b]); return ERROR;
else if(table[a][b]!=-1&&table[a][b]!=0) else
}
}
printf(\类型为%c,归约为N,\,gl); return 10;
main() {
ch=fgetc(fp); coor(ch); while(ch!=EOF) {
if(ch==' '||ch==9||ch==10){
ch=fgetc(fp);
coor(ch);}//'\\t'为水平制表符ASCII码为.\\n占两个字节,前一字节无ASCII码为换行格
//int j=0; FILE *fp; char ch;
if((fp=fopen(\,\))==NULL) //readonly方式打开文件 { }
printf(\文件内容如下:\\n\); ch=fgetc(fp); while(ch!=EOF) { }
printf(\语法分析如下:\\n\); fseek(fp,0,0); int key;
//坐标移到文档开始位置
putchar(ch); ch=fgetc(fp);
//EOF文档结束标志
printf(\找不到文件!!!\\n\); return(0);
式,后一字节ASCII码为
else {
fseek(fp,-1,1); l-=1;
key=parser(fp); if(key==1) { } else {
printf(\出现语法错误!!\\n\\n\);
printf(\成功通过词法分析和语法分析!!\\n\\n\);
}
}
}
}
//printf(\ch=fgetc(fp); coor(ch);
printf(\); fclose(fp); return(0);
五、运行结果:
正确输入时结果:
错误输入时结果:
实验三 语义分析程序实现
一、实验目的与要求
在实现词法、语法分析程序的基础上,编写相应的语义子程序,进行语义检查,加深对语法制导翻译原理的理解,进一步掌握将语法分析所识别的语法范畴变换为某种中间代码(四元式)的语义分析方法,完成编译器的前端开发工作。
二、实验内容
语法制导翻译模式是在语法分析的基础上,增加语义操作来实现的。对于给定文法中的每一产生式,编写相应的语义子程序。在语法分析过程中,每当用一产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作之外,还要调用相应的语义子程序,以便完成生成中间代码、查填有关表格、检查并报告源程序中的错误等工作。每个语义子程序需指明相应产生式中各个符号的具体含义,并规定使用该产生式进行分析时所应采取的语义动作。这样,语法制导翻译程序在对源程序从左到右进行的一遍扫描中,既完成语法分析任务,又完成语义分析和中间代码生成方面的工作。
高级语言的语法结构类型很多,例如说明语句、程序流程控制语句、子程序结构语句、格式语句等,可选择其中一类进行语义分析程序的开发。
输入:作为测试用例的源程序文件。
输出:将源程序转换为中间代码形式表示,并将中间代码序列输出到文件中。若源程序中有错误,应指出错误信息。
三、基本实验题目
针对实验一中定义的文法G1[<赋值语句>],首先根据需进行的语义工作,完成对文法的必要拆分和语义动作的编写,从而为每个产生式都配备相应的语义子程序。然后编写并调试相应的语法制导翻译程序。在此,中间代码以四元式表示,并且对于不同数据类型的运算对象,在进行算术运算前须转换为相同的数据类型。
要求完成词法、语法和语义分析的整体设计,重点通过对实验二中语法分析程序的扩展,将编译程序前端涉及的各个模块组合在一起,形成一个将源程序翻译为四元式序列的编译系统。
四、示例
对实验二中的示例一给出的文法G2[<算术表达式>],在利用递归下降法进行语法分析的同时,生成四元式形式的中间代码序列。语法制导翻译程序的核心部分(指表达式、项和因式的处理)的算法,可用程序四描述如下:
程序四 利用递归下降法生成简单算术表达式的四元式序列
#include
#include
#define RIGHT 1 #define ERROR 0 #define MAXINPUT 300 #define MAXSTACK 100

