3

更具体地说,我需要|将任何实例转换为\|. 我尝试阅读有关阅读器宏的文档,但我非常迷茫。有人可以用可以理解的术语解释这一点,或者理想地告诉我如何编写这样的宏。

4

2 回答 2

2

您实际上是在破坏|通常语法中的通常含义,因此您应该以某种统一的方式真正做到这一点,以尽量减少意外。您的解决方案没有这样做 - 它|根据是否是第一件事而区别对待,这很糟糕。例如,xxx|xxx将其读取为整个符号中的一个字符,这意味着您会得到一个名称为 的符号"xxx|xxx",但输入|xxx会得到两个符号,名称分别为"|""xxx"。因此,最好将您的语法|视为其他字符,以获得更一致且更易于解释的行为。

您的代码的另一个可能问题是您将其#f用作 readtable,这意味着阅读器不会与可能被修改的阅读器组合。

最后,您应该真正注意额外的参数,并在给出它们时返回一个语法对象。原因很明显,我猜你不这样做的原因是你对阅读这样的代码感兴趣。但是你真的应该用一只眼睛关注潜在的扩展,在 Racket 中,这种代码的明显未来将是组成一种适当的语言而不是 read+eval hack。确实,这看起来有点矫枉过正,但在这种情况下,有一个简单的解决方案是使用“与其他字符相同”快捷方式来避免编写冗长的代码。

以下解决了所有这些问题:

(define rt (let ([c (current-readtable)]) (make-readtable c #\| #\a c)))
于 2013-04-01T22:26:41.977 回答
1

弄清楚了!这是调整(read)函数以更改|into的所有实例的代码\|

(define rt2 (make-readtable #f #\| 'non-terminating-macro
                            (lambda (c in . _)
                              '\|)))

(parameterize ([current-readtable rt2]
               [current-namespace ns])
  (eval (read)))
于 2013-04-01T22:01:08.217 回答