转,实验四、语法分析实验
自:https://www.cnblogs.com/2647409627qq/p/6235044.html
实验四、语法分析实验
一、 实验目的
(1) 编制一个语义分析程序
(2) 语义分析程序是在语法分析程序的基础上进行编写的,主要任务是根据语法分析来插入中间代码、语义规则以及生成四元式。
(3) 通过语义分析的练习,能够进一步了解编译原理。
(4) 通过了解语义分析程序的设计原则、语义规则的描述技术、识别机制及语义分析程序的自动构造原理。
二、 实验内容和要求
(1) 根据语法分析程序进行改写语义分析程序
(2) 根据语言的语义规则,插入中间代码、语义规则以及生成四元式等
(3) 并在分析过程中进行语义检查,四元式作为输出或以某种形式的语法树作报告错误
三、 实验方法、步骤及结果测试
1、实验方法、步骤:
完成静态语义审查和处理
a) 上下文相关性审查
b) 类型匹配审查
c) 类型转换
d) 如:s:=2*3.1416*r*(h+r);
i. 赋值语句的语义:计算赋值符号右边表达式的值,送到赋值号左边的变量中。
ii. 检查赋值号左右两边的类型是否匹配
iii. 根据赋值语句的语义,将它翻译成四元式中间代码
2、原理分析:我是在语法分析程序的基础上进行修改的,是根据语法分析来插入中间代码、制定语义规则以及生成四元式。



void S(){
char y=str[t-1];int x;
if(syn==10){
scaner();
if(syn==18){
scaner(); x=E();printf("\n(':=',%d, ,%c)\n",x,y);
}
}
}
int E(){
int x;printf("E ");
x=T();return E1(x);
}
int E1(int x){
int y;printf("E1 ");
if (syn==13) {
scaner();
y=T();gen4('+',x,y);return E1(x+y);
}else if (syn==14) {
scaner();y=T();gen4('-',x,y);return E1(x-y);
}else {
if (syn==28 || syn==25)return(x);
else error();
}
}
int T(){
int x;printf("T ");
x=F();return T1(x);
}
int T1(int x){
int y;printf("T1 ");
if (syn==15) {
scaner();y=F();gen4('*',x,y);return T1(x*y);
}else if (syn==16) {
scaner();y=F();gen4('/',x,y);return T1(x/y);
}
else {
if (syn==28 ||syn==25 || syn==13||syn==14)return (x);
else error();
}
}
int F(){
int y; printf("F ");
if (syn==27) {
scaner();y=E();
if(syn==28) {scaner();return (y);
}else error();
}else if (syn==11 || syn==10){ y=sum; scaner();return (y);
}
}

