转编译为另一种语言[关闭]

2023-12-08

代码转编译的典型方式有哪些?目前,我正在编写一种简单的编程语言,其处理方式是递归的。循环遍历一个节点列表,假设当前节点是一个变量节点,它会调用一个emit_variable_node函数,它会将一些代码逐字附加到字符串中,例如:

以下代码是伪代码,我正在用 C 编写我的项目,并编译为 C。

char *file_contents;

void emit_variable_node(VariableNode *var) {
    // I know += doesn't work on strings, just pretend it does.
    file_contents += var.getType();
    file_contents += " "; // a space
    file_contents += var.getName();
    // etc
}

我还假设我们给出的代码已经过语义分析,并且是正确的。然后 file_contents 字符串被存储到一个临时文件中,该文件在由 C 编译器编译后被删除。

这是一种不好的做法,还是有更好、更干净的方法来做到这一点?


您可以通过任何您喜欢的方式编写解析器,并在解析时生成代码,不需要 AST 节点(“语法定向翻译”)。这通常会产生非常糟糕的代码,因为代码生成器没有机会考虑上下文来生成更好的代码。

您可以构建一个解析器,它首先构建抽象语法树 (AST),然后作为第二遍遍历树生成代码,而不查看任何相邻节点。这只是之前的答案,其中包含 AST。 这是一个未优化的转译器输出的极其糟糕的示例做了这样的事情。

更好的方法是从 AST 生成代码,其中每个 AST 节点本地代码生成器检查其邻居,以决定要做什么。这将为您提供更好的代码。

更好的解决方案是效仿传统编译器,为您的语言构建一个良好的前端,包括符号表以及控制和数据流分析。然后您可以使用它来生成更好的代码。

关于实际代码生成:是的,您可以打印文本字符串。字符串模板更方便一些,但它们只是打印文本字符串的一种奇特方式,因此它们不会增加任何功能或提高生成的代码质量。

更好的解决方案是将源语言的 AST 转换为目标语言的 AST,包括所有本地检查以及使用符号表和流分析中的信息。这样做的好处是,通过用目标语言生成 AST,您现在可以在目标语言中应用源语言中无法实现的优化。 [真正的编译器会做这样的事情,但他们使用的术语是“将 AST 转换为 IR(内部表示)”,并且他们对 IR 进行优化。] 在目标 AST 上的所有优化完成后,您必须漂亮地打印最终的 AST...使用字符串模板之类的东西。

大多数人没有精力从头开始构建一个好的转译器。所以他们做了一些像第一个建议这样的黑客行为(只是说说而已)。但是,如果您想要将代码从一种语言转换为另一种语言的真正良好基础,请查看我们的DMS 软件再造工具包。 DMS拥有多种语言的解析器,可以实现自定义语言的解析器,自动构建AST,提供大量支持解析后的生活,例如,构建符号表和流分析、进行 AST 到 AST 转换,并拥有漂亮的打印机。DMS 被设计为支持此类任务的平台。这意味着您可以专注于构建任务的高质量翻译部分,而不是尝试构建所有有用的基础设施。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

