-1

我正在尝试在 Scheme 中创建自己的模式匹配系统。首先,我正在为 s 表达式制作一个解析器,将它们分成如下标记:

'(1 2 b (3 4))=>'(number number symbol (number number))

应该注意的是,我以前没有define-syntax在 Scheme 中使用过,所以这可能是我搞砸的地方。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)))
4

1 回答 1

0

您的代码非常混乱。事实上,它很困惑,我不确定你要完全做什么:我的回答是基于你所说的分类器在你的问题开始时应该产生的内容。

  • 首先,您的宏指的是sexpr在宏中没有任何意义的宏,并且因为Scheme 宏是卫生的,所以它绝对不会引用sexprwhich 的参数classify-sexpr
  • 其次,您在这里根本不需要宏。我怀疑你可能会想,因为你正在尝试编写一个宏,所以你必须在它的构造中使用宏:这不一定是正确的,而且通常是一个坏主意。
  • 第三,您的语法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))say的东西。你可以很容易地做到这一点:

(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))))
于 2020-10-19T15:20:55.060 回答