编译原理——中间代码生成

一、实验目的

掌握中间代码的生成方法

学会临时变量的使用和分配方法。

二、实验题目

编写相应的Lex和Yacc程序,将整数表达式的翻译成三地址代码。

整数表达式中可能含有 + - * /  (  )  和 变量, 

例如,下列表达式

    a + b * ( c - d ) + e / ( c + d )

翻译为:

    t1 = c - d

    t2 = b * t1

    t3 = a + t2

    t4 = c + d

    t5 = e / t4

    t6 = t3 + t5

三、实验内容

生成表达式的三地址码表示。

尝试优化临时变量的使用(选做)。

Lex程序:

%{

    #include "syntax.tab.h"

    #include <stdio.h>

    #include <stdlib.h>

    #include "var.h"

    int yyerror(const char *);

    %}

   

    letter         [A-Za-z_]

    digit          [0-9]

    identifier     {letter}({letter}|{digit})*

     

    %%

    [0-9]+         {  yylval = var_new_const(yytext);  return INTEGER; }

    {identifier}   {  yylval = var_find(yytext);  return  IDENTIFIER; }

    [+\-*/()=\n]    {  return *yytext;  /* 返回操作符 */  }

    [ \t]      {  ; /* skip whitespace */  }

    .          {  yyerror("invalid character");  }

    %%

    int yywrap() {

        return 1;

    }

   

Yacc程序:

%{

#include <stdio.h>

#include <stdlib.h>



#include "var.h"

int yylex(void);

int yyerror(const char *);

%}

%token IDENTIFIER

%token INTEGER

%right '='

%left '+' '-'

%left '*' '/'

%%

program:  

    program expr '\n' {    }

    |

    ;

expr:

  INTEGER { $$ = $1; }

  | IDENTIFIER { $$ = $1 ; }

  | expr '+' expr  {  $$=var_new_temp();  printf("  %s = %s + %s\n", var_get_name($$), var_get_name($1), var_get_name($3));  }

  | expr '-' expr  {  $$=var_new_temp();  printf("  %s = %s - %s\n", var_get_name($$), var_get_name($1), var_get_name($3));  }

  | expr '*' expr  {  $$=var_new_temp();  printf("  %s = %s * %s\n", var_get_name($$), var_get_name($1), var_get_name($3));  }

  | expr '/' expr  {  $$=var_new_temp();  printf("  %s = %s / %s\n", var_get_name($$), var_get_name($1), var_get_name($3));  }

  | '(' expr ')'   { $$=$2; }

  | IDENTIFIER '=' expr {  printf("  %s = %s\n", var_get_name($1), var_get_name($3) );  $$=$1; }

;

%%

int yyerror(const char *s) {

 fprintf(stderr, "error: %s\n", s);

 return 0;

}

int main() {

    yyparse();

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜不下的黄昏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值