转编译为另一种语言[关闭] 的相关文章

  • boost::asio + std::future - 关闭套接字后访问冲突

    我正在编写一个简单的 TCP 客户端来发送和接收单行文本 异步操作由 std future 处理 以便于超时阻塞查询 不幸的是 我的测试应用程序在破坏服务器对象时因访问冲突而崩溃 这是我的代码 TCP客户端 hpp ifndef TCPCL
  • 为什么相同的代码在同一台计算机上的执行时间可能不同?

    我是 C 编程新手 我编写了代码并希望获得它的运行时 这就是我所做的 每次运行代码时 我都会得到不同的运行时值 这样对吗 或者我的代码有问题吗 int main int argc char argv time t start end sta
  • 如何在 Visual Studio 2010 中增强 XAML 设计器?

    当我使用 XAML 设计器时 进入设计器和退出设计器是如此困难和缓慢 当我这样做时 Visual Studio 卡了一段时间 有什么方法可以增强 XAML 设计器和编辑器吗 Ant 保存 XAML 文件时非常慢 这通常意味着您可能有复杂的
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • VB.NET 相当于 C# 属性简写吗?

    是否有与 C 等效的 VB NET public string FirstName get set 我知道你能做到 Public Property name As String Get Return name ToString End Ge
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 使用 C 语言使用 strftime() 获取缩写时区

    我看过this https stackoverflow com questions 34408909 how to get abbreviated timezone and this https stackoverflow com ques
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • PlaySound 可在 Visual Studio 中运行,但不能在独立 exe 中运行

    我正在尝试使用 Visual Studio 在 C 中播放 wav 文件 我将文件 my wav 放入项目目录中并使用代码 PlaySound TEXT my wav NULL SND FILENAME SND SYNC 我按下播放按钮 或
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 上下文敏感与歧义

    我对上下文敏感性和歧义如何相互影响感到困惑 我认为正确的是 歧义 歧义语法会导致使用左推导或右推导构建多个解析树 所有可能的语法都是二义性的语言是二义性语言 例如 C 是一种不明确的语言 因为 x y 总是可以表示两个不同的事物 如下所述
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • 如何从main方法调用业务对象类?

    我已将代码分为业务对象 访问层 如下所示 void Main Business object public class ExpenseBO public void MakeExpense ExpensePayload payload var
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当

