我想解决有关宏的问题:
定义此构造:
(subl e_1 e_2 ... -> e_i ... e_j <- e_j+1 ... e_n)
; 其评估返回子列表(e_i ... e_j)
。 例如。(subl 1 -> 2 3 4 <- 5 6)
应为(2 3 4)
。
我试图解决它(以下是部分解决方案)但它没有用......
(define-syntax subl
(syntax-rules(> <)
((_ x y ... > x ... y < c v )
(begin
'(x y)))))
错误是:
语法规则:模式中错位的省略号(遵循其他省略号) 在:......
答案 0 :(得分:4)
你不能在一对括号中使用多个省略号,如果你使用的是关键词->
和<-
,那么这并不重要,语言不够聪明,不知道在哪里停止扩张。
示例:
(_ x ...)
是合法的,x ...
会抓住所有内容,直到结束时
(_ x y ... z)
是合法的,x
与开头的单个元素匹配,y ...
捕获所有内容,但最后一个元素z
与最后的单个元素匹配。
(_ (x ...) y ...)
是合法的,x ...
捕获内括号内的所有内容,并y ...
在外括号内进行任务。
(_ x ... y ...)
不合法,因为您无法说明扩展这两个群组的距离。
所以你必须分多步解决问题:删除->
之前的元素,删除<-
之后的元素,最后捕获中间的列表。
(define-syntax subl
(syntax-rules (-> <-)
((_ -> x ... <-)
'(x ...))
((_ -> x ... y)
(subl -> x ...))
((_ x y ...)
(subl y ...))))
答案 1 :(得分:2)
您需要创建将您的源转换为更简单的处理模式:
(define-syntax subl
(syntax-rules (-> <-)
((_ "build-list" end middle before)
(subl "execute" before middle end))
((_ "build-list" before () () -> . rest)
(subl "build-list" () () before . rest ))
((_ "build-list" middle () before <- . rest)
(subl "build-list" () middle before . rest ))
((_ "build-list" (xs ...) the others x . rest)
(subl "build-list" (xs ... x) the others . rest))
((_ "execute" before middle end)
; I guess this is wrong
'middle)
((_ . rest)
(subl "build-list" () () () . rest))))
(subl a b c -> d e f <- f g) ; == '(d e f) => (d e f)
更改您希望代码更简单的格式是什么? (subl a b c -> d e f <- f g) => (subl "execute" (a b c) (d e f) (f g))
然后您在“执行”模式中拥有所需的逻辑。
答案 2 :(得分:1)
您可以使用Racket syntax-parse
实现您的宏(因为您包含了racket标记:)),它具有比#lang racket
(require (for-syntax syntax/parse))
(define-syntax (subl stx)
(syntax-parse stx #:datum-literals (-> <-)
[(_ a b ... -> c ... d <- e ... f)
#:when (printf "a: ~a\n" (syntax->datum #'a))
#:when (printf "bs: ~a\n" (syntax->datum #'(b ...)))
#:when (printf "cs: ~a\n" (syntax->datum #'(c ...)))
#:when (printf "d: ~a\n" (syntax->datum #'d))
#:when (printf "es: ~a\n" (syntax->datum #'(e ...)))
#:when (printf "f: ~a\n" (syntax->datum #'f))
#''(c ... d)]))
(subl 1 -> 2 3 4 <- 5 6)
更具表现力的模式语言。
a: 1
bs: ()
cs: (2 3)
d: 4
es: (5)
f: 6
'(2 3 4)
产生
{{1}}