zoukankan      html  css  js  c++  java
  • 语法翻译(3)...

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

    对于抽象语法树的总结 :

    下面是作业 :

    【抽象语法树】

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

    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 '
    '{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
    ", 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 }

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

  • 相关阅读:
    Mysql注入绕过姿势
    轻松入侵我学校网站
    华科机考:矩阵转置
    浙大patB习题的一点总结
    链表的一些基本操作
    关于C中函数传参的一点理解
    Java与JavaScript中判断两字符串是否相等的区别
    Jsp中out.println()与System.out.println()的区别
    eclipse背景主题
    Kruskal算法的简单实现
  • 原文地址:https://www.cnblogs.com/nzhl/p/5536617.html
Copyright © 2011-2022 走看看