此文章用于记录第一次编译器实验的实践心得以及一些知识记录。
次实验主要目的是将C语言代码转换成对应的汇编代码,这就涉及到对与表达式的处理。
我们一般使用的表达式是中缀表达式,这对于我们人来说是比较好识别并且计算的。但对于机器,内部都是按照从左到右的顺序来处理表达式,所以在面对含有不同优先级的表达式时并不是很好处理,这时我们就需要把中缀表达式转换成后缀表达式,来便于计算机的运算。
中缀表达式转换为后缀表达式_中缀表达式转后缀表达式-CSDN博客
这篇博客主要介绍了两种转换方法:
使用栈的方法:(逆波兰算法)
括号法:
vector<string> infixToPostfix(const vector<string>& tokens) {
stack<string> ops; // 运算符栈
vector<string> postfix; // 后缀表达式令牌
for (int i = 0; i < tokens.size();i++) {
if (isdigit(tokens[i][0]) || isalpha(tokens[i][0])) { // 数字或变量直接输出
postfix.push_back(tokens[i]);
}
else if (tokens[i] == "(") {
ops.push(tokens[i]);
}
else if (tokens[i] == ")") {//弹出字符直到为空或者遇到左括号
while (!ops.empty() && ops.top() != "(") {
postfix.push_back(ops.top());
ops.pop();
}
ops.pop(); // 弹出"("
}
else if (isOperator(tokens[i])) {
while (!ops.empty() && isOperator(ops.top()) && getPrecedence(ops.top()) >= getPrecedence(tokens[i])) {
postfix.push_back(ops.top());
ops.pop();
}
ops.push(tokens[i]); // 将当前运算符压入栈
}
}
while (!ops.empty()) {
postfix.push_back(ops.top());
ops.pop();
}
return postfix;
}
然后我们需要根据得到的后缀表达式,一次扫描来得到对应的汇编代码。
void evalutePostfix(const vector<string>& postfix, const unordered_map<string, int>& variables) {
for (const string& token : postfix) {
if (isdigit(token[0])) {
cout << "mov eax, "<<token<<"" << endl;
cout << "push eax" << endl;
}
else if (isalpha(token[0])) {
cout << "mov eax, DWORD PTR [ebp" << variables.at(token) << "]" << endl;
cout << "push eax" << endl;
}
else {
if (token == "+") {
cout << "pop ebx" << endl;
cout << "pop eax" << endl;
cout << "add eax, ebx" << endl;
cout << "push eax" << endl;
}
else if (token == "-") {
cout << "pop ebx" << endl;
cout << "pop eax" << endl;
cout << "sub eax, ebx" << endl;
cout << "push eax" << endl;
}
else if (token == "*") {
cout << "pop ebx" << endl;
cout << "pop eax" << endl;
cout << "imul eax, ebx" << endl;
cout << "push eax" << endl;
}
else if (token == "/") {
cout << "pop ebx" << endl;
cout << "pop eax" << endl;
cout << "cdq" << endl;
cout << "idiv ebx" << endl;
cout << "push eax" << endl;
}
}
}
cout << "pop eax" << endl;
}
其他的就还比较好解决 。