编写一个计算机程序,用于判断输入字符串是否为命题公式。输入含有命题变量、逻辑运算符、左右括号字符串,输出若为命题公式返回其抽象语法树,否则返回空树
时间: 2024-10-07 19:04:10 浏览: 132
编写这样一个程序通常需要结合词法分析(Lexer)和语法分析(Parser)。我们可以使用递归下降解析或自底向上的方法,如LR或LL解析器。这里是一个简化的例子,假设我们只考虑最基础的二元运算符(AND, OR)和括号,并且忽略优先级规则,先使用词法分析分割字符串:
```cpp
#include <iostream>
#include <stack>
#include <string>
// 定义一个简单的语法节点
struct Node {
char op; // 运算符
Node* left = nullptr;
Node* right = nullptr;
};
Node* parseFormula(std::string formula) {
if (formula.empty()) {
return nullptr;
}
std::stack<Node*> nodes;
for (char c : formula) {
switch (c) {
case '(':
nodes.push(new Node());
break;
case ')':
if (nodes.empty() || nodes.top()->op != '(') {
throw std::runtime_error("Invalid parentheses");
}
Node* top = nodes.top();
nodes.pop();
top->right = nodes.top();
nodes.pop();
break;
default:
if (isalpha(c)) { // 命题变量
Node* node = new Node();
node->left = new Node();
node->left->op = c;
nodes.push(node);
} else if (c == 'A' || c == 'O') { // 逻辑运算符
if (nodes.empty()) {
throw std::runtime_error("Operator without operands");
}
Node* node = new Node();
node->op = c;
node->left = nodes.top();
nodes.pop();
nodes.push(node);
while (!nodes.empty() && nodes.top()->op == c) { // 消耗连续的相同运算符
node->right = nodes.top();
nodes.pop();
}
}
}
}
if (!nodes.empty()) {
throw std::runtime_error("Unmatched closing parenthesis");
}
return nodes.top();
}
int main() {
try {
std::string input = "A(a) O(b)";
Node* tree = parseFormula(input);
if (tree) {
// 输出抽象语法树的信息(这里仅做示例,实际应用中可能需要遍历并打印)
std::cout << "Abstract Syntax Tree:\n";
printTree(tree);
} else {
std::cout << "Not a valid proposition formula.\n";
}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << "\n";
}
return 0;
}
void printTree(Node* node) {
if (node) {
std::cout << node->op;
if (node->left) {
printTree(node->left);
}
if (node->right) {
std::cout << "(";
printTree(node->right);
std::cout << ")";
}
std::cout << '\n';
}
}
```
注意这只是一个非常基础的版本,实际的实现会更复杂,包括处理优先级和更多的运算符,以及处理无效的输入。
阅读全文