6 Stimmen

`Fehler beim Parsen des Splint-Debuggings`

Dies ist das erste Mal, dass ich splint (aus den Ubuntu-Repositories) benutze, und ich wurde sofort von einem WTF getroffen. Die Fehlermeldung:

nightcracker@nightcracker-pc:~/c/brainfuck$ splint brainfuck.c
Splint 3.1.2 --- 03 Mai 2009

brainfuck.c:17:6: Parsefehler. (Für Hilfe bei Parsefehlern siehe splint -help
               parseerrors.)
*** Kann nicht fortgesetzt werden.

Offenbar sieht es jetzt etwas falsches in Zeile 16, Spalte 6. Lassen Sie uns das überprüfen (Veröffentlichung des vollständigen Codes):

#include 
#include 
#include 

enum {
    CELL_CHUNK_SIZE = 1024,
};

typedef unsigned char cell;

int main(int argc, char *argv[]) {
    if (argc < 1) {
        fprintf(stderr, "FEHLER: Nicht genügend Argumente\n");
        return 1;
    }

    FILE  *srcfile; // Quelldatei << DIESE LINIE SCHEINT FALSCH ZU SEIN
    long srclen; // Größe der Quelldatei
    char *bf; // Brainfuck-Code in Speicher

    char *ip; // Befehlszeiger
    cell *cells; // Brainfuck-Zellen
    cell *newcells; // zum Erstellen eines neuen Zellchunks verwendet
    cell *cp; // Zellenzeiger
    unsigned long numcells = CELL_CHUNK_SIZE; // Anzahl der aktuellen Zellen
    unsigned nest; // aktuelle Verschachtelung
    int buf; // Ein-/Ausgabe-Puffer

    srcfile = fopen(argv[1], "rb");
    if (srcfile == NULL) {
        fprintf(stderr, "FEHLER: Konnte die Quelldatei nicht öffnen\n");
        return 2;
    }

    // Quelldateilänge abrufen
    fseek(srcfile, 0, SEEK_END);
    srclen = ftell(srcfile);
    fseek(srcfile, 0, SEEK_SET);

    // Speicher für Quelldatei zuweisen
    bf = malloc(srclen);
    if (bf == NULL) {
        fprintf(stderr, "FEHLER: Konnte keinen Speicher für die Quelldatei zuweisen\n");
        return 3;
    }

    // Quelldatei im Speicher lesen
    if (srclen != fread(bf, sizeof(char), srclen, srcfile)) {
        fprintf(stderr, "FEHLER: Fehler beim Lesen der Quelldatei\n");
        free(bf);
        return 4;
    }

    fclose(srcfile);

    cells = malloc(CELL_CHUNK_SIZE * sizeof(cell));
    memset(cells, 0, CELL_CHUNK_SIZE);

    if (cells == NULL) {
        fprintf(stderr, "FEHLER: Speicherzuweisung fehlgeschlagen\n");
        free(bf);
        free(cells);
        return 5;
    }

    cp = cells; // Zellenzeiger auf am weitesten links stehende Zelle initialisiert
    ip = bf; // Befehlszeiger auf das erste Zeichen initialisiert
    nest = 0;

    while (ip >= bf && ip <= (bf + srclen)) {
        switch (*ip) {
            case '+':
                (*cp)++;
                break;
            case '-':
                (*cp)--;
                break;
            case '>':
                cp++;
                if ((cp - cells) == numcells) {
                    newcells = realloc(cells, (numcells + CELL_CHUNK_SIZE) * sizeof(cell)); // Speicher für neuen Chunk zuweisen

                    if (newcells == NULL) {
                        fprintf(stderr, "FEHLER: Speicherzuweisung fehlgeschlagen\n");
                        free(bf);
                        free(cells);
                        return 5;
                    }

                    cp = newcells + (cp - cells); // Zellenzeiger auf Zelle im neuen Chunk zeigen lassen
                    cells = newcells; // Zellen auf neue Speicherstelle zeigen lassen (falls verändert)
                    memset(cp, 0, CELL_CHUNK_SIZE); // neuen Chunk initialisieren
                    numcells += CELL_CHUNK_SIZE;
                }
                break;
            case '<':
                cp--;
                break;
            case '.':
                putchar(*cp);
                break;
            case ',':
                if ((buf = getchar()) != EOF) {
                    *cp = (unsigned char) buf;
                } else *cp = 0;
                break;
            case '[':
                if (!(*cp)) {
                    ip++; // über die öffnende Klammer hinaus bewegen
                    while (nest > 0 || *ip != ']') { // zu passendem ] springen
                        if (*ip == '[') nest++; // Verschachtelung betreten
                        if (*ip == ']') nest--; // Verschachtelung verlassen (oder Hauptschleife, bei der Verschachtelung > 0 fehlschlägt)

                        ip++; // nach rechts bewegen
                    }

                }
                break;
            case ']':
                if (*cp) {
                    ip--; // vor schließende Klammer bewegen
                    while (nest > 0 || *ip != '[') { // zu passendem [ zurückspulen
                        if (*ip == '[') nest--; // Verschachtelung verlassen (oder Hauptschleife, bei der Verschachtelung > 0 fehlschlägt)
                        if (*ip == ']') nest++; // Verschachtelung betreten

                        ip--; // nach links bewegen
                    }
                    ip--; // vor der öffnenden Klammer bewegen
                }
                break;
        }

        ip++; // zu nächster Anweisung bewegen
    }

    free(cells);
    free(bf);
    return 0;
}

Beachten Sie, dass dieses Programm ohne Fehler kompiliert (gcc -Wall -std=c99 brainfuck.c) und sich zur Laufzeit normal verhält.

Hinweis: Wenn Sie sich durch den Namen Brainfuck beleidigt fühlen, leben Sie damit. Es ist eine Programmiersprache, die vom Autor so benannt wurde, und ich respektiere und verwende diesen Namen.

11voto

pmg Punkte 102904

Ist Splint C99-kompatibel?

Versuchen Sie /* ... */ anstelle von // ... und verschieben Sie Deklarationen vor jeglichem Code

0 Stimmen

OMG, ich wusste nie, dass einzelne Zeilenkommentare in c99 eingeführt wurden. Mein Compiler hat sich nie beschwert, auch ohne -std=c99. Leider behebt das nicht mein Problem.

0 Stimmen

Ich habe meinem Beitrag noch eine Sache aus C99 hinzugefügt (Deklarationen, die mit Code gemischt sind, sind auch neu)

0 Stimmen

@nightcracker: ziemlich viele Compiler akzeptierten // als Erweiterung, aber es war erst offizieller Bestandteil der Sprache bis C99.

2voto

EchoLynx Punkte 319

Sie können auch +slashslashcomment verwenden, wenn Sie splint aufrufen. In diesem Fall:

splint +slashslashcomment brainfuck.c


Splint-Handbuch Anhang B:

P:- slashslashcomment

Ein // Kommentar wird verwendet. ISO C99 erlaubt // Kommentare, aber frühere Standards nicht.

(würde dies in einem Kommentar platzieren, aber habe nicht genug Ruf)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X