Schrift
[thread]6557[/thread]

C Datei parsen: An Regex-Experten



<< >> 10 Einträge, 1 Seite
alexus-777
 2004-09-01 22:42
#49805 #49805
User since
2004-04-13
121 Artikel
BenutzerIn
[default_avatar]
Hallo Community,

es soll eine C Quellcode Datei nach bestimmten Strings durchgesucht werden. Das Problem stellen Kommentare dar,

Code: (dl )
1
2
3
4
 /* Kommentar */<string>
<string> /*Kommentar
*/ <code> /*Kommentar*/ <string>/*
*/


die manchmal über mehrere Zeilen gehen. Gesuchte Strings können auch dazwischen stehen. Kommentare sollen dabei komplett ignoriert werden.

Hat jemand ein gescheites Regex Vorschlag, um dieses Prob zu lösen?

Danke im Voraus
Gruß Alexander
lichtkind
 2004-09-01 22:56
#49806 #49806
User since
2004-03-22
5697 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
also ich bin noch nicht der regex king aber die exe hat auch einen multiline mode wo es egal ist ob ein zeilen ende dazwichen ist, es ist ein parameter m der das macht vielleicht voher die newlines rausfiltern.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
betterworld
 2004-09-02 02:05
#49807 #49807
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Am einfachsten waere es, wenn Du zunaechst mit s#/\*.*?\*/## und s#//.*## alle Kommentare aus dem String entfernst und dann mit dem Resultat arbeitest. Das koennte allerdings je nach Rahmenbedingung etwas ineffizient sein.

Ansonsten haette ich noch eine Moeglichkeit:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use strict;
use warnings;

my $c1 = '
/* Kommentar */

/* Noch
ein Kommentar XXX */
';

my $c2 = '
/* Kommentar */

XXX';

my $re = qr#^(?:(?!/\*).|/\*.*?\*/)*XXX#s;

print "XXX kommt in c1 vor\n" if $c1 =~ $re;
print "XXX kommt in c2 vor\n" if $c2 =~ $re;


Vielleicht sind da noch ein paar Bugs mit verschachtelten Kommentaren drin, ausserdem werden // -Kommentare nicht beruecksichtigt, aber das kriegst Du dann auch alleine hin.\n\n

<!--EDIT|betterworld|1094076355-->
Crian
 2004-09-02 03:37
#49808 #49808
User since
2003-08-04
5872 Artikel
ModeratorIn
[Homepage]
user image
Und pass auf, früher war es ok, Kommentare durch nichts zu ersetzen, was dazu führte, dass man damit Quelltext zusammensetzen konnte. Heute gibt es dafür ein spezielles Makro (## falls ich mich richtig erinnere) und Kommentar wird durch ein Leerzeichen ersetz.

Edit: Und bedenke "Schweinereien" wie

Code: (dl )
1
2
 int  a = 3;    /* Dies ist /* ein Kommentar */
char b = '\n'; /* dies ist auch ein Kommentar */


Edit2: Ich würde mit Konstrukten wie

Code: (dl )
s~/\*(?:(?!\*/).)*\*/~~gs


bzw. in schöner

Code: (dl )
1
2
3
4
s~/\*            # Kommentar-Anfang
  (?:(?!\*/).)*  # Kommentar-Inneres
  \*/            # Kommentar-Ende
 ~~gsx


arbeiten.

Problematisch könnte es auch sein, wenn Kommentaranfang oder Ende irgendwo in konstanten Strings auftaucht. Genaugenommen müsstest Du darauf auch achten, aber dann brauchst Du bald einen echten Parser.\n\n

<!--EDIT|Crian|1094082603-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Ishka
 2004-09-02 04:04
#49809 #49809
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Dann gibts noch die Gemeinheit, daß // - Kommentare im Falle eines \ am Zeilenende sich auch auf die nächste Zeile beziehen, also
Code: (dl )
s#//.*(\\\n.*)*##g;
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
betterworld
 2004-09-02 04:07
#49810 #49810
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Und nicht zu vergessen die folgende Art zu kommentieren:
Code: (dl )
1
2
3
#if 0
dies ist ein Kommentar
#endif
Crian
 2004-09-02 04:28
#49811 #49811
User since
2003-08-04
5872 Artikel
ModeratorIn
[Homepage]
user image
Also würd ich mich pragmatisch nach den in Deinen C-Quellen vokommenden Schweinereien richten und alles andere noch als Kommentar in Deinen Code schreiben, um deutlich zu machen, dass er nicht allgemeingültig ist, bzw. dass Du schlau genug warst all diese Finten zu erkennen, Du sie aber aus Pragmatismus nicht behalndelst.

Das sichert einen auch ab, falls später mal jemand meint, man hätte da doch mal sowas geschrieben, dass das und das könne, ob man ihm das Programm nicht mal geben könne. Zu dem Zeitpunkt weiß man dann auch nicht mehr genau, was man damals exakt gemacht hat bzw. hat keine Zeit alles nochmal zu durchdenken, also drückt man es dem Kollegen dann in die Hand, und wenns dann am Ende bei ihm crasht ist mans dann gewesen Steht dann aber im Quellcode drin, welche Fälle nicht behandelt werden, ist man fein raus. ;-)

Ok ist mir noch nicht passiert, aber ich bin da etwas paranoid =)
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
pq
 2004-09-02 05:09
#49812 #49812
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
perldoc -q comments
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
betterworld
 2004-09-02 05:46
#49813 #49813
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
[quote=pq,02.09.2004, 03:09]perldoc -q comments[/quote]
Wobei der Ausdruck, der da empfohlen wird, ja auch zunaechst alle Kommentare entfernt. Das benoetigt einen zweiten Durchlauf und ist daher (glaube ich) nicht so ganz effizient.
alexus-777
 2004-09-02 09:16
#49814 #49814
User since
2004-04-13
121 Artikel
BenutzerIn
[default_avatar]
Danke, für die Vorschläge! :)
<< >> 10 Einträge, 1 Seite



View all threads created 2004-09-01 22:42.