Racket 以换行符作为语句结尾的读卡器

Racket 以换行符作为语句结尾的读卡器,racket,Racket,我试图在Racket中创建一种新的语言,其中语句位于单独的行上。换行符定义语句的结尾和新语句的开头 我通读了指南中非常有用的一章,但示例集中在扩展类似s-exp的语言上。我看到的唯一选项是为read和readsyntax手动编写自己的解析器 我想用,但我不知道我能不能用。我试过: (make-readtable #f #f 'non-terminating-macro my-read-line-fn) 但我不知道这是否有多大帮助。我想我可以创建一个子readtable,它可以执行类似于读取单词

我试图在Racket中创建一种新的语言,其中语句位于单独的行上。换行符定义语句的结尾和新语句的开头

我通读了指南中非常有用的一章,但示例集中在扩展类似s-exp的语言上。我看到的唯一选项是为
read
readsyntax
手动编写自己的解析器

我想用,但我不知道我能不能用。我试过:

(make-readtable #f #f 'non-terminating-macro my-read-line-fn)
但我不知道这是否有多大帮助。我想我可以创建一个子readtable,它可以执行类似于
读取单词
读取字符串
的操作,我可以根据读取行fn获取的字符将其分派到该子readtable

这是最好的策略还是有一种预定义的阅读方式一直读到行尾?

Racket没有“语句”,因此以“语句”结尾的换行符的概念是荒谬的


如果您的动机是减少或消除括号,我建议您使用“标准替代”的reader-like,而不是自制的东西。

我认为您不需要对readtable做任何事情。您的lang/reader.rkt可以提供您自己的
read语法
,它可以按照自己的意愿进行读取/解析,并可能在遇到EOL时停止

一个有趣的例子是。它的“语句”概念是单个字符,但IIUC也有
[
方括号
]


查看它的lang/reader.rkt和parser.rkt以了解低级位,然后尝试了解它最终如何作为Racket表达式进行计算。

您确实需要编写解析您的语言的read和read语法版本。readtable只是用来修改内置的read,所以我建议您看看Parser Tools(),它是以lex/yacc样式编写解析器的工具

另一种方法是使用ragg:


使用DrRacket中的软件包管理器安装Ragg。在可用软件包列表中搜索ragg。

制作您自己的reader.rkt:

#lang s-exp语法/模块读取器
(测试)
#:读取语法我的读取语法
#当前位置阅读我的阅读
;; 覆盖默认读取(不使用,但为必需)
(定义(我的读入)(读入行))
;; 通过每次读取一个字符串来重写读取语法,然后
;; 将其传递到语句字符串->代码以获取作为dara和
;; 使用datum->syntax设置语法
(在中定义(我的读取语法)
(数据->语法#f(语句字符串->代码(读入行)))
;; 这实际上就是您想要代码的方式
;; 成为s-表达式。我想我的
;; 模块有一个称为代码的原语
;; 按原样解释字符串
(定义(语句字符串->代码字符串)
(列表代码str))

如果动机是这样,我同意你的看法。另见Honu和Pyret。然而,OP的动机可能是制作面向线路的DSL。是的,这就是我正在做的。这种语言更接近Bash而不是Racket,所以我需要有副作用的语句和类似的语法(即,没有括号)。@Christian如果是这样的话,你应该用更多的细节更新你的问题;您没有说过定制DSL是您的目标,也没有想到语法的示例,甚至没有语句是什么。我没有足够的信息来评估使用默认阅读器是否适合您的情况,尽管根据您对Greg的评论,您似乎对这种方法很感兴趣。现在你的问题似乎是XY问题。谢谢你的建议;我的简单读/读语法实现似乎可以工作。如果我想让Racket的默认读卡器读取一些语法,最好的方法是用Racket的默认读卡器参数化当前读卡器,然后调用读/读语法吗?如果您正在实现
read
readsyntax
,我不明白为什么您还需要自定义读卡器。但是,如果我错了,您确实需要这样做,那么将其作为一个单独的堆栈溢出问题可能会更好?