我正在尝试编写一个球拍阅读器扩展程序,禁用对管道角色的特殊处理|.
我有两个文件:mylang/lang/reader.rkt实现lang阅读器并mylang/testing.rkt试用它.我跑去raco pkg install --link安装郎.
这是reader.rkt:
#lang s-exp syntax/module-reader
racket
#:read my-read
#:read-syntax my-read-syntax
(define (parse-pipe char in srcloc src linum colnum)
#'\|)
(define my-readtable
(make-readtable #f #\| 'terminating-macro parse-pipe))
(define (my-read-syntax src in)
(parameterize ((current-readtable my-readtable))
(read-syntax src in)))
(define (my-read in)
(syntax->datum
(my-read-syntax #f in)))
Run Code Online (Sandbox Code Playgroud)
有了testing.rkt这样的:
#lang mylang
(define | 3)
(+ 3 2)
Run Code Online (Sandbox Code Playgroud)
按预期运行并生成5个.但是下一个不会:
#lang mylang
(define |+ 3)
(+ |+ 2)
Run Code Online (Sandbox Code Playgroud)
抱怨define: bad syntax (multiple expressions after identifier) in: (define \| + 3)哪个是合理的,因为parse-pipe产生语法对象,而不是字符串,所以它过早地终止了符号的读取.
我可以做的一件事是继续阅读直到符号的结尾,但这是最好的hackish因为我将重新实现符号解析并且它不会修复符号在中间具有管道char的情况,或者如果| 在字符串内等
我想要做的是删除|的默认阅读器程序 从可读表,但我不知道如何/如果可以做到.
好的,我找到了办法.文档make-readtable说:
char like-char readtable - 使char被解析的方式与在readtable中解析like-char的方式相同,其中readtable可以是#f以指示默认的可读表.
所以我可以让读者|像普通人一样阅读a:
(define my-readtable
(make-readtable #f #\| #\a #f))
Run Code Online (Sandbox Code Playgroud)
它有效
(define hawdy|+ "hello")
(string-append hawdy|+ "|world")
; => "hello|world"
Run Code Online (Sandbox Code Playgroud)