Frage

Kann mir jemand Punkt zu einem Programm, das Strings aus C-Quellcode abstreift? Beispiel

#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;
}

wird

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

Was ich suche ist ein Programm sehr ähnlich wie stripcmt nur, dass ich will Strings abzustreifen und nicht die Kommentare.

Der Grund, dass ich für ein bereits entwickeltes Programm suchen und nicht nur einige praktisch regulärer Ausdruck ist weil, wenn Sie beginnen alle Eckfällen (Anführungszeichen innerhalb von Zeichenketten, mehrzeiligen Strings usw.) unter Berücksichtigung Dinge beginnen in der Regel (viel) sein komplexer als es zuerst erscheint. Und gibt es Grenzen, was REs erreichen kann, ich vermute, dass es für diese Aufgabe nicht möglich ist. Wenn Sie denken, Sie haben eine extrem robust regulären Ausdruck zu unterbreiten fühlen Sie sich frei, aber bitte nicht naiv sed 's/"[^"]*"//g' wie Vorschläge.

(keine Notwendigkeit für eine spezielle Handhabung von (möglicherweise un-ended) Strings innerhalb von Kommentaren, wird diese zuerst entfernt werden)

Unterstützung für mehrzeilige Strings mit eingebetteten Zeilenumbrüchen ist nicht wichtig (nicht legal C), aber Strings enden mehrere Zeilen mit \ am Ende Spanning muss unterstützt werden.

Dies ist fast das gleiche wie die < a href = "https://stackoverflow.com/questions/676296/how-to-tokenize-parse-string-literals-from-javascript-source-code"> andere questions , aber ich fand keinen Hinweis auf irgendwelche Werkzeuge.

War es hilfreich?

Lösung

Sie können die Quellcode StripCmt (tar.gz - 5kB). Es ist trivialerweise klein, und sollte nicht allzu schwierig sein, anstatt zu Striping Saiten anzupassen (es ist released unter der GPL ).

Sie möchten vielleicht auch die offiziellen lexikalischen Sprachregeln für C-Strings untersuchen. Ich fand diese sehr schnell, aber es könnte nicht sein definitiv. Es definiert eine Zeichenfolge wie:

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

Andere Tipps

Alle der Tokens in C (und die meisten anderen Programmiersprachen) sind „normale“. Das heißt, sie können durch einen regulären Ausdruck angepasst werden.

Ein regulärer Ausdruck für C-Strings:

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

Die Regex ist nicht allzu schwer zu verstehen. Im Grunde ein Stringliteral ist ein Paar doppelter Anführungszeichen umgeben ein Bündel von:

  • Nicht-Sonder (non-Zitat / Backslash / Newline) Zeichen
  • Fluchten, die mit einem Schrägstrich beginnen und dann aus einem von:
    • ein einfaches Escape-Zeichen
    • 1 bis 3 Oktalziffern
    • x und 1 oder mehr hexadezimale Ziffern

Dies basiert auf Abschnitten 6.1.4 und 6.1.3.4 des C89 / C90 spec. Wenn irgendetwas anderes in C99 schleicht, wird dies nicht verstanden, aber das sollte nicht schwer zu beheben.

Hier ist ein Python-Skript, eine C-Quelldatei Entfernen Stringliterale zu filtern:

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:

Es kam mir, nachdem ich die darüber geschrieben, während es wahr ist, dass alle C-Token regelmäßig sind, indem sie nicht alles, was wir Zeichenüber eine Chance für die Mühe haben. Insbesondere dann, wenn ein doppeltes Anführungszeichen zeigt sich in dem, was ein anderer Token sein sollten wir den Gartenweg hinunter führen kann. Sie haben erwähnt, dass die Kommentare bereits abgezogen worden ist, so dass die einzige andere Sache, die wir über wirklich Charakter kümmern müssen Literale (obwohl der Ansatz Im gehend zu verwenden, leicht und zu handhaben Kommentare verlängert werden). Hier ist ein robuster Skript, das Zeichenliterale Griff:

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

Im Wesentlichen String und Zeichenliteral Token wir finden, und dann char-Literale allein zu lassen, aber Stringliterale Strippen. Die char wörtliche regex ist sehr ähnlich den Stringliteral ein.

In rubin:

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

druckt auf die Standardausgabe

In Python pyparsing:

from pyparsing import dblQuotedString

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

druckt auch auf die Standardausgabe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top