首页 文章

在球拍中实现语言翻译

提问于
浏览
1

我正在使用Racket实现一个将codegen转换为另一种语言的解释器 . 作为一个新手,我试图尽可能地避免使用宏;)因此我提出了以下“解释器”:

(define op (open-output-bytes))
(define (interpret arg)
  (define r
     (syntax-case arg (if)    
       [(if a b) #'(fprintf op "if (~a) {~a}" a b)]))
       ; other cases here
  (eval r))

这对我来说有点笨拙 . 这样做有“最佳实践”吗?我在这里做了一件完全疯狂的事吗?

2 回答

  • 2

    简短的回答:是的,这是一个合理的事情 . 但是,你这样做的方式很大程度上取决于你的具体情况 .

    你完全正确地认为将程序生成为字符串是一种容易出错且易碎的方法 . 但是,避免这种情况需要能够在更高级别表达目标语言,以避开该语言的解析器 .

    同样,它确实与您所针对的语言有很大关系,以及您想要做的工作有多好 . 在我知道我没有时间做正确的事情的情况下,我自己一起攻击用于生成Python的东西 .

    编辑:哦,你也在做Python吗? Bleah! :)

    你有很多不同的选择 . 您最干净的选择是生成Python AST节点的表示,因此您可以直接注入它们或使用现有的序列化 . 你会问我是否有这样的图书馆,而且......我很兴奋 . 我相信当前的Python架构包括......好吧,是的,我去看了看,你的状态很好 . Python的“Parser”模块生成AST,看起来AST模块可以直接构造 .

    https://docs.python.org/3/library/ast.html#module-ast

    我猜你最干净的路径是生成代表这些AST模块的JSON,然后编写一个Python存根,将它们转换为Python AST .

    所有这一切都假设你想走高速路;有一系列广泛的中间方法涉及python语法的简单推广(例如:哦,看起来这种语句有一个冒号后跟一个缩进的代码块,等等) .

  • 2

    如果源语言与Racket共享语法,则使用 read-syntax 生成表示输入程序的语法对象 . 然后使用递归下降使用 syntax-casesyntax-parse 来辨别各种构造 .

    我建议不要直接打印到输出端口,而是 Build 一个元素树(字符串,数字,符号等) . 最后一步是打印树的所有元素 . 使用树表示输出非常灵活,允许您不按顺序处理子表达式 . 它还允许您有效地连接来自不同来源的输出 .

    不需要宏 .

相关问题