四、实验总结
由于时间的关系,这次实验我暂且做了语义分析的算术表达式与赋值语句,虽然做的不多,
但也算把算术表达式做的不错,是有优先级的,我做的实验是以’#’为结束语,输出的四元式
是用(‘运算符’,操作数1,操作数2,运算结果);还有就是赋值语句是S:=E;这次实验,
我学会了语法分析和语义分析程序,利用自上而下的递归下降分析法来分析语法,然后进行
赋予语义规则,再生产中间代码,最后输出四元式。
#include <stdio.h>
//#include <string.h>
#define M 100
#define N 20
char str[M], wrong[N];
char ch;
int syn,t,m,n,sum,s=100;
char *keyword[6]= {"begin","if","then","while","do","end"};
void scaner();
void error();
void gen4(char ch,int x,int y);
void S();
int E();
int T();
int E1(int x);
int F();
int T1(int x);
main()
{
char c;
t=0;
printf("Please input the arithmetic expressions: ");
do{
ch=getchar();
str[t++]=ch;
}while (ch!='#');
t=0;
do{
scaner();
switch(syn)
{
case 11: printf("\n(%d,%d)",syn,sum); break;
case -1: printf("\n(%s,mistake)",wrong);break;
default: printf("\n(%d,%s)",syn, wrong);
}
}while (syn!=0);
getchar();
printf("\nWheter or not choice output grammer(y|n):");
scanf("%c",&c);
if(c=='Y'||c=='y'){
t=0;
scaner();
S();
E();
if (syn==25)
printf("\nGrammer correct\n");
else printf("\nGrammer mistake\n");
}
}
void scaner()
{
for (n=0;n<20;n++) wrong[n]=NULL;
m=0;
sum=0;
ch=str[t++];
while (ch==' ') {ch=str[t++];}
if (ch>='a'&& ch<='z')
{while (ch>='a'&& ch<='z'||ch>='0' && ch<='9')
{
wrong[m++]=ch;
ch=str[t++];
}
syn=10;t--;
for (n=0;n<6;n++)
if(strcmp(wrong,keyword[n])==0) {syn=n+1;break;}
}
else
if(ch>='0' && ch<='9')
{while (ch>='0' && ch<='9') {sum=sum*10+(ch-'0'); ch=str[t++];}
syn=11;t--;
}
else
switch(ch)
{
case '<': wrong[m++]=ch;
ch=str[t++];
if (ch=='>') {syn=21;wrong[m++]=ch;}
else if (ch=='=') {syn=22;wrong[m++]=ch;}
else {syn=20;t--;}
break;
case '>': m=0; wrong[m++]=ch;
ch=str[t++];
if (ch=='='){syn=24;wrong[m++]=ch;}
else {syn=23;t--;}
break;
case ':': m=0; wrong[m++]=ch;
ch=str[t++];
if (ch=='='){syn=18;wrong[m++]=ch;}
else {syn=17;t--;}
break;
case '+': syn=13;wrong[0]=ch;break;
case '-': syn=14;wrong[0]=ch;break;
case '*': syn=15;wrong[0]=ch;break;
case '/': syn=16;wrong[0]=ch;break;
case '(': syn=27;wrong[0]=ch;break;
case ')': syn=28;wrong[0]=ch;break;
case '=': syn=25;wrong[0]=ch;break;
case ';': syn=26;wrong[0]=ch;break;
case '#': syn=0;wrong[0]=ch;break;
default: syn=-1;wrong[0]=ch;
}
}
void S()
{
char y=str[t-1];int x;
if(syn==10)
{
scaner();
if(syn==18)
{
scaner();
x=E();
printf("\n(':=',%d, ,%c)\n",x,y);
}
}
}
int E()
{
int x;
printf("E ");
x=T();return E1(x);
}
int E1(int x)
{
int y;
printf("E1 ");
if (syn==13) {
scaner();
y=T();gen4('+',x,y);return E1(x+y);
}else if (syn==14) {
scaner();
y=T();gen4('-',x,y);return E1(x-y);
}
else {
if (syn==28 || syn==0)return(x);
else error();
}
}
int T()
{
int x;
printf("T ");
x=F();return T1(x);
}
int T1(int x)
{
int y;
printf("T1 ");
if (syn==15) {
scaner();
y=F();gen4('*',x,y);return T1(x*y);
}else if (syn==16) {
scaner();
y=F();gen4('/',x,y);return T1(x/y);
}
else {
if (syn==28 ||syn==0 || syn==13||syn==14)return (x);
else error();
}
}
int F()
{
int y;
printf("F ");
if (syn==27) {
scaner();
y=E();
//gen4('+',x,y);return E1(x+y);
if(syn==28) {scaner();return (y);
}
else error();
}
else if (syn==11 || syn==10){ y=sum; scaner();return (y);
}
}
void error()
{
printf("\n(%d,%s)mistake\n",syn, wrong);
}
void gen4(char ch,int x,int y)
{
int z;
float f;
switch(ch){
case '+':z=x+y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break;
case '-':z=x-y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break;
case '*':z=x*y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break;
case '/':f=(float)x/y;printf("\n('%c',%d,%d,%0.1f)\n",ch,x,y,f);break;
default:printf("mistakes!");
}
}

浙公网安备 33010602011771号