Transpiler 如何实现源代码的对应关系
创始人
2024-06-01 10:41:55
0

最近在写一个 IEC 61131-3 中的结构化文本 (ST) 到 C 语言的 transpiler,遇到一个小小的麻烦,调试时,用户看到的是 ST 代码,而调试器看到的 C 语言的 debug symbols,怎么把两者对应起来呢。最开始我想的是自己来实现映射关系,理论上是可行的,但是有些额外的工作要做。

是否有更简单的办法呢?我想其它 transpiler 应该有同样的需求。为此研究了一下 Vala 的做法,Vala 语言也是把自己翻译成 C 语言,再用 gcc 来编译的。

先写一个小程序(t.vala)

void main () {print ("hello, world\n");
}
  • 编译:
valac -v -g t.vala

编译时加一个-v 参数,我们可以看到,valac 先把 t.vala 转换成 t.vala.c,再调用 cc 去编译生成 t 。

Loaded package `/usr/local/share/vala-0.56/vapi/glib-2.0.vapi'
Loaded package `/usr/local/share/vala-0.56/vapi/gobject-2.0.vapi'
cc -g -o '/Users/jim/work/lab/lang/vala-0.56.1/compiler/demo/t' '/Users/jim/work/lab/lang/vala-0.56.1/compiler/demo/t.vala.c' -I/usr/local/Cellar/libffi/3.3_3/include -I/usr/local/Cellar/glib/2.68.4/include -I/usr/local/Cellar/glib/2.68.4/include/glib-2.0 -I/usr/local/Cellar/glib/2.68.4/lib/glib-2.0/include -I/usr/local/opt/gettext/include -I/usr/local/Cellar/pcre/8.45/include -L/usr/local/Cellar/glib/2.68.4/lib -L/usr/local/opt/gettext/lib -lgobject-2.0 -lglib-2.0 -lintl
  • 调试:

lldb.png

我们可以看到,虽然可执行文件 t 是由 t.vala.c 生成的,但是调试器里看到源码仍然是原始的 t.vala。这个是怎么做到的呢?

那个得先看看 t.vala.c 长什么样的了。但是 t.vala.c 是个临时文件,编译完后就被删除了。开始想了一个土的办法,在 vala_ccode_compiler_compile 里的 585 行,把删除临时文件的代码注释掉,就拿到了 t.vala.c 。后来发现可以直接生成 C 代码:

valac -g -c t.vala

t.vala.c 的内容:

/* t.vala.c generated by valac 0.56.1, the Vala compiler* generated from t.vala, do not modify */#include static void _vala_main (void);static void
_vala_main (void)
{
#line 2 "t.vala"g_print ("hello, world\n");
#line 14 "t.vala.c"
}int
main (int argc,char ** argv)
{
#line 1 "t.vala"_vala_main (); 
#line 1 "t.vala"return 0;
#line 25 "t.vala.c"
}

原来是通过 #line 宏指令实现的,#line 指令并不陌生,在 bison/yacc/flex 生成的代码里经常见到。这里有 line 指令详细的解释。

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:哪种网络模式具有... 使用AWS ECS中的awsvpc网络模式来获得最佳性能。awsvpc网络模式允许ECS任务直接在V...