| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 936 人关注过本帖
标题:一道习题,来吧,英雄们
只看楼主 加入收藏
辛或
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2023-4-17
结帖率:0
收藏
 问题点数:0 回复次数:5 
一道习题,来吧,英雄们
写一个宏处理器,它能够定义和展开不带参数的宏(像C预处理器那样)。它从cin读并向cout写。 只要能定义和展开宏,预处理器不管C语言作用域和生命周期规则。宏名字的命名规则和C的命名规则相同。 来吧,英雄们。

[此贴子已经被作者于2023-4-25 10:40编辑过]

搜索更多相关主题的帖子: 习题 处理器 规则  英雄 
2023-04-25 08:19
东海ECS
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:Python
等 级:版主
威 望:32
帖 子:412
专家分:1646
注 册:2023-1-24
收藏
得分:0 
程序代码:
#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




会当凌绝顶,一览众山小.
2023-04-25 18:42
辛或
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2023-4-17
收藏
得分:0 
以下是引用东海ECS在2023-4-25 18:42:33的发言:

#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 == '#') { // 如果是#,就将它和后面的token连接成一个字符串 i++; while (i < input.size() && input == ' ') { i++; // 跳过空格 } if (i == input.size()) { return output; // 如果宏没有参数了,就返回当前展开结果 } string token = ""; while (i < input.size() && input != ' ') { token += input; i++; } if (macro_map.count(token)) { output += macro_map[token].value; } else { output += "#" + token; // 如果找不到宏定义,就原样输出 } } else if (input == '(') { // 如果是左括号,就认为是宏调用 i++; while (i < input.size() && input == ' ') { i++; // 跳过空格 } string name = ""; while (i < input.size() && input != ' ' && input != ')') { name += input; i++; } if (macro_map.count(name)) { // 找到宏定义了,就展开宏 string arg_str = ""; while (i < input.size() && input != ')') { arg_str += input; 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++; } } return output; }

// 宏定义函数 void define_macro() { string name, value; cin >> name; getline(cin, value); macro

大哥,您这代码,没法看啊....
2023-04-25 19:22
辛或
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2023-4-17
收藏
得分:0 
以下是引用东海ECS在2023-4-25 18:42:33的发言:



// 宏定义函数 void define_macro() { string name, value; cin >> name; getline(cin, value); macro

整理了半天,发现还没有写完。晕倒。。。。。。你发个完整的来吧。宏不用带参数,你这个是带参数的。

[此贴子已经被作者于2023-4-25 19:34编辑过]

2023-04-25 19:33
辛或
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2023-4-17
收藏
得分:0 
回复 2楼 东海ECS
大哥,我又仔细看了一下,你这个token是按照空格来判断的,这个有点随意啊,a+b,(标志符+标志符) 中间不能认为是有空格啊。
2023-04-25 19:52
辛或
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2023-4-17
收藏
得分:0 
回复 3楼 辛或
大哥,您别嫌我麻烦,等了一天,就您给了个回复,激动得不行。我觉得您已经写得很好了。
再给您提一个修改意见,可以先不用带参数,您的宏展开函数是完整的,但是不能正确展开下面这些宏:

#define macro_1 a
#define macro_2 macro_1+b
int c=macro_2;

这里第二个宏使用了第一个宏,最好能完全展开。当然,是否会完全展开,要看您的宏定义函数怎么写的....。

[此贴子已经被作者于2023-4-25 20:27编辑过]

2023-04-25 20:12
快速回复:一道习题,来吧,英雄们
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018728 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved