首先特别感谢网易公司,网易公司提供的云课堂,公开课实在是太好了,有了这些东西我们这些渣渣学校的也可以学习国内外名校的课程了。
由于我在大学学习的网络工程,大学的时候自己也too young,学校没教《编译原理》这门课,自己也没主动接触过,看到许多大牛都很推荐学习《编译原理》这门课堂(程序员的三大浪漫之一:操作系统,编译原理,图形学),所以我也就很关注网易云课堂的这门课,最近这门课终于开了,所以把自己的学习历程记录下来吧,希望课程结束的时候自己能够写出来一个简单的编译器。
课程主页在这里:网易云课堂--中国科学技术大学--编译原理
注:有些图片直接从该课程讲师 @华保健 老师提供的ppt中截取。已经在征取老师的意见了,如果不合适的话,我会重新制作插图。
什么是编译器
编译器和解释器
编译器的结构
1:分析部分
2:综合部分
编译器的优化
- 优化必须是正确的。也就是说,不能改变被编译程序的意思
- 优化必须能够改善很多程序的性能
- 优化所需要的时间必须在可接受范围内
- 优化所需要的工程方面的工作必须是可管理的
编译器的第一个课堂作业
#include <iostream>
#include <vector>
#include <cassert>
class Expression
{
public:
Expression() { }
virtual ~Expression() { }
enum EXP_TYPE { ET_INT, ET_SUM };
virtual EXP_TYPE type() = 0;
};
class Expression_Int : public Expression
{
public:
Expression_Int(int v) : value_(v) { }
virtual ~Expression_Int() { }
virtual Expression::EXP_TYPE type() override
{ return Expression::ET_INT; }
int value() const { return value_; }
private:
int value_;
};
class Expression_Sum : public Expression
{
public:
Expression_Sum(Expression* left, Expression* right)
: left_(left), right_(right) { }
virtual ~Expression_Sum() { }
virtual Expression::EXP_TYPE type() override
{ return Expression::ET_SUM; }
Expression* left() { return left_; }
Expression* right() { return right_; }
private:
Expression* left_;
Expression* right_;
};
class Compiler
{
struct StackElem
{
enum ELEM_TYPE { ET_PUSH, ET_ADD };
ELEM_TYPE type_;
union
{
int value;
} context;
};
public:
void process(Expression* exp)
{
if (!exp) return;
switch (exp->type())
{
case Expression::ET_INT:
{
Expression_Int* p = dynamic_cast<Expression_Int*>(exp);
assert(p);
StackElem se;
se.type_ = StackElem::ET_PUSH;
se.context.value = p->value();
elemVec.push_back(se);
break;
}
case Expression::ET_SUM:
{
Expression_Sum* p = dynamic_cast<Expression_Sum*>(exp);
assert(p);
process(p->left());
process(p->right());
StackElem se;
se.type_ = StackElem::ET_ADD;
elemVec.push_back(se);
break;
}
default:
break;
}
}
void show()
{
for (auto e : elemVec)
{
switch (e.type_)
{
case StackElem::ET_ADD:
{
std::cout << "ADD" << std::endl;
break;
}
case StackElem::ET_PUSH:
{
std::cout << "PUSH " << e.context.value << std::endl;
break;
}
default:
break;
}
}
}
private:
std::vector<StackElem> elemVec; //stack
};
int main()
{
std::cout << "Compile starting" << std::endl;
// build an expression tree:
// +
// / \
// + 4
// / \
// 2 3
Expression* left = new Expression_Sum(new Expression_Int(2), new Expression_Int(3));
Expression* right = new Expression_Int(4);
Expression* exp = new Expression_Sum(left, right);
Compiler c;
c.process(exp);
c.show();
return 0;
}