Вы не можете сделать это таким образом - это не сработает для ряда контекстов. Вот несколько примеров, которые не работают:
(+ (/* 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.
)
Очевидно, что вход в целом должен иметь сбалансированные скобки - это означает, что нет особого смысла в реализации такого рода расширения. Даже без этого, какой смысл комментировать несбалансированный парен?
Но если кто-то добрался сюда, то вы должны получать удовольствие от такого рода самоистязаний ... не так ли?
person
Eli Barzilay
schedule
17.09.2010