方案中的多行注释(RnRS)

发布于 2024-09-24 03:20:03 字数 261 浏览 10 评论 0原文

我创建了这个解决方案:

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

但这真的是最好或最简单的方法吗?

I created this solution:

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

But is it really the best or easiest way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不甘平庸 2024-10-01 03:20:03

你不能这样做——它在很多情况下都不起作用。以下是一些不起作用的示例:

(+ (/* 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))

直到 R5RS,Scheme 报告中都没有标准的多行注释,但 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.
 )

显然,输入作为一个整体应该有平衡的括号——这意味着实现这种扩展没有多大意义。即使没有它,注释掉不平衡的括号有什么意义呢?

但如果有人一路走到这里,那么你一定很享受这种自虐……对吧?

You can't do it this way -- it won't work for a number of contexts. Here are some examples that won't work:

(+ (/* 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))

There is no standard multi-line comment in the Scheme reports up to R5RS, but R6RS has added a syntax that was widely used anyway: #|...|#.

But if you really want to...

Here's what I was talking about in the comment: if you're willing to wrap the whole code in a macro, then the macro can process the whole body, which can be effective in many more contexts. Pretty much all of them except for trying to comment out syntactically invalid stuffs like the semicolon example above, or an unterminated string. You can judge for yourself whether it's really worth the effort...

(Personally, as much as I enjoy such games, I still think they're pointless. But if you really enjoy these games and you think they're useful, then see the homework section below...)

(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 ...)]))

And an example:

(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))

 )

Homework

For extra credit, extend it so you can comment out unbalanced parens. For example, make this work:

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

Obviously, the input as a whole should have balanced parens -- this means that there's not much point in implementing this kind of an extension. Even without it, what's the point in commenting out an unbalanced paren?

But if anyone got all the way here, then you must enjoy this kind of self-torture ... right?

叹倦 2024-10-01 03:20:03

MIT、Gnu、R6RS 和 R7RS 支持多行注释,如下所示:

#|
    This is a comment
 |#

MIT, Gnu, R6RS and R7RS support multi-line comments like this:

#|
    This is a comment
 |#
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文