类型定义 #
/// ExprAST - AST 的基类
class ExprAST {
public:
virtual ~ExprAST() = default;
};
/// NumberExprAST - 数值类型的 AST 节点
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
};
/// VariableExprAST - 变量类型的 AST 节点
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
};
/// BinaryExprAST - 二元运算类型的 AST 节点
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
};
/// CallExprAST - 调用函数类型的 AST 节点
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
};
/// PrototypeAST - 函数原形定义类型的 AST 节点
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
: Name(Name), Args(std::move(Args)) {}
const std::string &getName() const { return Name; }
};
/// FunctionAST - 函数定义类型的 AST 节点
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
};
Parser #
/// top ::= definition | external | expression | ';'
/// 在主循环中,我们就是解析,TOP 由 definition | externale | expresson | ';' 构成
static void MainLoop() {
while (true) {
fprintf(stderr, "ready> ");
switch (CurTok) {
case tok_eof:
return;
case ';': // ignore top-level semicolons.
getNextToken();
break;
case tok_def:
HandleDefinition();
break;
case tok_extern:
HandleExtern();
break;
default:
HandleTopLevelExpression();
break;
}
}
}
// ParseTopLevelExpr 解释逻辑,是从 TOP 处理,也就是类似于 Main,
// PrototypeAST 特殊中 name 就是 "", 无参数
std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
auto Proto = std::make_unique<PrototypeAST>("", std::vector<std::string>());
return std::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
}
不过这里 Parser
使用的是
Top-down parsing
需要解决一个优先级的问题
比如在 *
优先级高于 +
,比如在解析
1 + 2 * 3
因此在这里比较复杂的代码如下
// 确定优先级表格
// 1 is lowest precedence.
BinopPrecedence['<'] = 10;
BinopPrecedence['+'] = 20;
BinopPrecedence['-'] = 20;
BinopPrecedence['*'] = 40; // highest.
/// binoprhs
/// ::= ('+' primary)*
/// ExprPrec 代表之前的优先级
// [EXAMPLE] 这里用 1 + 2 * 3 + 4 来解释一下
// [EXAMPLE] 第一次进这个函数, ExprPrec = 0, LHS = 1
std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
// 一个 Loop 循环
while (1) {
// 得到当前 Token 的优先级,比如 - 就是 20, * 就是 40
// [EXAMPLE] Token = + , TokPrec = 20
int TokPrec = GetTokPrecedence();
// 如果 前序的优先级比当前优先级高,就返回前序 AST 即可
if (TokPrec < ExprPrec)
return LHS;
// 存一下当前的 Token 操作符
int BinOp = CurTok;
getNextToken(); // 继续读取下一个 Token
// 解析 操作符后面的内容
// [EXAMPLE] RHS = 2
auto RHS = ParsePrimary();
if (!RHS)
return nullptr;
// 获取下一个操作符的优先级
// [EXAMPLE] NextToken = *, NextPrec = 40,
int NextPrec = GetTokPrecedence();
// 如果下一个操作符的优先级比当前操作符的优先级高,就把这个 RHS 传入开辟一个新的 BinOpRHS 来解析
// [EXAMPLE] 因为 NextPre 比 TokPrec 高,显然 2 应该和 后面的 * 进行组合,因此,把 2 传入 ParseBinOpRHS 解析
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
if (!RHS)
return nullptr;
}
// Merge LHS/RHS.
LHS = std::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
std::move(RHS));
} // loop around to the top of the while loop.
}