一道习题,来吧,英雄们
写一个宏处理器,它能够定义和展开不带参数的宏(像C预处理器那样)。它从cin读并向cout写。 只要能定义和展开宏,预处理器不管C语言作用域和生命周期规则。宏名字的命名规则和C的命名规则相同。 来吧,英雄们。[此贴子已经被作者于2023-4-25 10:40编辑过]
#include <iostream> #include <string> #include <map> using namespace std; // 宏定义结构体 struct Macro { string value; // 宏的值 Macro() {} Macro(string v) : value(v) {} }; // 存放宏定义的map map<string, Macro> macro_map; // 宏展开函数 string expand_macro(string input) { string output = ""; int i = 0; while (i < input.size()) { if (input[i] == '#') { // 如果是#,就将它和后面的token连接成一个字符串 i++; while (i < input.size() && input[i] == ' ') { i++; // 跳过空格 } if (i == input.size()) { return output; // 如果宏没有参数了,就返回当前展开结果 } string token = ""; while (i < input.size() && input[i] != ' ') { token += input[i]; i++; } if (macro_map.count(token)) { output += macro_map[token].value; } else { output += "#" + token; // 如果找不到宏定义,就原样输出 } } else if (input[i] == '(') { // 如果是左括号,就认为是宏调用 i++; while (i < input.size() && input[i] == ' ') { i++; // 跳过空格 } string name = ""; while (i < input.size() && input[i] != ' ' && input[i] != ')') { name += input[i]; i++; } if (macro_map.count(name)) { // 找到宏定义了,就展开宏 string arg_str = ""; while (i < input.size() && input[i] != ')') { arg_str += input[i]; i++; } if (i == input.size()) { return output; // 如果没有右括号,就返回当前展开结果 } i++; // 跳过右括号 if (arg_str == "") { output += macro_map[name].value; } else { // 替换宏定义中的所有参数 string value = macro_map[name].value; int pos = 0; while ((pos = value.find("#", pos)) != string::npos) { if (pos == value.size() - 1) { break; } int arg_num = value[pos + 1] - '0'; if (arg_num > 0 && arg_num <= arg_str.size()) { string arg_value = ""; int j = 0; while (j < arg_str.size() && arg_str[j] == ' ') { j++; } while (j < arg_str.size() && arg_str[j] != ',' && arg_str[j] != ')') { arg_value += arg_str[j]; j++; } value.replace(pos, 2, arg_value); } else { pos++; } } output += expand_macro(value); } } else { output += "(" + name; // 不是宏调用,就原样输出 } } else { output += input[i]; i++; } } return output; } // 宏定义函数 void define_macro() { string name, value; cin >> name; getline(cin, value); macro