我正在使用美丽的球拍来起草一个新的DSL,bleir,基于s-表达式.我首先使用主菜谱安装了一个新的球拍包。
raco pkg new bleir
cd bleir
raco pkg install然后我在疯狂的文件main.rkt中设置了一个残留的读取器和扩展器。
#lang br/quicklang
(module+ reader
(provide read-syntax)
(require br/quicklang))
(provide (rename-out [bleir-expander #%module-begin]))
(define-macro (bleir-expander PARSE-TREE)
#'(#%module-begin
(display PARSE-TREE)))然后,我编写了一个测试文件tyst-bleir.rkt故意拼写错误,以避免字符串名" test“可能出现的问题。
#lang bleir
42我有个问题:
模块语言:只允许模块表达式,无论是#lang还是(模块.)in: 42
我可以用两种方式解决它,“恶心”和“神秘”。首先,恶心的修复,在tyst-bleir.rkt
(module tyst-bleir bleir
42)这可以调用来自br/quicklang的双导出读取器和我的自定义扩展器,显示42。
问题1:#lang bleir语法应该与冗长的(module ...)语法相同,不是吗?为什么#lang bleir不从br/quicklang导入阅读器
现在,神秘的解决办法:
#lang s-exp bleir
42这显然使用了模块(包?) s-exp中的替代s-exp读取器,我想它是可以的。至少我没被堵住。但是,我不明白为什么不能以同样的方式使用br/quicklang的读取器。
#lang br/quicklang bleir
42bleir:未绑定标识符
问题2:为什么这不起作用?我能修好它吗?如果是这样的话,是怎么做的?
下面是另一个失败的尝试,尝试从s-exp导入main-rkt中的阅读器。
(module+ reader
(provide read-syntax)
(require s-exp))main.rkt:11:11:无法打开模块文件模块路径: s-exp路径:/usr/share/racket/collects/s/main.rkt系统错误:没有这样的文件或目录;rkt_err=3在: s-exp中没有可用的包建议。
问题3:为什么不起作用?我能修好它吗?如果是这样的话,是怎么做的?
发布于 2021-10-18 00:37:59
问题1
你没有完全遵循你提到的主食谱。如果你继续阅读,你会看到:
读语法必须返回一个值:模块表示代码,表示为语法对象。通常,将源文件中转换的S-表达式插入到这个语法对象中。这个语法对象必须没有标识符绑定。此模块代码必须包含对扩展程序的引用,该扩展程序将在模块代码验证时提供初始绑定集。伪码:
#lang br
(module reader br
(provide read-syntax)
(define (read-syntax name port)
(define s-exprs (read-code-from port))
(strip-bindings
#`(module dsl-mod-name dsl/expander
#,@s-exprs))))换句话说,您的read-syntax需要返回(strip-bindings #'(module ...))。
问题2
我认为你把“用户使用的语言”和“语言设计者使用的语言”混为一谈。
“用户使用的语言”类似于#lang bleir、#lang slideshow、#lang pollen等。这些语言提供构造来执行特定领域的任务。例如,#lang slideshow是一种用于创建演示文稿的语言。#lang pollen是一种用来创建书籍的语言。
“语言设计者使用的语言”是一种“用户使用的语言”,其中用户是语言设计者。这些语言提供构造,使语言的创建更容易。#lang br/quicklang属于这个类别。
因此,作为语言设计人员,您可以在内部使用#lang br/quicklang在您的bleir/main.rkt中构建语言bleir。但是,您的用户(不是语言设计人员)不需要编写(甚至注意到) #lang br/quicklang。
主菜谱讲述了两件事:阅读器和扩展器。在一种完全发展的语言中,您将同时提供阅读器和扩展器。s-exp可以被看作是一种方便的黑客语言,可以“运行”没有完全开发的语言,这些语言只有扩展程序,但还没有阅读器。
因此,#lang s-exp bleir工作的原因是您有一个功能良好的扩展程序,所以#lang s-exp bleir使用您的扩展程序,但是完全忽略了您的reader子模块。#lang bleir不能工作的原因是您的reader子模块存在缺陷(见问题1)。#lang br/quicklang bleir不能工作的原因是用户编写#lang br/quicklang没有任何意义。
我建议您简单地忘记s-exp并修复您的阅读器。AFAIK,Beau tiful Racket并没有真正谈论s-exp,如果您正在阅读这本书,使用s-exp只会让您感到困惑。
问题3
如果您想要一个技术性的答案,syntax.html (或者更一般的解析读取器%29)回答您的问题:
与球拍不同,s-exp不能作为模块路径使用.虽然#lang语言的语法与模块路径的语法重叠,但语言并不直接用作模块路径。相反,一种语言通过尝试两个位置获得模块路径:首先,它为语言的主模块寻找一个读取器子模块。如果这不是一个有效的模块路径,那么语言的后缀是/lang/reader。(如果两者都不是有效的模块路径,则会引发错误。)生成的模块使用类似于“读取器”的协议提供读取和读语法功能。
https://stackoverflow.com/questions/69600328
复制相似问题