【问题标题】:General utility to remove/strip all comments from source code in various languages?从各种语言的源代码中删除/删除所有注释的通用实用程序?
【发布时间】:2011-03-21 22:05:03
【问题描述】:

我正在寻找一个命令行工具,它可以从输入中删除所有 cmets 文件并返回剥离的输出。支持流行就好了 编程语言,如 c、c++、python、php、javascript、html、css 等。它 必须具有语法意识,而不是基于正则表达式,因为后者会捕获 源代码字符串中的模式也是如此。有没有这样的工具?

我完全知道 cmets 是有用的信息,并且经常离开它们 因为他们是个好主意。只是我的重点是不同的用例。

【问题讨论】:

    标签: php python c


    【解决方案1】:

    我不知道有这样的工具 - 这与说没有。

    我曾经开始设计一个,但很快就发疯了——C 和 C++ 中的注释规则没有帮助。

    /\
    *  Comment? *\
    /
    

    (答案:是的!)

    "/\
    * Comment? *\
    /"
    

    (答案:不!)

    要合理地完成工作,您必须注意:

    • 语言注释约定
    • 语言引用的字符串约定(Python 和 Perl 足以让你发疯)
    • 转义约定(Shell 将您带到这里 - 连同引号)

    这些结合起来使这项工作几乎不可能完成。

    我最终得到了一个程序,scc,用于剥离 C 和 C++ cmets。它的酷刑测试包括比上面显示的 cmets 更糟糕的例子——而且它做得不错。但是将其扩展为 shell、Perl 或 Python 或(随你选择)是非常重要的,所以我没有这样做。

    【讨论】:

    • 是的。我知道。我可以使用 javacc 和可用的语法 .jj 文件自己编写这样的工具(有很多可用的,适用于所有流行的语言)。我只是想知道是否有人尝试过。 (顺便说一句,我所有的问题都没有得到完全令人满意的回答。)
    【解决方案2】:

    cloc,一个免费的 Perl 脚本,可以做到这一点。

    从源代码中删除注释

    如何判断 cloc 是否正确识别 cmets?说服自己 cloc 做正确事情的一种方法是使用其--strip-comments 选项从文件中删除 cmets 和空行,然后将精简后的文件与原始文件进行比较。

    支持a lot of languages

    【讨论】:

    • 很抱歉,该工具在测试 python 文件中遗漏了很多 cmets——甚至是最基本的注释实例。它不是基于正则表达式的吗?我不知道您是否尝试过,但它似乎无法用于此目的。
    • @otz:这是一个成熟的工具,在我的任何用途上都没有让我失望,包括 Python 脚本。我认为您没有正确使用它。例如,在带有文件foo.py 的目录中执行命令perl /path/to/cloc-1.51.pl --strip-comments=n . 将创建一个删除了cmets 和空行的foo.py.n 文件。我想看一个你声称不起作用的例子(我相信 cloc 的开发人员也会这样做)。
    • 在 javascript 内联 cmets 上失败:paste.ubuntu.com/p/nBVN3S2w8G
    【解决方案3】:

    你可能会诱使GNU Source-highlight 这样做。

    【讨论】:

    • 如果我错了,请纠正我,但在我看来,它并不完全识别语法。它是半语法感知的,因为它本质上是基于正则表达式的,但正则表达式是“结构化的”,具体取决于语言。
    【解决方案4】:

    你想要的可以用 emacs 脚本来完成。

    我为您编写了这个脚本,它完全符合您的要求,并且可以轻松扩展到任何语言。

    文件名:kill-cmets

    #!/usr/bin/python                                                         
    
    import subprocess                                                         
    import sys                                                                
    import os                                                                 
    
    target_file = sys.argv[1]                                                 
    
    command =   "emacs -batch -l ~/.emacs-batch " + \                         
        target_file + \                                                       
        " --eval '(kill-comment (count-lines (point-min) (point-max)))'" + \  
        " -f save-buffer"                                                     
    
    #to load a custom .emacs script (for more syntax support),                
    #use -l <file> in the above command                                       
    
    #print command                                                            
    
    fnull = open(os.devnull, 'w')                                             
    subprocess.call(command, shell = True, stdout = fnull, stderr = fnull)    
    fnull.close()
    

    使用它只需调用:

    kill-comments <file-name>
    

    要向其中添加任何语言,请编辑 ~/.emacs-batch 并添加该语言的主要模式。 您可以在http://www.emacswiki.org 找到几乎所有您想要的语法感知模式。

    例如,这是我的 ~/.emacs-batch 文件。它扩展了上述脚本以从 javascript 文件中删除 cmets。 (我的 ~/.el 目录中有javascript.el

    (setq load-path (append (list (concat (getenv "HOME") "/.el")) load-path))    
    (load "javascript")                                               
    (setq auto-mode-alist (cons '("\\.js$" . javascript-mode) auto-mode-alist))
    

    通过添加 javascript,这将从您提到的所有文件类型以及更多文件类型中删除 cmets。

    祝你好运,编码愉快!

    【讨论】:

    • 哈哈。虽然它不够健壮,因为在大多数语言上突出显示的 emacs 是基于正则表达式的(因此会在字符串中捕获某些奇怪的 cmets,我对你的想法印象深刻:) 我想要的是一个语法感知工具。因此,它必须内置语言解析器(JavaCC .jj .jjt 文件有人吗?)
    • 你应该在关闭它之前在一些测试文件上尝试它。 Emacs 语法高亮相当不错。
    • 在 emacs 上尝试了 (kill-comment ARG)。总体上对它的准确性感到满意。它肯定比本页建议的 cloc 工具准确一百万倍。所以谢谢你。但同样,kill-comment 功能取决于 emacs 中的语法突出显示,其中大多数是基于正则表达式的。所以这真的取决于 -mode.el 有多好。但同样,我喜欢你的想法。
    • “理想情况下”您会想要该语言的嵌入式编译器/解释器,但考虑到在某些病态语言的情况下,实际确定什么是评论,什么不是评论可能是不可计算的(因此需要永远) ,在这种情况下,您实际上想要采用基于正则表达式的方法来删除“标准” cmets!对于许多语言来说,删除 cmets 不需要拉解析,并且可以证明正则表达式方法是正确的(这也是预处理器可能会做的事情)。请记住为您认为有用的答案投票/根据此处的礼仪选择一个作为“最佳”答案。
    【解决方案5】:

    Paul Dixon 的 response to this question 从脚本中剥离 cmets 可能值得一看。

    【讨论】:

    • OP 提到了多种语言,但提到的 Paul Dixons 方法只适用于 PHP。
    【解决方案6】:

    目前还没有这样的工具。

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 2011-05-23
      • 2015-01-09
      • 1970-01-01
      • 2022-10-22
      • 2018-07-18
      • 1970-01-01
      • 2014-07-23
      • 1970-01-01
      相关资源
      最近更新 更多