#ifdef's rausfiltern

  • 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.

  • 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:

  • 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):


    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*

  • 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:


    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!

  • Hab jetzt auf der Basis von deinem mal das zusammengezimmert:


    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*

  • So früh schon so wach im Kopf? ;)

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

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

Jetzt mitmachen!

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