sumlanguage编译到栈式计算机的编译器的实现

it2024-12-11  20

这是慕课的一门编译原理的网课的第一次实践作业 

 

github 地址如下

sumlanguage

 

首先我们将文法翻译成数据结构

将目标机器上的指令也翻译成数据结构

 

如下是对sumlanguage的文法的翻译

该语言有两种具体表达式,一种是   一个int表达式   另一种是sum表达式 以及一种抽象的表达式

 

其中 kind 域用于区别是哪一种具体表达式

enum Exp_Kind_t {EXP_INT, EXP_SUM}; struct Exp_t{ enum Exp_Kind_t kind; }; struct Exp_Int{ enum Exp_Kind_t kind; int i; }; struct Exp_Sum{ enum Exp_Kind_t kind; struct Exp_t *left; struct Exp_t *right; };

 

以及他们的构造器

用malloc创建对应大小的块给这个表达式并初始化

struct Exp_t *Exp_Int_new (int i){ struct Exp_Int *p = malloc (sizeof(*p)); p->kind = EXP_INT; p->i = i; return (struct Exp_t *)p; } struct Exp_t *Exp_Sum_new (struct Exp_t *left, struct Exp_t *right){ struct Exp_Sum *p = malloc (sizeof(*p)); p->kind = EXP_SUM; p->left = left; p->right = right; return (struct Exp_t *)p; }

 

下面是机器指令的数据结构,这是一个栈式计算机

 

也是一个抽象数据结构和两个具体数据结构

enum Stack_Kind_t {STACK_ADD, STACK_PUSH}; struct Stack_t{ enum Stack_Kind_t kind; }; struct Stack_Add{ enum Stack_Kind_t kind; }; struct Stack_Push{ enum Stack_Kind_t kind; int i; };

 

以及它的构造器

对比表达式的数据结构,这里对栈式计算机的实现有点相似,不过不清楚这是不是一般性的套路,还要继续学习才能知道

struct Stack_t *Stack_Add_new (){ struct Stack_Add *p = malloc (sizeof(*p)); p->kind = STACK_ADD; return (struct Stack_t *)p; } struct Stack_t *Stack_Push_new (int i){ struct Stack_Push *p = malloc (sizeof(*p)); p->kind = STACK_PUSH; p->i = i; return (struct Stack_t *)p; }

 

然后是核心编译部分

这里用switch语句对表达式的类型进行判断

如果是int 表达式则直接产生栈式计算机的PUSH这条指令,如果是sum表达式则

需要递归的对左表达式进行compile然后对右表达式进行compile然后产生栈式计算机的Add指令

 

void compile (struct Exp_t *exp){ switch (exp->kind){ case EXP_INT:{ struct Exp_Int *p = (struct Exp_Int *)exp; emit (Stack_Push_new (p->i)); break; } case EXP_SUM:{ //TODO(); struct Exp_Sum *p=(struct Exp_Sum *)exp; compile(p->left); compile(p->right); emit (Stack_Add_new ()); break; } default: break; } }

 

这样一个简单的sum语言编译到栈式计算机的编译器就实现了

 

学到的知识点是

1.将文法翻译成数据结构

2.c中使用一个抽象数据结构实现抽象

3.目标机器的指令也用数据结构先保存

4.如何使用git的push和pull操作同步github的仓库

转载于:https://www.cnblogs.com/tclan126/p/8615213.html

最新回复(0)