当前位置:   article > 正文

编译原理实验三-语义分析_输入是一段语句串,输出为三地址指令形式的四元式代码。

输入是一段语句串,输出为三地址指令形式的四元式代码。

一、实验目的

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

二、实验要求

采用递归下降语法制导翻译法,对算术表达式,赋值语句进行语义分析并生成四元式序列。
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

三、源程序

  1. #include<stdio.h>
  2. #include <stdlib.h>
  3. #include<string.h>
  4. #include <conio.h>
  5. char prog[80],token[6];
  6. int count=0;
  7. char ch; /*当前读入单词*/
  8. int syn,p,m,n,sum,kk=0,k=0; //p/*输入缓冲区指针*/
  9. int length=0; //输入字符长度
  10. int mark=0; /*标记注释//*/
  11. int mark2;// 用于/* */ 注释
  12. char * rwtab[6]={"begin","if","then","while","do","end"};
  13. char *expression(void);
  14. struct {
  15. char result[8];
  16. char ag1[8];
  17. char op[8];
  18. char ag2[8];
  19. }quad[20];
  20. void emit(char * result,char * ag1,char * op,char * ag2)
  21. {
  22. strcpy(quad[count].result,result);
  23. strcpy(quad[count].ag1,ag1);
  24. strcpy(quad[count].op,op);
  25. strcpy(quad[count].ag2,ag2);
  26. count++;
  27. return;
  28. }
  29. /*词法扫描程序:*/
  30. scaner()
  31. {
  32. for(n=0;n<8;n++)
  33. token[n]=NULL;
  34. m=0;
  35. ch=prog[p++];
  36. while(ch==' ')ch=prog[p++];
  37. if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
  38. {
  39. while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'))
  40. {
  41. token[m++]=ch;
  42. ch=prog[p++];
  43. }
  44. token[m++]='\0';
  45. ch=prog[--p];
  46. syn=10;
  47. for(n=0;n<6;n++)
  48. if(strcmp(token,rwtab[n])==0)
  49. {
  50. syn=n+1;
  51. break;
  52. }
  53. //break;
  54. }
  55. else
  56. if((ch<='9'&&ch>='0'))
  57. {
  58. sum=0;
  59. while((ch<='9'&&ch>='0'))
  60. {
  61. sum=sum*10+ch-'0';
  62. ch=prog[p++];
  63. }
  64. ch=prog[--p];
  65. syn=11;
  66. }
  67. else
  68. switch(ch)
  69. {
  70. case '<':m=0;token[m++]=ch;
  71. ch=prog[p++];
  72. if(ch=='>')
  73. {
  74. syn=21;
  75. token[m++]=ch;
  76. }
  77. else
  78. if(ch=='=')
  79. {
  80. syn=22;
  81. token[m++]=ch;
  82. }
  83. else
  84. {
  85. syn=20;
  86. ch=prog[--p];
  87. }
  88. break;
  89. case '>':token[m++]=ch;
  90. ch=prog[p++];
  91. if(ch=='=')
  92. {
  93. syn=24;
  94. token[m++]=ch;
  95. }
  96. else
  97. {
  98. syn=23;
  99. ch=prog[--p];
  100. }
  101. break;
  102. case ':':token[m++]=ch;
  103. ch=prog[p++];
  104. if(ch=='=')
  105. {
  106. syn=18;
  107. token[m++]=ch;
  108. }
  109. else
  110. {
  111. syn=17;
  112. ch=prog[--p];
  113. }
  114. break;
  115. case '+':syn=13;token[0]=ch;break;
  116. case '-':syn=14;token[0]=ch;break;
  117. case '*':
  118. syn=15;
  119. token[m++]=ch;
  120. ch=prog[p++];
  121. if (ch=='/')
  122. {
  123. mark2=1;
  124. return scaner();
  125. }
  126. ch=prog[--p];
  127. break;
  128. case '/':
  129. syn=16;
  130. token[m++]=ch;
  131. ch=prog[p++];
  132. if (ch=='/')
  133. {
  134. mark=0;
  135. while (mark==0)
  136. {
  137. scaner();
  138. }
  139. p++;
  140. //mark=0;
  141. }else if (ch=='*')
  142. {
  143. mark=1;
  144. syn=30; ///**/
  145. token[m++]='*';
  146. mark2=0;
  147. while(mark2==0)
  148. {
  149. scaner();
  150. }
  151. p++;
  152. //mark2=0;
  153. }
  154. ch=prog[--p];
  155. break;
  156. case ':=':syn=18;token[0]=ch;break;
  157. case '<>':syn=21;token[0]=ch;break;
  158. case '<=':syn=22;token[0]=ch;break;
  159. case '>=':syn=24;token[0]=ch;break;
  160. case '=':syn=25;token[0]=ch;break;
  161. case ';':syn=26;token[0]=ch;break;
  162. case '(':syn=27;token[0]=ch;break;
  163. case ')':syn=28;token[0]=ch;break;
  164. case '\n':
  165. syn = 29;
  166. token[0] = ch;
  167. mark = 1;
  168. return scaner();
  169. break;
  170. case '#':syn=0;token[0]=ch;break;
  171. case '\0':syn=1000;token[0]='\0';break;
  172. default:syn=-1;
  173. }
  174. }
  175. char *newtemp(void)
  176. {
  177. char *p;
  178. char m[8];
  179. p=(char *)malloc(8);
  180. k++;
  181. itoa(k,m,10);
  182. strcpy(p+1,m);
  183. p[0]='t';
  184. return(p);
  185. }
  186. //factor分析函数
  187. char * factor()
  188. {
  189. char *fplace;
  190. fplace=(char *)malloc(12);
  191. strcpy(fplace, " ");
  192. if(syn==10)
  193. {
  194. strcpy(fplace,token);
  195. scaner();
  196. }
  197. else if (syn==11)
  198. {
  199. itoa(sum,fplace,10);
  200. scaner();
  201. }
  202. else
  203. if(syn==27) //( 27
  204. {
  205. scaner();
  206. fplace=expression();
  207. if(syn==28)scaner();
  208. else
  209. {
  210. printf("缺少')' 出错!\n");
  211. kk=1;
  212. }
  213. }
  214. else
  215. {
  216. printf("表达式错误!\n");
  217. kk=1;
  218. }
  219. return (fplace);
  220. }
  221. //term分析函数
  222. char *term(void)
  223. {
  224. char *tp,*ep2,*eplace,*tt;
  225. tp=(char *)malloc(12);/*分配空间*/
  226. ep2=(char *)malloc(12);
  227. eplace=(char *)malloc(12);
  228. tt =(char *)malloc(12);
  229. strcpy(eplace,factor());
  230. while(syn==15||syn==16)
  231. {
  232. if(syn==15)
  233. {
  234. tt[0]='*';
  235. tt[1]='\0';
  236. }
  237. else if(syn==16)
  238. {
  239. tt[0]='/';
  240. tt[1]='\0';
  241. }
  242. scaner();
  243. strcpy(ep2,factor());
  244. strcpy(tp,newtemp()); //tp为临时变量
  245. emit(tp,eplace,tt,ep2); //将三地址代码送到四元式表
  246. strcpy(eplace,tp);
  247. //factor();
  248. }
  249. return (eplace);
  250. }
  251. //expression表达式分析函数
  252. char * expression()
  253. {
  254. char *tp,*ep2,*eplace,*tt;
  255. tp=(char *)malloc(12);/*分配空间*/
  256. ep2=(char *)malloc(12);
  257. eplace=(char *)malloc(12);
  258. tt =(char *)malloc(12);
  259. strcpy(eplace,term ());/*调用term分析产生表达式计算的第一项eplace*/
  260. while(syn==13||syn==14)
  261. {
  262. if(syn==13)
  263. {
  264. tt[0]='+';
  265. tt[1]='\0';
  266. }
  267. else if(syn==14)
  268. {
  269. tt[0]='-';
  270. tt[1]='\0';
  271. }
  272. scaner();
  273. strcpy(ep2,term());/*/调用term分析产生表达式计算的第二项ep2/*/
  274. strcpy(tp,newtemp());/*/调用newtemp产生临时变量tp存储计算结果/*/
  275. emit(tp,eplace,tt,ep2);/*/生成四元式送入四元式表/*/
  276. strcpy(eplace,tp);
  277. }
  278. return (eplace);
  279. }
  280. //statement语句分析函数
  281. statement()
  282. {
  283. //scaner();
  284. int schain=0;
  285. char tt[8],eplace[8];
  286. if(syn==10)
  287. {
  288. strcpy(tt,token);
  289. scaner();
  290. if(syn==18) //:= 18
  291. {
  292. scaner();
  293. strcpy(eplace,expression());
  294. emit(tt,eplace," "," ");
  295. schain=0;
  296. //expression();
  297. }
  298. else
  299. {
  300. printf("赋号值错误!\n");
  301. kk=1;
  302. }
  303. }
  304. else
  305. {
  306. printf("语句错误\n");
  307. //kk=1;
  308. }
  309. return (schain);
  310. }
  311. //语句串分析
  312. yucu()
  313. {
  314. int schain=0;
  315. schain=statement();
  316. while(syn!=6&&p!=length-1&&syn!=0)
  317. {
  318. if(syn!=26)
  319. scaner();
  320. while(syn==26) //26==;
  321. {
  322. scaner();
  323. if (syn!=0&&syn!=6)
  324. {
  325. schain=statement();
  326. }
  327. }
  328. }
  329. return (schain);
  330. }
  331. //递归下降分析程序
  332. lrparser()
  333. {
  334. int schain=0;
  335. scaner();
  336. if(syn!=1)
  337. {
  338. printf("begin错误\n");
  339. kk=1;
  340. }else
  341. scaner();
  342. schain=yucu();
  343. if (syn==6)
  344. {
  345. scaner();
  346. if(kk==0)
  347. printf("sucess");
  348. }else{
  349. if(kk!=1)
  350. kk=1;
  351. printf("缺少end\n");
  352. }
  353. return (schain);
  354. }
  355. void readFile(){
  356. int i = 0;
  357. char temp[255];
  358. /*ifstream fin("data.txt");*/
  359. FILE *fp=fopen("data.txt","r");
  360. while ((temp[i]=fgetc(fp))!=EOF)
  361. {
  362. prog[i++]=temp[i];
  363. }
  364. length = i;
  365. }
  366. int main()
  367. {
  368. int i;
  369. p=0;
  370. readFile();
  371. printf("\nplease intput string:");
  372. do
  373. {
  374. ch=getchar();
  375. prog[p++]=ch;
  376. }while(ch!='#');
  377. length=p;
  378. //将程序保存在prog字符数组中
  379. p=0;
  380. printf("词法分析:\n");
  381. do
  382. {
  383. scaner();
  384. if (syn<1000/*&&syn!=100&&syn!=101*/)
  385. {
  386. printf("(%d,%s)\n",syn,token);
  387. }
  388. } while (syn<1000);
  389. printf("\n\n");
  390. printf("语法分析:\n");
  391. p=0;
  392. //scaner();
  393. lrparser();
  394. printf("\n");
  395. printf("\n三地址指令如下:\n");
  396. for(i=0;i<count;i++)
  397. {
  398. printf("%s=",quad[i].result); //t1= //x=
  399. printf("%s",quad[i].ag1); //a //t1
  400. printf("%s",quad[i].op); //+
  401. printf("%s ",quad[i].ag2); //b
  402. printf("\n");
  403. }
  404. getch();
  405. }

四、实验结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/45744
推荐阅读
相关标签
  

闽ICP备14008679号