我的第一篇博客:编译器实践一 之 加法栈式计算机
最近学习了一点简单的Bison再加上抽象语法树,于是做了一下MOOC的留下的作业,按照要求,改了和增加了几处代码,感觉学到了很多东西。不过为了减少难度,突出侧重点,我没有去管理内存,内存泄露有点严重,代码仅供参考。
功能是输入一行或者多行算术表达式,对表达式建立抽象语法树,然后输出(主要是为了查看抽象表达式建立的是否准确),编译,完成对栈式计算机的模拟,原来的代码不支持减法,除法,括号表达式,并且只能完成一行的编译,我把它推广到了任意行数。
下面是对抽象语法树的定义:
/*ast.h*/
#ifndef AST_H
#define AST_H
enum Exp_Kind_t{
EXP_INT,
EXP_ADD,
EXP_TIMES,
EXP_DIV,
EXP_SUB};
/*
E -> n
| E + E
| E * E
*/
typedef struct Exp_t *Exp_t;
struct Exp_t{
enum Exp_Kind_t kind;
};
// all operations on "Exp"
void Exp_print (Exp_t exp);
int Exp_numNodes (Exp_t exp);
typedef struct Exp_Int *Exp_Int;
struct Exp_Int{
enum Exp_Kind_t kind;
int n;
};
Exp_t Exp_Int_new (int n);
typedef struct Exp_Add *Exp_Add;
struct Exp_Add{
enum Exp_Kind_t kind;
Exp_t left;
Exp_t right;
};
Exp_t Exp_Add_new (Exp_t left, Exp_t right);
typedef struct Exp_Times *Exp_Times;
struct Exp_Times{
enum Exp_Kind_t kind;
Exp_t left;
Exp_t right;
};
Exp_t Exp_Times_new (Exp_t left, Exp_t right);
typedef struct Exp_Div *Exp_Div;
struct Exp_Div{
enum Exp_Kind_t kind;
Exp_t left;
Exp_t right;
};
Exp_t Exp_Div_new (Exp_t left, Exp_t right);
typedef struct Exp_Sub *Exp_Sub;
struct Exp_Sub{
enum Exp_Kind_t kind;
Exp_t left;
Exp_t right;
};
Exp_t Exp_Sub_new (Exp_t left, Exp_t right);
#endif
下面是ast.h的实现:
/*ast.c*/
#include <stdio.h>
#include <stdlib.h>
#include "ast.h"
// "constructors"
Exp_t Exp_Int_new (int n)
{
Exp_Int p = malloc (sizeof (*p));
p->kind = EXP_INT;
p->n = n;
return (Exp_t)p;
}
Exp_t Exp_Add_new (Exp_t left, Exp_t right)
{
Exp_Add p = malloc (sizeof