码迷,mamicode.com
首页 > 其他好文 > 详细

读龙书学编译原理 语法翻译(3)...

时间:2016-05-28 01:10:38      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:

接着上节讲, 我们来看如何在分析中插入合适的代码来生成语法树...

技术分享

对于抽象语法树的总结 :

技术分享

下面是作业 :

【抽象语法树】

在这个题目中,你将完整的实现抽象语法树(包括数据结构的定义、语法树的生成等)。首先,请下载我们提供的代码包:

http://staff.ustc.edu.cn/~bjhua/mooc/ast.zip

代码的运行方式是:

首先生成语法分析器:

  $ bison exp.y

然后生成编译器:

  $ gcc main.c exp.tab.c ast.c

最后使用编译器编译某个源文件:

  $ a.exe <test.txt

 

在提供的代码里,我们已经提供了抽象语法树的定义、若干操作、及由bison生成语法树的代码框架。你的任务是:

  1. 进一步完善该代码框架,使其能够分析减法、除法和括号表达式;(你需要修改语法树的定义,修改bison源文件及其它代码)

  2. 重新研究第一次作业中的从Sum编译到Stack的小型编译器代码,把他移植到目前的代码框架中,这样你的编译器能够从文本文件中读入程序,然后输出编译的结果。(注意,你必须扩展你的编译器,让他能够支持减法和除法。)

代码实现 :

 1 %{
 2 #include <stdio.h>
 3 #include "ast.h"
 4   int yylex(); // this function will be called in the parser
 5   void yyerror(char *);
 6 
 7   Exp_t tree;
 8 
 9   %}
10 
11 %union{
12   Exp_t exp;
13  }
14 
15 %type <exp> digit exp program
16 
17 
18 %left + -
19 %left * /
20 
21 %start program
22 
23 %%
24 
25 program: exp \n{tree = $1;}
26 ;
27 
28 exp: digit     {$$ = $1;}
29 | exp + exp  {$$ = Exp_Add_new ($1, $3);}
30 | exp - exp  {$$ = Exp_Minus_new ($1, $3);}
31 | exp * exp  {$$ = Exp_Times_new ($1, $3);}
32 | exp / exp  {$$ = Exp_Divide_new ($1, $3);}
33 ;
34 
35 digit: 0  {$$ = Exp_Int_new (0);}
36 | 1       {$$ = Exp_Int_new (1);}
37 | 2       {$$ = Exp_Int_new (2);}
38 | 3       {$$ = Exp_Int_new (3);}
39 | 4       {$$ = Exp_Int_new (4);}
40 | 5       {$$ = Exp_Int_new (5);}
41 | 6       {$$ = Exp_Int_new (6);}
42 | 7       {$$ = Exp_Int_new (7);}
43 | 8       {$$ = Exp_Int_new (8);}
44 | 9       {$$ = Exp_Int_new (9);}
45 | (exp) {$$ = $2;}
46 ;
47 
48 %%
49 
50 int yylex ()
51 {
52   int c = getchar();
53   return c;
54 }
55 
56 // bison needs this function to report
57 // error message
58 void yyerror(char *err)
59 {
60   fprintf (stderr, "%s\n", err);
61   return;
62 }
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include "ast.h"
 4 
 5 // "constructors"
 6 Exp_t Exp_Int_new (int n)
 7 {
 8   Exp_Int p = malloc (sizeof (*p));
 9   p->kind = EXP_INT;
10   p->n = n;
11   return (Exp_t)p;
12 }
13 
14 Exp_t Exp_Add_new (Exp_t left, Exp_t right)
15 {
16   Exp_Add p = malloc (sizeof (*p));
17   p->kind = EXP_ADD;
18   p->left = left;
19   p->right = right;
20   return (Exp_t)p;
21 }
22 
23 Exp_t Exp_Minus_new (Exp_t left, Exp_t right)
24 {
25   Exp_Add p = malloc (sizeof (*p));
26   p->kind = EXP_MINUS;
27   p->left = left;
28   p->right = right;
29   return (Exp_t)p;
30 }
31 
32 Exp_t Exp_Times_new (Exp_t left, Exp_t right)
33 {
34   Exp_Add p = malloc (sizeof (*p));
35   p->kind = EXP_TIMES;
36   p->left = left;
37   p->right = right;
38   return (Exp_t)p;
39 }
40 
41 Exp_t Exp_Divide_new (Exp_t left, Exp_t right)
42 {
43   Exp_Add p = malloc (sizeof (*p));
44   p->kind = EXP_DIVIDE;
45   p->left = left;
46   p->right = right;
47   return (Exp_t)p;
48 }
49 // all operations on "Exp"
50 void Exp_print (Exp_t exp)
51 {
52   switch (exp->kind){
53   case EXP_INT:{
54     Exp_Int p = (Exp_Int)exp;
55     printf ("%d", p->n);
56     return;
57   }
58   case EXP_ADD:{
59     Exp_Add p = (Exp_Add)exp;
60     printf ("(");
61     Exp_print (p->left);
62     printf (") + (");
63     Exp_print (p->right);
64     printf (")");
65     return;
66   }
67   case EXP_MINUS:{
68     Exp_Minus p = (Exp_Minus)exp;
69     printf ("(");
70     Exp_print (p->left);
71     printf (") - (");
72     Exp_print (p->right);
73     printf (")");
74     return;
75   }
76   case EXP_TIMES:{
77     Exp_Times p = (Exp_Times)exp;
78     printf ("(");
79     Exp_print (p->left);
80     printf (") * (");
81     Exp_print (p->right);
82     printf (")");
83     return;
84   }
85   case EXP_DIVIDE:{
86     Exp_Divide p = (Exp_Divide)exp;
87     printf ("(");
88     Exp_print (p->left);
89     printf (") / (");
90     Exp_print (p->right);
91     printf (")");
92     return;
93   }
94   default:
95     return;
96   }
97 }

 

剩下的两个文件改动不大就不贴代码了...

读龙书学编译原理 语法翻译(3)...

标签:

原文地址:http://www.cnblogs.com/nzhl/p/5536617.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!