Laden...

Mit Regex C++-Dateien parsen

Erstellt von Nachtwind vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.229 Views
N
Nachtwind Themenstarter:in
118 Beiträge seit 2005
vor 14 Jahren
Mit Regex C++-Dateien parsen

Hm.. in einem kleinen Programm versuche ich C(++) Dateien zu parsen..
Im Moment versuche ich erst einmal ganz einfach nur die Funktionen herauszuziehen.. Klassen kaemen spaeter einmal dran - das ist erstmal zweitrangig.
Das einfachste waere sicher fuer diese Art Job eine Regexsuche zu machen... Dummerweise habe ich praktisch keine Idee von Regex und versucht folgenden Code zusammenzubasteln:


  void[^]
  /{ 
  \b[A-Z0-9._%+-
  \}

Das ganze ist, natuerlich, ziemlich falsch... hat hier jemand eine Ahnung, wie man den entsprechenden Pattern schreiben kann? am besten waere es auch statt nur void auch int/char etc zu haben.. aber da hab ich nun gar keinen Schimmer mehr von...

Danke schonmal :0)

3.430 Beiträge seit 2007
vor 14 Jahren

Hallo Nachtwind,

ich bin zwar auch nicht der RegexExperte und kann auch nicht wirklich weiter helfen, aber ich kenne das Programm von Hebivore
On-the-fly Regex-Tester: Regex-Lab

Damit kann man das sehr schön testen und das Leben wird gleich viel einfacher =)

Gruss
Michael

5.299 Beiträge seit 2008
vor 14 Jahren

Hi!

einen wasserdichten CodeParser wird man allein mit Regex nicht erstellen können. Weil Regex kann prinzipiell keine verschachtelten Strukturen analysieren.

Und damit würdich an deiner Stelle auch anfangen: mit der Analyse der Verschachtelung. und im Kopf der verschachtelten Blöcke müsste sich iwie unterscheiden lassen: isses ein Namespace, ein for, if, loop, while etc.

So in die Richtung

Der frühe Apfel fängt den Wurm.

N
Nachtwind Themenstarter:in
118 Beiträge seit 2005
vor 14 Jahren

Naja... gedacht habe ich mir das auch schon, aber da ich keinen echten Codeparser brauche sondern nur ganze Funktionen aus einer Datei auslesen brauche, dachte ich wuerde Regex reichen. Schade, dass nicht(?)

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo Nachtwind,

Schade, dass nicht(?)

Wie schon gesagt, das Regex kann keine verschachtelten Strukturen - in deinem Fall klappt das mit den geschweiften Klammern zum Erkennen des Anfangs und Endes einer Methode nicht. Mit Regex könntest du nur bis zur ersten (bzw. n-ten) geschlossenen Klammer suchen.

Gruß,
dN!3L

N
Nachtwind Themenstarter:in
118 Beiträge seit 2005
vor 14 Jahren

Naja, im grossen und ganzen gehts also wieder zurueck zu einer etwas umstaendlichereren Suche.. schade. Dachte Regex waeren hier der beste Weg.

Ich versuche einen kleinen Parser zu schreiben mit dem ich Arduinosketche durch avr-gcc schicken kann. Da die Sketche einen etwas anderen Aufbau als AVR-C Dateien haben muss ich die resultierende Datei etwas umbauen, so dass aus


void setup()
{
  //..
}

void loop()
{
 //...
}


void main()
{
//setup code

while(true)
 {
   //loop code
  }
}

wird.

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo Nachtwind,

ich habe mal etwas ähnliches gemacht (alle Klassen aus einer Datei lesen). Hier mal der relevante Code:


string text = File.ReadAllText(sourcePath);
foreach (Match match in Regex.Matches(text,@"<Regex für Methodendeklaration>"))
{
	int index = match.Index;

	while (text[index++]!='{') ;
	int bracketCount = 1;
	while (bracketCount>0)
	{
		if (text[index]=='{')
			bracketCount++;
		else if (text[index]=='}')
			bracketCount--;
		index++;
	}

	string methodContent = text.Substring(match.Index,index-match.Index);
}

Gruß,
dN!3L

N
Nachtwind Themenstarter:in
118 Beiträge seit 2005
vor 14 Jahren

Danke schonmal fuer den Code.
startindex - ist das das erste Zeichen des funktionsaufrufs? also das 'v' von void?

was muss der Regex abdecken?
habe einen, der den kompletten Functionsheader abdeckt (also void bla(args))

2.891 Beiträge seit 2004
vor 14 Jahren

startindex - ist das das erste Zeichen des funktionsaufrufs? also das 'v' von void? Ups, noch ein Überbleibsel aus dem Ursprungscode. Ja, das der Index des ersten Zeichens der Methodendeklaration (also match.Index). Ich habe den Code oben entsprechend korrigiert.

was muss der Regex abdecken?
habe einen, der den kompletten Functionsheader abdeckt (also void bla(args))

Wenn du den hast, einwandfrei. Das Snippet braucht ihn zwar nicht komplett, aber je spezifischer, desto besser. Er sollte halt nur nicht irgendwo dazwischen Matchen und auch nicht auf übergeordnete Elemente (Klasse, Namespace).

Beste Grüße,
dN!3L

1.361 Beiträge seit 2007
vor 14 Jahren

Hi dN!3L,

wenn ich das richtig sehe, geht das aber natürlich nur, wenn die brackets wirklich Blöcke beschreiben sollen. (Also nicht im String oder Kommentar)

Kurz gefasst: Die obige Methode würde sich nicht mal selbst korrekt finden 😃
(Aber wenn man strings und kommentare ausschließen kann, gehts ja)

beste Grüße
zommi

2.891 Beiträge seit 2004
vor 14 Jahren

Hallo zommi,

vollkommen korrekt.
Ich habe den Code damals benutzt, um die "Eine einzige Klasse pro Datei"-Regel umzusetzten und mir massig Arbeit zu ersparen (in 5 Dateien steckten so 150 Klassen - nicht von mir!). Für sowas hat's gereicht, hat nur minimale manuelle Nacharbeiten erfordert. Sollte man mehr vorhaben, muss man sich natürlich um Kommentare und Vorkommen in Zeichenketten Gedanken machen.

@Nachtwind: Willst du einzig "void setup()" durch "void main()" und "} void loop()" durch "while (true)" ersetzen? Oder noch mehr? Denn wenn die Struktur immer so wie beschrieben ist, ginge das sehr leicht mit Regex.Replace zu lösen (ohne Klammernprobleme).

Gruß,
dN!3L

N
Nachtwind Themenstarter:in
118 Beiträge seit 2005
vor 14 Jahren

Hm, jain.. das ist im Grunde das, was zu tun waere. Neben diesen beiden Aenderungen gibt es aber noch den ueblichen wust an Variablen und 'fremd'funktionen, die einfach in die neue Datei uebernommen werden muessten.

3.971 Beiträge seit 2006
vor 14 Jahren

Kleiner Hinweis am Rande

habe einen, der den kompletten Functionsheader abdeckt (also void bla(args))

Wobei dieser absolut nur für C(++) zu gebrauchen wäre, für JavaScript oder C# könnte man diesen wegen mehrzeiligen Lambda-Ausdrücken/anonyme Funktionen nicht verwenden.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...