如何在球拍中创建新语言?

时间:2018-08-05 06:21:39

标签: racket

我想创建一种新的语言,其语法与键入的球拍相同,但是执行后会做两件事:

  1. 像输入球拍一样运行给定程序
  2. 如果检查类型,则将输入翻译成另一种语言(例如python)。我正计划编写一个从键入球拍形式到python语法的翻译器。

关于如何开始的任何建议或指向某些框架代码的指针?我已经读过this tutorial,但是它主要谈论的是创建我不需要的新语法。

我了解如何编写球拍代码以将一种语言翻译成另一种语言,但我没有得到的是我能同时完成上述两项工作,即首先以另一种语言运行它,然后再使用相同的输入。

1 个答案:

答案 0 :(得分:2)

听起来您想用一种新的#%module-begin格式来制作语言。读者可以插入此表格(当您在文件顶部进行#lang ....行时插入),或者如果您手动编写模块,则可以使用该语言插入。这两种方式通常与您的语言定义相关联。该宏可以完全访问整个模块的未扩展语法,例如,像这样的宏:

(provide (rename-out [-module-begin #%module-begin]))
(define-simple-macro (-module-begin body ...)
  (#%module-begin
    (writeln '(body ...))
    body ...))

将创建一种可以完成两件事的语言:

  1. 打印出代码主体(作为s表达式),并且

  2. 使用编写语言定义的#%module-begin运行正文。

您将看到如何使用此技术两次捕获程序主体,并用它做两件事。因此,让我们尝试运行此示例。首先,让我们从上方获取示例,并将其放在文件“ mylang.rkt”中:

#lang racket
(provide (rename-out [-module-begin #%module-begin])
         (except-out (all-from-out racket) #%module-begin))
(require syntax/parse/define)
(define-simple-macro (-module-begin body ...)
  (#%module-begin
    (writeln '(body ...))
    body ...))

现在我们可以像这样在mylang中编写程序了:

#lang s-exp "mylang.rkt"
(+ 1 2)

当您运行它时,您会得到类似以下的内容:

((+ 1 2))
3

首先打印出程序文本,然后运行它。

您可以在我写的a paperthe Video language中了解有关此过程的更多信息。您可能还会发现Beautiful Racket这本书,其中包含一些可能有用的示例。