2009-08-18 15 views
2

誰もがCソースコードから文字列を取り除くプログラムを指摘できますか?例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 だけのようなプログラムです。

あなたはすべてのコーナーケースを考慮し始めるとき(文字列内の引用符は、複数行の文字列など) 事が一般的になり始めるので、私はすでに開発されたプログラムを探しているだけでなく、いくつかの便利な正規表現しています理由は です(多くの)より複雑なものが最初に現れます。そして REが達成できるものには限界がありますが、私はそれがこの作業には不可能だと考えています。 あなたはと思っていれば、極度のの堅牢な正規表現を投稿しても構いませんが、提案は好きではありません。sed 's/"[^"]*"//g'

(ない法的C)埋め込まれた改行で複数行の文字列の

のサポートは重要ではありません(、それらが最初に削除されますコメント内の(おそらく非エンド)の文字列の特別な処理は必要ない)が、最後に\で終わる複数の行にまたがる文字列をサポートする必要があります。

これはsomeotherquestionsとほぼ同じですが、どのツールも参照できませんでした。

+3

純粋に興味のあることとして、なぜこのようなツールが必要ですか?言い換えれば、ツールの出力で何をするつもりですか? –

+0

トークン検索用です。たとえば、「どのファイルにx、y、zという関数がありますか」。あらかじめ処理してコメントや文字列を削除することで、正確な結果が得られます。現在のところ、ストリングはノイズを生成しています。 – hlovdal

+2

Cを理解するコード解析ツールを使用する方が良いのではないでしょうか?それらの多くがあります。 –

答えて

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. 
+0

私はstripcmtのソースをチェックすることを考えていませんでした。変更は簡単でした。 – hlovdal

5

C(および他のほとんどのプログラミング言語)のトークンのすべての「通常の」です:それはのように文字列を定義します。つまり、正規表現で一致させることができます。

C文字列の正規表現:

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

正規表現を理解するにはあまりにも難しいことではありません。基本的には文字列リテラルはの束を囲む二重引用符のペアは次のとおりです。

  • 非特殊な(非引用/バックスラッシュ/改行)文字をバックスラッシュで始まり、その後の1で構成さ
  • エスケープ、 :
    • 簡単なエスケープ文字
    • 1〜3桁の8進数
    • xと1以上の六角桁

これはセクション6.1.4と6.1.3に基づいています。C89/C90仕様の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')) 

EDIT:

私は上記の投稿をした後、それはすべてCというのは本当である間、と私に起こりましたトークンは定期的なものですが、私たちはトラブルの機会があるすべてをトークン化しません。特に、二重引用符が別のトークンでなければならない場合、私たちは庭の道を導くことができます。コメントはすでに削除されていると言いました。私たちが本当に心配する必要があるのは、文字リテラルだけです(ただし、使用するアプローチはコメントを扱うために簡単に拡張できます)。ここでは文字リテラルを処理し、より堅牢なスクリプトは次のとおりです。

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リテラル正規表現は、文字リテラル1と非常によく似ています。 Rubyで

+0

この場合、私はそれが良いと思います:(*^\\ n)| \\。)* – hiena

+0

正規表現が処理できません << char * str = "one \ two \ three \ n "; >>は、改行があることを示しています。これはコーナーケースの意味です。 – hlovdal

+0

\を使用して行を結合するのは前処理の一部であり、無視しています(例: > - あなたは何をやりたいのですか?)あなたが心配しているのはラインジョインです。abfnrtv文字クラスに\ nを追加し、forループをsys .stdout.write(regex.sub(repl、sys.stdin.read())。charリテラルの内部で行の連結を心配している場合は、chr_reを微調整する必要があります。 –

0

:pyparsingを使用してPythonで標準出力

0

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

プリント:

from pyparsing import dblQuotedString 

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

もstdoutに印刷します。

関連する問題