Chez Scheme 的自定义模式匹配工具
Custom pattern-matching facility for Chez Scheme
我正在尝试在 Scheme 中制作自己的模式匹配系统。首先,我正在为 s-expressions 创建一个解析器,将它们分成这样的标记:
'(1 2 b (3 4))
=> '(number number symbol (number number))
应该注意的是,我之前没有在 Scheme 中使用过 define-syntax
,所以这可能是我搞砸的地方。 Chez Scheme 抛出这个错误:
Exception: invalid syntax classify at line 21, char 4 of pmatch.scm
。请注意,行号不会与此处的代码片段完全对应。有谁知道我做错了什么?
(define-syntax classify
(syntax-rules ()
((_ checker replacement)
((checker (car sexpr)) (cons replacement (classify-sexpr (cdr sexpr)))))))
(define (classify-sexpr sexpr)
(cond
((null? sexpr) sexpr)
(classify list? (classify-sexpr (car sexpr)))
(classify number? 'number)
(classify symbol? 'symbol)
(else
(cons 'symbol (classify-sexpr (cdr sexpr))))))
(display (classify-sexpr '(1 (b 3) (4 5) 6)))
您的代码非常混乱。事实上,它太混乱了,我完全不确定你到底想做什么:我的回答是基于你所说的分类器在你的问题开始时应该产生的结果。
- 首先,你的宏引用了
sexpr
,它在宏中没有任何意义,因为Scheme宏是卫生的,它肯定不会引用sexpr
,它是[=的参数16=].
- 其次,您在这里根本不需要宏。我怀疑您可能在想,因为您正在尝试 编写 一个宏,所以您必须在其构造中使用宏:这不一定是正确的,而且通常是个坏主意。
- 第三,你的
cond
的语法是拙劣的无法修复:我无法理解它试图做什么。
- 最后
list
分类将不再需要:如果您想将 (1 2 3 (x))
分类为 (number number number (symbol))
那么您将永远不会遇到您拥有列表的情况想要分类,因为你必须走进它才能对其元素进行分类。
而不是只写明显的函数做你想做的事:
(define classification-rules
;; an alist of predicate / replacement which drives classigy
`((,number? number)
(,symbol? symbol)))
(define (classify thing)
;; classify thing using classification-rules
(let loop ([tail classification-rules])
(cond [(null? tail)
'something]
[((first (first tail)) thing)
(second (first tail))]
[else
(loop (rest tail))])))
(define (classify-sexpr sexpr)
;; classify a sexpr using classify.
(cond
[(null? sexpr) '()]
[(cons? sexpr) (cons (classify-sexpr (car sexpr))
(classify-sexpr (cdr sexpr)))]
[else (classify sexpr)]))
现在
> (classify-sexpr '(1 2 3 (x 2) y))
'(number number number (symbol number) symbol)
可能您真正想要的是将(1 2 (x 2))
分类为(list number number (list symbol number))
的东西。你可以很容易地做到这一点:
(define atomic-classification-rules
;; an alist of predicate / replacements for non-conses
`((,number? number)
(,symbol? symbol)))
(define (classify-sexpr sexpr)
(cond
[(null? sexpr) '()]
[(list? sexpr)
`(list ,@(map classify-sexpr sexpr))]
[(cons? sexpr)
`(cons ,(classify-sexpr (car sexpr))
,(classify-sexpr (cdr sexpr)))]
[else
(let caloop ([rtail atomic-classification-rules])
(cond [(null? rtail)
'unknown]
[((first (first rtail)) sexpr)
(second (first rtail))]
[else
(caloop (rest rtail))]))]))
现在
> (classify-sexpr '(1 2 3 (x 2) y))
'(list number number number (list symbol number) symbol)
> (classify-sexpr '(1 2 3 (x 2) . y))
'(cons number (cons number (cons number (cons (list symbol number) symbol))))
我正在尝试在 Scheme 中制作自己的模式匹配系统。首先,我正在为 s-expressions 创建一个解析器,将它们分成这样的标记:
'(1 2 b (3 4))
=> '(number number symbol (number number))
应该注意的是,我之前没有在 Scheme 中使用过 define-syntax
,所以这可能是我搞砸的地方。 Chez Scheme 抛出这个错误:
Exception: invalid syntax classify at line 21, char 4 of pmatch.scm
。请注意,行号不会与此处的代码片段完全对应。有谁知道我做错了什么?
(define-syntax classify
(syntax-rules ()
((_ checker replacement)
((checker (car sexpr)) (cons replacement (classify-sexpr (cdr sexpr)))))))
(define (classify-sexpr sexpr)
(cond
((null? sexpr) sexpr)
(classify list? (classify-sexpr (car sexpr)))
(classify number? 'number)
(classify symbol? 'symbol)
(else
(cons 'symbol (classify-sexpr (cdr sexpr))))))
(display (classify-sexpr '(1 (b 3) (4 5) 6)))
您的代码非常混乱。事实上,它太混乱了,我完全不确定你到底想做什么:我的回答是基于你所说的分类器在你的问题开始时应该产生的结果。
- 首先,你的宏引用了
sexpr
,它在宏中没有任何意义,因为Scheme宏是卫生的,它肯定不会引用sexpr
,它是[=的参数16=]. - 其次,您在这里根本不需要宏。我怀疑您可能在想,因为您正在尝试 编写 一个宏,所以您必须在其构造中使用宏:这不一定是正确的,而且通常是个坏主意。
- 第三,你的
cond
的语法是拙劣的无法修复:我无法理解它试图做什么。 - 最后
list
分类将不再需要:如果您想将(1 2 3 (x))
分类为(number number number (symbol))
那么您将永远不会遇到您拥有列表的情况想要分类,因为你必须走进它才能对其元素进行分类。
而不是只写明显的函数做你想做的事:
(define classification-rules
;; an alist of predicate / replacement which drives classigy
`((,number? number)
(,symbol? symbol)))
(define (classify thing)
;; classify thing using classification-rules
(let loop ([tail classification-rules])
(cond [(null? tail)
'something]
[((first (first tail)) thing)
(second (first tail))]
[else
(loop (rest tail))])))
(define (classify-sexpr sexpr)
;; classify a sexpr using classify.
(cond
[(null? sexpr) '()]
[(cons? sexpr) (cons (classify-sexpr (car sexpr))
(classify-sexpr (cdr sexpr)))]
[else (classify sexpr)]))
现在
> (classify-sexpr '(1 2 3 (x 2) y))
'(number number number (symbol number) symbol)
可能您真正想要的是将(1 2 (x 2))
分类为(list number number (list symbol number))
的东西。你可以很容易地做到这一点:
(define atomic-classification-rules
;; an alist of predicate / replacements for non-conses
`((,number? number)
(,symbol? symbol)))
(define (classify-sexpr sexpr)
(cond
[(null? sexpr) '()]
[(list? sexpr)
`(list ,@(map classify-sexpr sexpr))]
[(cons? sexpr)
`(cons ,(classify-sexpr (car sexpr))
,(classify-sexpr (cdr sexpr)))]
[else
(let caloop ([rtail atomic-classification-rules])
(cond [(null? rtail)
'unknown]
[((first (first rtail)) sexpr)
(second (first rtail))]
[else
(caloop (rest rtail))]))]))
现在
> (classify-sexpr '(1 2 3 (x 2) y))
'(list number number number (list symbol number) symbol)
> (classify-sexpr '(1 2 3 (x 2) . y))
'(cons number (cons number (cons number (cons (list symbol number) symbol))))