Hello Compiler
Posted 十木禾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hello Compiler相关的知识,希望对你有一定的参考价值。
源语言 : 加法表达式语言,支持形如 1+1
、1+2+3
…… 的运算
目标机器:栈式计算机,支持push(n)
、add()
两种操作(使用C++模拟)
构造一个栈式计算机
#include<iostream>
#define ERROR -9999;
using namespace std;
class StackComputer
private:
int stack_arr[100]; // 操作数栈
int head = 0; // 栈顶指针
int pop()
if(this->head < 1) return ERROR;
this->head--;
return this->stack_arr[this->head];
public:
StackComputer() = default;
void push(int n)
this->stack_arr[this->head] = n;
this->head ++;
int add()
if(this->head < 2) return ERROR;
int result = this->pop() + this->pop();
this->push(result);
return result;
void print() // 打印结果
if(this->head == 1) cout<<this->pop()<<endl;
;
main
函数如下
int main()
StackComputer c;
c.push(1);
c.push(10);
c.add();
c.push(100);
c.add();
c.print(); // 输出111
现在我们编写一个编译器将1+10+100
编译成:
c.push(1);
c.push(10);
c.add();
c.push(100);
c.add();
c.print();
编写编译器
步骤说明
首先将1+10+100
生成如下的抽象语法树
然后对该二叉树进行后续遍历,按照如下的规则生成代码
- 遇到整数
n
,则生成c.push(n)
- 遇到操作符
+
,则生成c.add()
- 遍历完成整棵树以后,生成
c.print()
构造抽象语法树
#define MODE_NUM 0
#define MODE_CHAR 1
typedef struct AbsTree* BinTree;
struct AbsTree
int mode;
int data;
bool isRoot; // 标记当前节点是否为根节点
BinTree left, right;
; // 一棵二叉树
BinTree genTree(int mode, int data) // 生成二叉树结点的工具
BinTree tree = (BinTree)malloc(sizeof(AbsTree));
tree->left = NULL;
tree->right = NULL;
tree->isRoot = false;
if(mode == MODE_NUM) tree->data = data;
tree->mode = mode;
return tree;
BinTree genAbsTree(char* lang) // 生成抽象语法树并返回根节点
BinTree root = NULL, left = NULL, right = NULL;
for(int i=0; i<strlen(lang); i++)
char elem = lang[i];
bool isNum = isdigit(elem);
if(isNum) // 扫描到数字
int num = elem - 48;
// 将字符串数字转化为数字[如 '123' -> 123]
while(i+1 < strlen(lang)
&& isdigit(lang[i+1]))
num = num*10 + (lang[++i] - 48);
if(left == NULL)
left = genTree(MODE_NUM, num);
else
right = genTree(MODE_NUM, num);
root->right = right;
root->left = left;
left = root;
else // 扫描到非数字
if (elem == ' ') continue;
root = genTree(MODE_CHAR, -1);
root->left = left;
if (root!=NULL) root->isRoot = true; // 标记当前结点为根节点
return root;
生成目标代码
// 树的后序遍历生成目标代码
void genTargetCode(BinTree node)
if(node == NULL) return;
genTargetCode(node->left);
genTargetCode(node->right);
if (node->mode == MODE_NUM)
printf("c.push(%d);\\n", node->data);
else
printf("c.add();\\n");
if(node->isRoot) printf("c.print();\\n");
测试
int main()
char sum_exp[100] = "1 + 10 + 100";
BinTree root = genAbsTree(sum_exp);
genTargetCode(root);
运行之后生成目标代码正确。
以上是关于Hello Compiler的主要内容,如果未能解决你的问题,请参考以下文章
[An Introduction to GCC 学习笔记] 15 How the compiler works, Identifying files
[An Introduction to GCC 学习笔记] 15 How the compiler works, Identifying files
gcc 中-lfoo表示啥意思。 这个中gcc foo.c -L /home/lib -lfoo -o hello