【问题标题】:Removing strings from C source code [closed]从 C 源代码中删除字符串 [关闭]
【发布时间】:2010-11-20 15:12:20
【问题描述】:

谁能指出一个从 C 源代码中去除字符串的程序?示例

#include <stdio.h>
static const char *place = "world";
char * multiline_str = "one \
two \
three\n";
int main(int argc, char *argv[])
{
        printf("Hello %s\n", place);
        printf("The previous line says \"Hello %s\"\n", place);
        return 0;
}

变成

#include <stdio.h>
static const char *place = ;
char * multiline_str = ;
int main(int argc, char *argv[])
{
        printf(, place);
        printf(, place);
        return 0;
}

我正在寻找的是一个非常像stripcmt 的程序 只是我想剥离字符串而不是 cmets。

我正在寻找一个已经开发的程序而不仅仅是一些方便的正则表达式的原因是 因为当您开始考虑所有极端情况时(字符串中的引号、多行字符串等) 事情通常开始比最初看起来要复杂得多。和 REs 可以实现的目标是有限的,我怀疑这项任务是不可能的。 如果您确实认为自己有一个非常强大的正则表达式,请随时提交,但请不要天真的sed 's/"[^"]*"//g' 喜欢建议。

(不需要对 cme​​ts 中的(可能未结束的)字符串进行特殊处理,这些将首先被删除)

支持嵌入换行符的多行字符串并不重要(不合法的 C 语言),但必须支持跨越多行以 \ 结尾的字符串。

这和someotherquestions几乎一样,但是我没有找到任何工具的参考。

【问题讨论】:

  • 纯粹出于兴趣,为什么需要这样的工具?换句话说,您打算如何处理该工具的输出?
  • 用于token搜索。例如“在哪些文件中调用了函数 x、y 和 z”。通过预处理、删除 cmets 和字符串,我将得到准确的结果。目前字符串正在产生噪音。
  • 用懂C的代码分析工具不是更好吗?有很多。
  • 我想将 find + xargs 与检查脚本一起使用(无需设置),其中该检查脚本在执行实际工作之前先剥离 cmets 和字符串(例如,可以检查如果文件调用 printf,则应包含 )。

标签: c string code-formatting utility reformatting


【解决方案1】:

在 Python 中使用 pyparsing:

from pyparsing import dblQuotedString

source = open(filename).read()
dblQuotedString.setParseAction(lambda : "")
print dblQuotedString.transformString(source)

也打印到标准输出。

【讨论】:

    【解决方案2】:

    在红宝石中:

    #!/usr/bin/ruby
    f=open(ARGV[0],"r")
    s=f.read
    puts(s.gsub(/"(\\(.|\n)|[^\\"\n])*"/,""))
    f.close
    

    打印到标准输出

    【讨论】:

      【解决方案3】:

      C(和大多数其他编程语言)中的所有标记都是“常规的”。也就是说,它们可以通过正则表达式匹配。

      C 字符串的正则表达式:

      "([^"\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))*"
      

      正则表达式并不难理解。基本上,字符串文字是一对双引号,围绕着一堆:

      • 非特殊(非引号/反斜杠/换行符)字符
      • 转义符,以反斜杠开头,然后包含以下内容之一:
        • 一个简单的转义字符
        • 1 到 3 个八进制数字
        • x 和 1 个或多个十六进制数字

      这是基于 C89/C90 规范的 6.1.4 和 6.1.3.4 部分。如果 C99 中出现了其他问题,这将无法解决,但这应该不难修复。

      这是一个用于过滤 C 源文件并删除字符串文字的 python 脚本:

      import re, sys
      regex = re.compile(r'''"([^"\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))*"''')
      for line in sys.stdin:
        print regex.sub('', line.rstrip('\n'))
      

      编辑:

      在我发布上述内容后,我突然想到,虽然所有 C 标记都是常规的,但如果不标记所有内容,我们就有可能遇到麻烦。特别是,如果双引号出现在应该是另一个标记的地方,我们可以被引导到花园小路上。您提到 cmets 已经被剥离,所以我们真正需要担心的唯一另一件事是字符文字(尽管我将使用的方法也可以轻松扩展以处理 cmets)。这是一个处理字符文字的更强大的脚本:

      import re, sys
      str_re = r'''"([^"\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))*"'''
      chr_re = r"""'([^'\\\n]|\\(['"?\\abfnrtv]|[0-7]{1,3}|x[0-9a-fA-F]+))'"""
      
      regex = re.compile('|'.join([str_re, chr_re]))
      
      def repl(m):
        m = m.group(0)
        if m.startswith("'"):
          return m
        else:
          return ''
      for line in sys.stdin:
        print regex.sub(repl, line.rstrip('\n'))
      

      本质上,我们正在寻找字符串和字符文字标记,然后单独留下 char 文字,但去掉字符串文字。 char 文字正则表达式与字符串文字非常相似。

      【讨论】:

      • 这种情况下我觉得会更好:([^"\\\n]|\\.)*
      • 您的正则表达式无法处理 two \three\n";>> 其中 表示有换行符。这就是我所说的极端情况:)
      • 使用 \ 加入行是预处理的一部分,我忽略了这一点。 (例如:如果代码是 > - 那你想做什么呢?)如果你只关心行连接,你可以在 abfnrtv 字符类中添加 \n , 并用 sys.stdout.write(regex.sub(repl, sys.stdin.read()) 替换 for 循环。如果您担心 char 文字内部的行连接,还需要调整 chr_re .
      • 另一个选项,取决于你想要的,是首先通过预处理器运行所有代码。
      【解决方案4】:

      您可以下载source code to StripCmt (.tar.gz - 5kB)。它非常小,并且不应该太难适应条带化字符串(它是released under the GPL)。

      您可能还想研究 C 字符串的官方词汇语言规则。我很快找到了this,但它可能不是确定的。它将一个字符串定义为:

      stringcon ::= "{ch}", where ch denotes any printable ASCII character (as specified by isprint()) other than " (double quotes) and the newline character.
      

      【讨论】:

      • 我没有想过要检查stripcmt的来源。修改起来很简单。
      猜你喜欢
      • 1970-01-01
      • 2010-12-09
      • 2012-09-12
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 2012-10-02
      • 2017-04-21
      相关资源
      最近更新 更多