Многострочные комментарии в схеме (RnRS) - PullRequest
4 голосов
/ 17 сентября 2010

Я создал это решение:

; use like this:
; (/* content ... */ <default-return>)
; or
; (/* content ... */) => #f
(define-syntax /*
  (syntax-rules (*/)
    ((/* body ... */) #f)
    ((/* body ... */ r) r)))

Но действительно ли это лучший или самый простой способ?

Ответы [ 2 ]

5 голосов
/ 17 сентября 2010

Вы не можете сделать это таким образом - это не будет работать для ряда контекстов.Вот несколько примеров, которые не будут работать:

(+ (/* foo */) 1 2)

(define (foo a (/* b */) c) ...)

(/* foo; bar */)

(/*x*/)

(let ((x (/* 1 */) 2))
  ...)

(let ((/* (x 1) */)
      (x 2))
  ...)

(car '((/* foo */) 1 2 3))

В отчетах Scheme нет стандартных многострочных комментариев вплоть до R5RS, но R6RS добавил синтаксис, который так или иначе широко использовался: #|...|#.

Но если вы действительно хотите ...

Вот то, о чем я говорил в комментарии: если вы хотите обернуть весь код вмакрос, то макрос может обрабатывать все тело, что может быть эффективным во многих других контекстах.Практически все они, за исключением попыток закомментировать синтаксически некорректные материалы, такие как пример с точкой с запятой выше, или неопределенную строку.Вы сами можете судить, действительно ли это стоит усилий ...

(Лично мне нравятся такие игры, я все равно считаю, что они бессмысленны. Но если вам действительно нравятся эти игры и вы считаете, что они полезны, а затем посмотрите раздел домашней работы ниже ...)

(define-syntax prog (syntax-rules () [(_ x ...) (prog~ (begin x ...))]))
(define-syntax prog~
  (syntax-rules (/* */)
    [(prog~ (/* x ...) b ...)
     ;; comment start => mark it (possibly nested on top of a previous mark)
     (prog~ (x ...) /* b ...)]
    [(prog~ (*/ x ...) /* b ...)
     ;; finished eliminating a comment => continue
     (prog~ (x ...) b ...)]
    [(prog~ (*/ x ...) b ...)
     ;; a comment terminator without a marker => error
     (unexpected-comment-closing)]
    [(prog~ (x0 x ...) /* b ...)
     ;; some expression inside a comment => throw it out
     (prog~ (x ...) /* b ...)]
    [(prog~ ((y . ys) x ...) b ...)
     ;; nested expression start => save the context
     (prog~ (y . ys) prog~ ((x ...) (b ...)))]
    [(prog~ (x0 x ...) b ...)
     ;; atomic element => add it to the body
     (prog~ (x ...) b ... x0)]
    [(prog~ () prog~ ((x ...) (b ...)) nested ...)
     ;; nested expression done => restore context
     (prog~ (x ...) b ... (nested ...))]
    [(prog~ () /* b ...)
     ;; input done with an active marker => error
     (unterminated-comment-error)]
    [(prog~ () b ...)
     ;; all done, no markers, not nested => time for the burp.
     (b ...)]))

И пример:

(prog

 (define x 1)

 (display (+ x 2)) (newline)

 /*
 (display (+ x 10))
 /* nested comment! */
 (/ 5 0)
 */

 (define (show label /* a label to show in the output, before x */
               x /* display this (and a newline), then returns it */)
   (display label)
   (display x)
   (newline)
   x
   /* this comment doesn't prevent the function from returning x */)

 (let ([x 1] /* some comment here */ [y 2])
   (show "result = " /* now display the result of show... */
         (show "list = " (list x /* blah blah */ y)))
   'done /* just a value to return from the `let' expression */)

 (show "and ... " '(even works /* boo! */ inside a quote))

 )

Домашняя работа

Длядополнительный кредит, расширить его, чтобы вы могли закомментировать несбалансированные парены.Например, сделайте эту работу:

(prog
 blah blah /* junk ( junk */ blah blah /* junk ) junk */ blah blah.
 )

Очевидно, что входные данные в целом должны иметь сбалансированные парены - это означает, что нет особого смысла в реализации такого рода расширения.Даже без этого, какой смысл комментировать неуравновешенного парня?

Но если кто-то здесь проделал весь этот путь, тогда вы должны получать удовольствие от такого рода мучений ... верно?

2 голосов
/ 19 мая 2017

MIT, Gnu, R6RS и R7RS поддерживают многострочные комментарии, например:

#|
    This is a comment
 |#
...