使用C++,实现中缀表达式转换成抽象语法树,输出结果为语法树的样子
时间: 2024-03-17 21:40:48 浏览: 84
C++实现中缀表达式转后缀表达式
5星 · 资源好评率100%
下面是使用C++实现中缀表达式转换成抽象语法树的示例代码:
```cpp
#include <iostream>
#include <stack>
using namespace std;
// 定义抽象语法树节点结构体
struct ASTNode {
char op; // 操作符
int val; // 操作数
ASTNode* left; // 左子树
ASTNode* right; // 右子树
ASTNode(char op, int val) {
this->op = op;
this->val = val;
this->left = nullptr;
this->right = nullptr;
}
};
// 判断是否为操作符
bool isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
// 比较操作符优先级
int priority(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
// 中缀表达式转换成抽象语法树
ASTNode* infixToAST(string expr) {
stack<ASTNode*> nodeStack; // 节点栈
stack<char> opStack; // 操作符栈
for (int i = 0; i < expr.length(); i++) {
char c = expr[i];
if (isdigit(c)) { // 如果是数字,将其转换成操作数节点
int val = c - '0';
while (i + 1 < expr.length() && isdigit(expr[i + 1])) {
val = val * 10 + (expr[++i] - '0');
}
ASTNode* node = new ASTNode('\0', val);
nodeStack.push(node);
} else if (isOperator(c)) { // 如果是操作符,将其转换成操作符节点
while (!opStack.empty() && priority(opStack.top()) >= priority(c)) {
char op = opStack.top(); opStack.pop();
ASTNode* right = nodeStack.top(); nodeStack.pop();
ASTNode* left = nodeStack.top(); nodeStack.pop();
ASTNode* node = new ASTNode(op, 0);
node->left = left;
node->right = right;
nodeStack.push(node);
}
opStack.push(c);
} else if (c == '(') { // 左括号入栈
opStack.push(c);
} else if (c == ')') { // 右括号出栈
while (opStack.top() != '(') {
char op = opStack.top(); opStack.pop();
ASTNode* right = nodeStack.top(); nodeStack.pop();
ASTNode* left = nodeStack.top(); nodeStack.pop();
ASTNode* node = new ASTNode(op, 0);
node->left = left;
node->right = right;
nodeStack.push(node);
}
opStack.pop();
}
}
// 处理剩余的操作符
while (!opStack.empty()) {
char op = opStack.top(); opStack.pop();
ASTNode* right = nodeStack.top(); nodeStack.pop();
ASTNode* left = nodeStack.top(); nodeStack.pop();
ASTNode* node = new ASTNode(op, 0);
node->left = left;
node->right = right;
nodeStack.push(node);
}
return nodeStack.top();
}
// 输出抽象语法树
void printAST(ASTNode* node, int indent = 0) {
if (node == nullptr) return;
for (int i = 0; i < indent; i++) cout << " ";
if (node->op == '\0') {
cout << node->val << endl;
} else {
cout << node->op << endl;
printAST(node->left, indent + 2);
printAST(node->right, indent + 2);
}
}
int main() {
string expr = "3*(4+5)-6/(1+2)";
ASTNode* root = infixToAST(expr);
printAST(root);
return 0;
}
```
在这个示例中,我们定义了一个ASTNode结构体表示抽象语法树节点,包括操作符、操作数、左子树和右子树四个成员变量。然后,我们使用两个栈分别存储节点和操作符,遍历中缀表达式,根据优先级规则将操作符转换成操作符节点,并将其作为子节点放入其它节点中。最后,我们输出抽象语法树的样子,可以看到它的结构和中缀表达式的结构类似,但更加清晰易懂。
阅读全文