随机推荐

  • 将 mongodb 对象转换为 javascript 对象

    启动时我将配置文件传递给另一个 node js 模块 配置文件包含以下 json resolution activated true types of 23 当我在调用的 node js 模块中打印接收到的类型数组时 它看起来像 conso
  • 父子模块中的 Maven pom 继承和重写

    我很好奇如何决定子 pom 中的元素是否会覆盖父 pom 详细信息 或者只是与子 pom 中的父 pom 继承元素一起添加 我们举个例子来理解一下 例如 每个依赖项都由 Maven 坐标唯一标识 在子pom中 如果依赖项的maven坐标与父
  • 有没有办法让 Three.js 相机看起来偏离中心渲染?

    有没有办法设置 Three js 渲染器 使相机的观察点不在渲染图像的中心 澄清一下 在 0 0 0 处对一个只有一个 1x1x1m 立方体的场景进行成像 相机位于 0 0 10 观察点位于原点 与立方体的中心重合 如果我按原样渲染这个场景
  • 如何使用 php 从 HTML 表单收集数据?

    假设有一个 HTML 文件 其中有一个表单 其中包含一些数据 这些数据是使用 textarea 和 checkbox 从用户那里获取的输入 如何将此数据发送到 PHP 文件 您可以通过提交表单来发布此数据 然后在您可以使用的 php 文件上
  • 基于iOS 4并部署iOS 3的媒体播放器问题

    当在设备 3 1 2 上运行时 为什么它还传递 if NSClassFromString MPMoviePlayerViewController nil 做iOS4的代码就会崩溃 如何解决这个问题 if NSClassFromString
  • 使用 C# 将 FileStream 编码为 base64

    我知道如何对一个简单的字符串进行编码 解码base64 但是如果数据已经被写入文件流目的 假设我只能访问 FileStream 对象 而不能访问其中先前存储的原始数据 我将如何编码文件流转base64在将 FileStream 刷新到文件之
  • 具有重复数字的序列[重复]

    这个问题在这里已经有答案了 Data 我有一个data frame看起来像这样 df lt data frame id c 1 10 color c rep red 5 rep blue 5 df gt id color gt 1 1 re
  • 使用 django 查询返回活动时区中的日期时间

    我试图从表中检索最后 n 小时的行并在给定时区中打印它们的日期时间 给出打印日期时使用的时区 我试图使用 activate 使 django 返回具有正确时区的日期时间 但它返回 UTC 格式的日期 这是我当前的代码 min time da
  • Android 中如何实现通知功能?

    我正在 Android 上做一个帮助台应用程序 我想实现未读票证的通知 客户建议或投诉 在此应用程序的 iPhone 版本中 即使该应用程序未在应用程序图标本身上打开未读票据计数器 在 Android 中是否有可能 如果是这样 请帮助我像
  • QDate - 错误的年份

    我有以下情况 QDate fixDate QDate fromString QString 270912 ddMMyy 返回的年份是1912 我不明白为什么以及如何获得正确的年份 提前致谢 两位数年份始终解释为19xx 所以你可以通过YYY
  • Android并发数据库操作——“数据库被锁定”

    我正在编写一个具有 在线模式 的应用程序 即根据需要下载 解析数据并将其插入到 SQLite 数据库中 所有这些都是由服务执行的 该应用程序由多个请求服务更新数据的活动组成 不同的数据取决于活动 当用户浏览活动时 无需等待服务完成 很容易获
  • 比 MySQL 中的 UUID 更短的非重复字母数字代码

    当我插入一条记录时 MySQL数据库是否可以生成仅由数字和字母组成的5或6位数字代码 如果是这样怎么办 就像 goo gl bit ly 和 jsfiddle 一样 例如 http bit ly 3PKQcJ http jsfiddle n
  • Cakephp 和对多个结果集进行分页

    当在一个操作中调用一次 this gt paginate 时 我的分页工作正常 但它似乎不能很好地支持多次调用 这就是我想做的 function admin index published this gt pagination Post a
  • 核心动画围绕点旋转

    我想让 IBOutlet 围绕父视图中的特定点旋转 目前我只知道如何围绕锚点旋转它 但是 我想使用对象图层之外的点 旋转角度是相对于设备从该点出发的方向计算的 void viewDidLoad super viewDidLoad locat
  • 合并两个单独的 MySQL 查询的结果

    我正在尝试执行两个单独的数据库查询并将结果返回到表单 每个结果都写入一个表中 我希望能够将两个查询合并为一个查询 并按任务编号对结果进行排序 第一个查询 Booking Date date d m Y driver SESSION user
  • “从未使用过不可变值‘context’的初始化,请考虑替换对‘_’的赋值或将其删除

    我很快将变量声明为 let context LAContext LAContext 它会发出警告 从未使用过不可变值 context 的初始化 请考虑替换对 的赋值或将其删除 一切都在错误消息中 值 从未使用过 您的变量没有在任何地方使用
  • 将 Quartz 连接到 MS Sql Server

    我对 Quartz Job Scheduler 相当陌生 我可能会问一些愚蠢的问题 但是 我在将 Quartz Server 2010 连接到 MS SQL Server 2012 时遇到问题 我创建了几个工作正常的作业 但无法创建与 SQ
  • 字符串中当前位置左侧的字符位置

    从字符串中的某个任意位置 我需要找到距离我的位置左侧最近的字符位置 如果我想向右执行此操作 我可以使用 IndexOf 但我不确定如何向左做 我想出的两种方法只是从我的位置开始的递减循环 或者将字符串反向并使用正常的 IndexOf 其他人
  • 列表视图适配器中的按钮

    任何人都可以解决我的问题 经过 2 天的努力 我终于得到了 70 的输出 Exp 我有列表视图 其数据来自服务器 列表视图内部有一些文本 按钮和滚动索引 A BC D E F G 问题 按钮不起作用意味着当我单击它时 如果添加以下代码 它看
  • 转编译为另一种语言[关闭]

    Closed 这个问题需要多问focused 目前不接受答案 代码转编译的典型方式有哪些 目前 我正在编写一种简单的编程语言 其处理方式是递归的 循环遍历一个节点列表 假设当前节点是一个变量节点 它会调用一个emit variable no