c编译器学习07:minilisp编译器改造(debug模式支持调试)

问题

原版的minilisp编译器不支持argv输入测试,不方便单步调试。
代码改造目标是既不改变原有程序的各种功能,
又能支持个人习惯的vs单步debug模式。

CMakeLists.txt变更

定义DEBUG宏
解决单步调试源码定位偏差问题

cmake_minimum_required(VERSION 3.10)
project(minilisp)add_compile_options(-std=gnu99 -g -Wall)# Create executable
add_executable(minilisp minilisp.c)if(CMAKE_BUILD_TYPE STREQUAL "Debug")target_compile_options(minilisp PRIVATE -O0)target_compile_options(minilisp PRIVATE -DDEBUG)
else()target_compile_options(minilisp PRIVATE -O2)
endif()

源码变更

加两个变量

static char* g_arg = NULL;
static int g_pos = 0;

加两个函数my_getchar my_ungetc

将代码中getchar()替换为my_getchar()
ungetc(c, stream)替换为my_ungetc(c, stream)

static int my_getchar() {if (NULL == g_arg) {return getchar();}else {if (0 != g_arg[g_pos]) {return g_arg[g_pos++];}else {return EOF;}}
}static void my_ungetc(int c, FILE* stream) {if (NULL == g_arg) {ungetc(c, stream);}else {if (g_pos > 0) {--g_pos;}}
}

修改main函数

原版main函数改为main_函数
并在main_中加入以下判断

int main_(int argc, char** argv) {...// The main loopif (argc > 1) {//argv[1]printf("run by arg : %s\n", argv[1]);g_arg = argv[1];g_pos = 0;}else {printf("run by user input, eg:(+ 2 3)\n");}//stdinfor (;;) {...}
}

新增一个main函数

int main(int argc, char** argv) {if (argc > 1) {return main_(argc, argv);//debug release都支持带参数执行}else {
#ifdef DEBUGchar* argv_test[2] = { "./minilisp" ,"(+ 1 2)" };//debug时,支持单步调试
#elsechar* argv_test[1] = { "./minilisp" };//release时,等于原版
#endif // DEBUGreturn main_(sizeof(argv_test) / sizeof(char*), argv_test);}
}

debug release测试效果

在这里插入图片描述

单步debug效果

图中515这一行的原始代码是int c = getchar();
原版的会卡在getchar()这一行,执行不下去
程序会等待控制台输入一个字符
在这里插入图片描述

以上或许是一种c程序的改造范式,可复用。
这让我想起了,将exe改为dll,将dll改为exe,也是类似变更入口函数即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/487172.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot邮箱注册

1.准备工作 操作之前准备两个邮箱 我准备了网易邮箱和QQ邮箱,网易邮箱用来发送验证码,QQ邮箱用来做注册(希望大家和我一样,不然可能会出错 ) 发送验证码的邮箱需要开启一些设置,否则不…

windows server2008前后端项目部署

目录 一.部署环境 准备一个windows server 2008的镜像 准备jdk1.8 准备tomcat服务器 准备mysql数据库 二.部署步骤 1.1新建虚拟机 1.2打开远程 连接宿主机远程桌面 1.3下载安装jdk 修改path 1.4安装tomcat 1.5.安装mysql mysql安装成功 把war包丢到tomcat webapp里面去…

Selenium IDE插件录制网页,解放双手

1、 国内下载地址 https://www.crx4chrome.com/crx/77585/ ,这个网络正常基本可以下载,目前最新版本是3.17.2。 点击Crx4Chrome下载。下载后的文件名称是:mooikfkahbdckldjjndioackbalphokd-3.17.2-Crx4Chrome.com.crx。 2、 安装 直接打开…

【MySQL】数据库概述

目录 一、为什么使用数据库? 二、数据库与数据库管理系统 2.1 相关概念 2.2 两者关系 三、 MySQL介绍 四、 RDBMS和非RDBMS 4.1 关系型数据库(RDBMS) 4.2 非关系型数据库(非RDBMS) 五、关系型数据库设计规则 …

挑战杯 基于卷积神经网络的乳腺癌分类 深度学习 医学图像

文章目录 1 前言2 前言3 数据集3.1 良性样本3.2 病变样本 4 开发环境5 代码实现5.1 实现流程5.2 部分代码实现5.2.1 导入库5.2.2 图像加载5.2.3 标记5.2.4 分组5.2.5 构建模型训练 6 分析指标6.1 精度,召回率和F1度量6.2 混淆矩阵 7 结果和结论8 最后 1 前言 &…

QT问题 打开Qt Creator发现没有菜单栏

之前不知道按了什么快捷键,当我再次打开Qt Creator时发现菜单栏消失啦 找了许多原因发现:安装有道词典的快捷键Ctrl Alt m 与Qt Creator里的快捷键冲突导致菜单栏被莫名其妙的隐藏 解决方法: 1找到有道词典快捷键 2再次按快捷键 Ctrl Alt m就可以重新显示菜单栏

机器学习---强化学习方法

1. 强化学习方法 1.1 动态规划法 动态规划方法是由Bellman 方程转化而来,通过修正Bellman 方程的规则,提高所期望值函数的近 似值。常用算法有两种:值迭代(Value Iteration)和策略迭代(Policy Iteration…

[云原生] 二进制k8s集群(下)部署高可用master节点

在上一篇文章中,就已经完成了二进制k8s集群部署的搭建,但是单机master并不适用于企业的实际运用(因为单机master中,仅仅只有一台master作为节点服务器的调度指挥,一旦宕机。就意味着整个集群的瘫痪,所以成熟…

较通用web脚手架模板搭建

较通用web脚手架模板搭建 从这里开始就接触到以后写项目的思维了。 做一个web开发,那就要层次分明,要有个实现的规划,这通常也是有一个较为通用的模板的。 总的来说:不同的层次有不同的模块,每个模块有必须实现的功…

【开源】JAVA+Vue.js实现校园电商物流云平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 商品数据模块2.3 快递公司模块2.4 物流订单模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 商品表3.2.2 快递公司表3.2.3 物流订单表 四、系统展示五、核心代码5.1 查询商品5.2 查询快递公司5.3 查…

一种基于javax.max注解的能力增强技术

目录 现有框架的不足之处 我的改进内容 改进的成果 现有框架的不足之处 Max是javax.validation包中的一个常用注解,用于对传入参数进行最大值校验。但是其校验区间为闭区间,且不支持修改,如:Max(2),表示表示传入参…

Codeforces Round 494 (Div. 3)

目录 A. Polycarps Pockets B. Binary String Constructing C. Intense Heat D. Coins and Queries E. Tree Constructing F. Abbreviation A. Polycarps Pockets 记录数量可以直接开一个桶即可然后求最大值 void solve(){cin>>n;vector<int> ton(105);int …