从角色的可读表中删除球拍的默认阅读器程序

spe*_*ufo 4 racket

我正在尝试编写一个球拍阅读器扩展程序,禁用对管道角色的特殊处理|.

我有两个文件: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的情况,或者如果| 在字符串内等

我想要做的是删除|的默认阅读器程序 从可读表,但我不知道如何/如果可以做到.

spe*_*ufo 6

好的,我找到了办法.文档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)