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

实验的输入和输出

输入是语法分析提供的正确的单词串,输出为三地址指令形式的四元式序列。

例如:对于语句串

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

语法分析的流程:

具体的代码实现:

#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#include <conio.h>
char prog[80],token[6];
int count=0;
char ch;  /*当前读入单词*/
int syn,p,m,n,sum,kk=0,k=0;  //p/*输入缓冲区指针*/
int length=0;    //输入字符长度
int mark=0;       /*标记注释//*/
int mark2;// 用于/* */ 注释
char * rwtab[6]={"begin","if","then","while","do","end"};
char *expression(void);
struct {
char result[8];
char ag1[8];
char op[8];
char ag2[8];
}quad[20];
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;
}
/*词法扫描程序:*/
scaner()
{
for(n=0;n<8;n++)
token[n]=NULL;
m=0;
ch=prog[p++];
while(ch==' ')ch=prog[p++];
if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
{
while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
ch=prog[--p];
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
//break;
}
else
if((ch<='9'&&ch>='0'))
{
sum=0;
while((ch<='9'&&ch>='0'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
ch=prog[--p];
syn=11;
}
else
switch(ch)
{
case '<':m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else
if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
ch=prog[--p];
}
break;
case '>':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
ch=prog[--p];
}
break;
case ':':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[m++]=ch;
ch=prog[p++];
if (ch=='/')
{
mark2=1;
return scaner();
}
ch=prog[--p];
break;
case '/':
syn=16;
token[m++]=ch;
ch=prog[p++];
if (ch=='/')
{
mark=0;
while (mark==0)
{
scaner();
}
p++;
//mark=0;
}else if (ch=='*')
{
mark=1;
syn=30;   ///**/
token[m++]='*';
mark2=0;
while(mark2==0)
{
scaner();
}
p++;
//mark2=0;
}
ch=prog[--p];
break;
case ':=':syn=18;token[0]=ch;break;
case '<>':syn=21;token[0]=ch;break;
case '<=':syn=22;token[0]=ch;break;
case '>=':syn=24;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 '\n':
syn = 29;
token[0] = ch;
mark = 1;
return scaner();
break;
case '#':syn=0;token[0]=ch;break;
case '\0':syn=1000;token[0]='\0';break;
default:syn=-1;
}
}
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);
}
//factor分析函数
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)   //(   27
{
scaner();
fplace=expression();
if(syn==28)scaner();
else
{
printf("缺少')' 出错!\n");
kk=1;
}
}
else
{
printf("表达式错误!\n");
kk=1;
}
return (fplace);
}
//term分析函数
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);
//factor();
}
return (eplace);
}
//expression表达式分析函数
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分析产生表达式计算的第一项eplace*/
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());/*/调用term分析产生表达式计算的第二项ep2/*/
strcpy(tp,newtemp());/*/调用newtemp产生临时变量tp存储计算结果/*/
emit(tp,eplace,tt,ep2);/*/生成四元式送入四元式表/*/
strcpy(eplace,tp);
//term();
}
return (eplace);
}
//递归下降分析程序
lrparser()
{
int schain=0;
scaner();
if(syn!=1)
{
//scaner();
读取一个单词
//yucu();
//if(syn==6)
//{
//  scaner();
//  if((syn==0)&&(kk==0))
//      printf("sucess");
//}
//else
//{
//  if(kk!=1) printf("缺少end!");
//  kk=1;
//}
printf("begin错误\n");
kk=1;
}else
scaner();
schain=yucu();
if (syn==6)
{
scaner();
if(kk==0)
printf("sucess");
}else{
if(kk!=1)
kk=1;
printf("缺少end\n");
}
return (schain);
}
//语句串分析
yucu()
{
int schain=0;
schain=statement();
while(syn!=6&&p!=length-1&&syn!=0)
{
if(syn!=26)
scaner();
while(syn==26)     //26==;
{
scaner();
if (syn!=0&&syn!=6)
{
schain=statement();
}
}
}
return (schain);
}
//statement语句分析函数
statement()
{
//scaner();
int schain=0;
char tt[8],eplace[8];
if(syn==10)
{
strcpy(tt,token);
scaner();
if(syn==18)  //:= 18
{
scaner();
strcpy(eplace,expression());
emit(tt,eplace," "," ");
schain=0;
//expression();
}
else
{
printf("赋号值错误!\n");
kk=1;
}
}
else
{
printf("语句错误\n");
//kk=1;
}
return (schain);
}
void readFile(){
int i = 0;
char temp[255];
/*ifstream fin("data.txt");*/
FILE *fp=fopen("data.txt","r");
while ((temp[i]=fgetc(fp))!=EOF)
{
prog[i++]=temp[i];
}
length = i;
}
void main()
{
int i;
p=0;
readFile();
/*printf("\nplease intput string:");*/
/*do
{
ch=getchar();
prog[p++]=ch;
}while(ch!='#');
length=p;*/
//将程序保存在prog字符数组中
p=0;
printf("词法分析:\n");
do
{
scaner();
if (syn<1000/*&&syn!=100&&syn!=101*/)
{
printf("(%d,%s)\n",syn,token);
}
} while (syn<1000);
printf("\n\n");
printf("语法分析:\n");
p=0;
//scaner();
lrparser();
printf("\n");
printf("\n三地址指令如下:\n");
for(i=0;i<count;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();
//printf("%d %d",length,p);
}

编译原理---语义分析相关推荐

  1. c 语言编写编译原理语义分析实验,北邮 编译原理 语义分析实验报告

    <北邮 编译原理 语义分析实验报告>由会员分享,可在线阅读,更多相关<北邮 编译原理 语义分析实验报告(14页珍藏版)>请在人人文库网上搜索. 1.编译原理第六章 语义分析目 ...

  2. 编译原理语义分析_编译原理 第一章 绪论

    编译原理系列,是在学习本校 "编译技术" 这门课程时,所作记录,参考教材为 <编译技术基础教程>清华大学出版社和<程序设计语言编译原理>国防工业出版社(陈火 ...

  3. 编译原理—语义分析(Java)

    递归下降语法制导翻译 实现含多条简单赋值语句的简化语言的语义分析和中间代码生成. 测试样例 begin a:=2; b:=4; c:=c-1; area:=3.14*a*a; s:=2*3.1416* ...

  4. 编译原理语义分析代码_Pix2Pix原理分析与代码解读

    原理分析: 图像.视觉中很多问题都涉及到将一副图像转换为另一幅图像(Image-to-Image Translation Problem),这些问题通常都使用特定的方法来解决,不存在一个通用的方法.但 ...

  5. 【编译原理】WHILE循环语句的翻译程序设计与实现(递归下降法、输出四元式)(赋值语句的词法分析、语义分析)

    注:本文记录 WHUT-计算机学院-编译原理 课程 课内实践 >>点击查看武汉理工大学计算机专业课程资料汇总 项目下载地址:https://download.csdn.net/downlo ...

  6. 笔记-编译原理-实验四-语义分析与中间代码生成

    实验四. 语义分析及中间代码生成 设计思想 根据对属性文法及语义分析.中间代码生成的学习,可以将实验二.三的两种语法分析器进行一定的改造,以达到进行语法分析的同时进行语义分析并生成中间代码.根据PL0 ...

  7. 编译原理实验三 语义分析程序设计与实现

    一.实验目的 在实现词法.语法分析程序的基础上,编写相应的语义子程序,进行语义处理,加深对语法制导翻译原理的理解,进一步掌握将语法分析所识别的语法范畴变换为某种中间代码(四元式)的语义分析方法,并完成 ...

  8. 【编译原理实验六】语义分析

    语义分析器 内容 学习经典的语义分析器 (1)选择一个编译器,如:TINY或PL/0,其它编译器也可(需自备源代码). (2)阅读语义分析源程序,加上你自己的理解.尤其要求对相关函数与重要变量的作用与 ...

  9. PYTHON实现算术表达式的词法语法语义分析(编译原理应用)

    本学期编译原理的一个大作业,我的选题是算术表达式的词法语法语义分析,当时由于学得比较渣,只用了递归下降的方法进行了分析. 首先,用户输入算术表达式,其中算术表达式可以包含基本运算符,括号,数字,以及用 ...

最新文章

  1. AS3.0开始类库依赖出现了四种新语法
  2. SAP销售订单-订单组合
  3. C++学习笔记--(1)
  4. 如何不部署Keras / TensorFlow模型
  5. UvaLive7362 Fare(欧拉函数)
  6. iOS10 Safari不识别viewport禁用缩放的暴力解决方案
  7. c语言出100道计算题,C语言例题100道
  8. hack tool Mirkov4
  9. 京东的焦虑:强制996,高管离职,奶茶风波...
  10. GNSS定位中的不同高度概念及计算
  11. 小码王python_小码王分享给Python初学者的几个技巧
  12. 9.支撑向量机SVM
  13. 先有鸡还是先有鸡蛋?C语言发展史给出的答案
  14. 使用Tab键控制切换网页光标位置
  15. QQ看点模块100条测试用例
  16. Qt入门极简教程(二)
  17. html里如何将数字转换为条形码,excel中如何把数字变成条形码?
  18. php中date设置北京时区,PHP中设置时区方法小结
  19. 图书管理系统设计类图
  20. 锄头哥直播技术探讨----基础普及篇

热门文章

  1. 【eclipse】注释模版
  2. Linux应用程序管理及RPM软件包
  3. pjax php demo,Pjax无刷新加载页面基础示例
  4. 最新出炉!java堆排序图解
  5. Laplacian算子(拉普拉斯算子)
  6. QQ快捷登录(sdk登录)
  7. 爸爸不在家,你要保护妈妈
  8. 【POJ2195】Going Home(费用流)
  9. python编写安卓脚本,用python+uiautomator写android测试脚本环境的搭建
  10. 晒自己做的一个管理系统(清新风格)EasyUI