读入的也可以是一个赋值语句:左端是一个符号名,右端是表达式。 表达式中可以有四则运算符、括号、整数/实数值、已经赋值的符号名和预定义的符号常量( pi 和 e ),也可以只有单个的整数/实数值。 发现输入内容与文法不符或将导致非法计算时,则从标准输出设备输出出错提示,并计算出错次数。写出此c++程序并给出注释
时间: 2024-02-29 14:51:14 浏览: 22
以下是一个实现该功能的 C++ 程序,注释在代码中:
```c++
#include <iostream>
#include <string>
#include <unordered_map>
#include <cmath>
using namespace std;
// 定义预定义符号常量 pi 和 e
const double PI = acos(-1);
const double E = exp(1);
// 定义全局变量,用于记录出错次数
int error_count = 0;
// 定义符号表,用于存储已经赋值的符号名和对应的值
unordered_map<string, double> symbol_table;
// 判断字符 c 是否为运算符
bool is_operator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
// 判断字符 c 是否为数字
bool is_digit(char c) {
return c >= '0' && c <= '9';
}
// 获取运算符的优先级
int get_priority(char op) {
if (op == '+' || op == '-') {
return 1;
} else {
return 2;
}
}
// 计算表达式的值,返回结果
double calculate(string expr) {
string postfix_expr = ""; // 存储转换后的后缀表达式
string num_str = ""; // 存储数字字符串
int num_left_paren = 0; // 记录左括号的数量
int num_right_paren = 0; // 记录右括号的数量
for (int i = 0; i < expr.length(); i++) {
char c = expr[i];
if (c == ' ') {
continue; // 忽略空格
} else if (c == '(') {
num_left_paren++;
postfix_expr += c;
} else if (c == ')') {
num_right_paren++;
if (num_right_paren > num_left_paren) {
cout << "Error: Mismatched parentheses." << endl;
error_count++;
return 0;
}
while (postfix_expr.length() > 0 && postfix_expr[postfix_expr.length()-1] != '(') {
postfix_expr += ' ';
postfix_expr += postfix_expr[postfix_expr.length()-3];
postfix_expr += ' ';
postfix_expr += postfix_expr[postfix_expr.length()-2];
postfix_expr += ' ';
postfix_expr += postfix_expr[postfix_expr.length()-1];
postfix_expr.pop_back();
postfix_expr.pop_back();
postfix_expr.pop_back();
postfix_expr.pop_back();
}
postfix_expr.pop_back();
} else if (is_operator(c)) {
while (postfix_expr.length() > 0 && postfix_expr[postfix_expr.length()-1] != '(' && get_priority(postfix_expr[postfix_expr.length()-1]) >= get_priority(c)) {
postfix_expr += ' ';
postfix_expr += postfix_expr[postfix_expr.length()-3];
postfix_expr += ' ';
postfix_expr += postfix_expr[postfix_expr.length()-2];
postfix_expr += ' ';
postfix_expr += postfix_expr[postfix_expr.length()-1];
postfix_expr.pop_back();
postfix_expr.pop_back();
postfix_expr.pop_back();
postfix_expr.pop_back();
}
postfix_expr += ' ';
postfix_expr += c;
} else {
num_str += c;
if (i == expr.length()-1 || is_operator(expr[i+1]) || expr[i+1] == ')' || expr[i+1] == '(') {
double num = stod(num_str);
postfix_expr += ' ';
postfix_expr += to_string(num);
num_str = "";
}
}
}
if (num_left_paren != num_right_paren) {
cout << "Error: Mismatched parentheses." << endl;
error_count++;
return 0;
}
if (postfix_expr.length() == 0) {
cout << "Error: Invalid expression." << endl;
error_count++;
return 0;
}
int start = 0;
int end = 0;
double result = 0;
for (int i = 0; i < postfix_expr.length(); i++) {
char c = postfix_expr[i];
if (c == ' ') {
continue;
} else if (is_operator(c)) {
end = i-1;
double num2 = stod(postfix_expr.substr(start, end-start+1));
start = i+1;
end = i+1;
while (end < postfix_expr.length() && postfix_expr[end] != ' ') {
end++;
}
double num1 = stod(postfix_expr.substr(start, end-start));
start = end+1;
if (c == '+') {
result = num1 + num2;
} else if (c == '-') {
result = num1 - num2;
} else if (c == '*') {
result = num1 * num2;
} else if (c == '/') {
if (num2 == 0) {
cout << "Error: Division by zero." << endl;
error_count++;
return 0;
}
result = num1 / num2;
}
postfix_expr = postfix_expr.substr(0, start-1) + to_string(result) + postfix_expr.substr(end);
i = start-2;
start = 0;
end = 0;
}
}
return stod(postfix_expr);
}
int main() {
string input_line;
while (getline(cin, input_line)) {
if (input_line.empty()) {
continue;
}
if (input_line == "quit") {
break;
}
int equal_sign_pos = input_line.find('=');
if (equal_sign_pos == string::npos) {
cout << "Error: Invalid expression." << endl;
error_count++;
continue;
}
string symbol_name = input_line.substr(0, equal_sign_pos);
string expr_str = input_line.substr(equal_sign_pos+1);
if (symbol_name.empty() || expr_str.empty()) {
cout << "Error: Invalid expression." << endl;
error_count++;
continue;
}
if (symbol_table.find(symbol_name) != symbol_table.end()) {
cout << "Error: Symbol " << symbol_name << " already exists." << endl;
error_count++;
continue;
}
double result = calculate(expr_str);
if (error_count == 0) {
symbol_table[symbol_name] = result;
cout << symbol_name << " = " << result << endl;
} else {
error_count = 0;
}
}
return 0;
}
```
该程序实现了读入一个赋值语句,计算表达式的值,并将符号名和对应的值存储到符号表中。如果输入内容与文法不符或导致非法计算,则从标准输出设备输出出错提示,并计算出错次数。