1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

#ifdef's rausfiltern

  • Incazzato
  • 23. August 2005 um 19:42
  • Unerledigt
  • Incazzato
    8
    Incazzato
    Mitglied
    Punkte
    570
    Beiträge
    85
    • 23. August 2005 um 19:42
    • #1

    Ich habe mit teilweise unglaublich unstrukturiertem C/C++ - Code zu tun, bei dem oft weite Teile in #ifdef xy - Klauseln eingebettet sind.
    Ich frage mich, wie sich folgendes mit vertretbarem Aufwand machen lässt:
    Alle source-files sollen nach
    #ifdef XY
    code...
    #endif
    gescannt werden, die Zeilen dazwischen sollen komplett rausgelöscht werden (nein, ich werde den Code nieee mit definiertem XY kompilieren müssen!). Allerdings darf sich so ein Parser nicht durch geschachtelte #ifdef's drausbringen lassen.
    Außerdem sollte im Fall
    #ifdef XY
    code...
    #else
    code...
    #endif
    zusätzlich das abschließende #endif entfernt werden, damit der Präprozessor keinen Syntax-Fehler bringt.
    Ich wäre noch in der Lage, dies formal - etwa in EBNF - zu formulieren. Aber mit welchen Tools macht man sowas dann? Geht es mit dem Präprozessor selber irgendwie? Oder mit sed/awk (Ich habe keinen Schimmer, wie man damit umgeht)?
    Wäre für Tipps dankbar.

  • Kongo
    6
    Kongo
    Mitglied
    Punkte
    295
    Beiträge
    44
    • 23. August 2005 um 19:47
    • #2

    Das schreit ja richtig nach Perl :))

    Also im Ernst. Mit Perl sind das sicher nur ein paar Zeilen Code um so nen Parser zu schreiben.

    :thumb: Geschrieben nach der alten, neuen und zukünftigen Rechtschreibung! :thumb:

  • Plantschkuh!
    24
    Plantschkuh!
    Mitglied
    Reaktionen
    163
    Punkte
    6.173
    Beiträge
    1.181
    • 23. August 2005 um 20:09
    • #3

    Zu Perl äußer ich mich nicht, aber hier ist eine potentielle primitive Lösung mit lex (ja, die erste Zeile gehört eingerückt):

    Code
    unsigned long level = 0;
    
    
    %%
    
    
    #if(n?def)? level++;
    #else       ;
    #endif      level--;
    \n          if (level == 0) ECHO;
    .           if (level == 0) ECHO;
    Alles anzeigen


    Usage:

    Code
    lex foo.l && gcc lex.yy.c -lfl && ./a.out < input.c > output.c


    wobei foo.l obiger Lex-Source ist und input.c das zu transformierende Programm.

    Edit: Das tut jetzt übrigens alle #ifs und #ifdefs raus. Falls nur #ifdef für bestimmte Makros gemeint war, dann wirds bissi komplizierter.

    *plantsch*

  • Incazzato
    8
    Incazzato
    Mitglied
    Punkte
    570
    Beiträge
    85
    • 24. August 2005 um 00:23
    • #4
    Zitat von Plantschkuh!

    Zu Perl äußer ich mich nicht, aber hier ist eine potentielle primitive Lösung mit lex (ja, die erste Zeile gehört eingerückt):


    Das liest sich sehr gut!
    In der Tat sollen nur genau die von einem bestimmten Makro abhängigen Blöcke raus, sagen wir mal von "KACK" . Ich versuche das mal einzubauen:

    Code
    unsigned long level = 0;
        unsigned long kack_flag = 0;     // oder gibts auch boolean?
        signed long kack_level = -1;
    
    
    %%
    
    
    #ifdef KACK  kack_flag = 1; kack_level = level;
    #if(n?def)?   level++;
    #else           ;                   // nur zur Dekoration, oder?
    #endif          level--; if (level == kack_level) kack_flag = 0; kack_level = -1;
    \n         if (kack_flag == 0) ECHO;
    .           if (kack_flag == 0) ECHO;
    Alles anzeigen


    Syntax ist einfach geraten, korrigiere mich bitte gegebenenfalls. Muss bei "#ifdef KACK" das Leerzeichen gequotet werden?
    Kann ich die auszuführenden Anweisungen so hintereinanderschreiben? Was bedeuten "\n" und "." am Ende?

    Vielen Dank übrigens!

  • Plantschkuh!
    24
    Plantschkuh!
    Mitglied
    Reaktionen
    163
    Punkte
    6.173
    Beiträge
    1.181
    • 24. August 2005 um 09:46
    • #5

    Hab jetzt auf der Basis von deinem mal das zusammengezimmert:

    Code
    unsigned long level = 0;
        int kack_flag = 0;
        signed long kack_level = -1;
    
    
    ifkack  #ifdef\ +__cplusplus
    
    
    %%
    
    
    {ifkack}    kack_flag = 1; kack_level = level++;
    #if(n?def)? level++; ECHO;
    #else       if (kack_flag) kack_flag = 0; else ECHO;
    #endif      {
                    level--;
                    if (level == kack_level)
                    {
                        kack_flag = 0;
                        kack_level = -1;
                    }
                    else
                        ECHO;
                }
    \n          if (kack_flag == 0) ECHO;
    .           if (kack_flag == 0) ECHO;
    Alles anzeigen


    Sollte funktionieren, solang nirgends #ifdef KACK in einem Kommentar oder String vorkommt und #ifdef KACKs nicht geschachtelt sind. Du mußt nur in der Zeile "ifkack #ifdef\ +__cplusplus" das __cplusplus durch den Namen deines Makros ersetzen.
    Und ja, die Regel für #else war in meiner ersten Version redundant, sollte nur andeuten, daß ein #else explizit nicht ausgegeben werden soll.
    \n steht für ein Newline (Zeilenende), . für ein beliebiges Zeichen außer Newline. D.h. alle Zeichen, die nicht Teil von einem #ifdef oder sowas sind, sollen ausgegeben werden, wenn der flag 0 ist.

    Und schließlich: http://www.eskimo.com/~scs/C-faq/q10.18.html

    *plantsch*

  • Incazzato
    8
    Incazzato
    Mitglied
    Punkte
    570
    Beiträge
    85
    • 24. August 2005 um 12:16
    • #6

    So früh schon so wach im Kopf? :winking_face:

    Weils so schön ist, noch meine endgültige Version:

    Code
    unsigned long level = 0;
        int kack_flag = 0;
        signed long kack_level = -1;
    
    
    ifkack  #ifdef\ +KACK
    
    
    %%
    
    
    {ifkack}    	kack_flag = 1; kack_level = level++;
    #if(n?def)? 	{
    		level++;
    		if (kack_flag == 0) ECHO;
    		}
    #else       	{
    		if(kack_flag) {
    			if(kack_level == (level-1)) {
    				kack_flag = 0;
    			}
    		}
    		else ECHO;
    		}
    #endif      	{
                    level--;
                    if (level == kack_level)
                    {
                        kack_flag = 0;
                        kack_level = -1;
                    }
                    else
    			if (kack_flag == 0) ECHO;
    		}
    \n          	if (kack_flag == 0) ECHO;
    .           	if (kack_flag == 0) ECHO;
    Alles anzeigen

    Waren noch kleine Änderungen nötig, damit bei innerer und äußerer Verschachtelung alls stimmt. z.B blieben in Header-Files Zeilen mit "#ifdef endif" übrig.
    Aber jetzt habe ich den ganzen (entKACKten) Kack ohne Syntaxfehler kompiliert.

    muchos gracias!
    PS: ich war mal in deiner TheoInf-Übung :winking_face:

  • Maximilian Rupp 27. Dezember 2024 um 12:06

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Rechtliches

Impressum

Datenschutzerklärung