2011-03-27 107 views
6

这是我第一次使用splint(来自Ubuntu的仓库),我立即被WTF击中。错误消息:splint调试解析错误

[email protected]:~/c/brainfuck$ splint brainfuck.c 
Splint 3.1.2 --- 03 May 2009 

brainfuck.c:17:6: Parse Error. (For help on parse errors, see splint -help 
       parseerrors.) 
*** Cannot continue. 

现在,显然它看到的东西错了第16行,第6列让我们检查出来(发布完整的代码):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

enum { 
    CELL_CHUNK_SIZE = 1024, 
}; 

typedef unsigned char cell; 

int main(int argc, char *argv[]) { 
    if (argc < 1) { 
     fprintf(stderr, "ERROR: Not enough arguments\n"); 
     return 1; 
    } 

    FILE *srcfile; // source file << THIS LINE APPARENTLY IS WRONG 
    long srclen; // source file size 
    char *bf; // brainfuck code file in memory 

    char *ip; // instruction pointer 
    cell *cells; // brainfuck cells 
    cell *newcells; // used for creating a new chunk of cells 
    cell *cp; // cell pointer 
    unsigned long numcells = CELL_CHUNK_SIZE; // amount of current cells 
    unsigned nest; // current nesting 
    int buf; // i/o buffer 

    srcfile = fopen(argv[1], "rb"); 
    if (srcfile == NULL) { 
     fprintf(stderr, "ERROR: Couldn't open source file\n"); 
     return 2; 
    } 

    // get source file length 
    fseek(srcfile, 0, SEEK_END); 
    srclen = ftell(srcfile); 
    fseek(srcfile, 0, SEEK_SET); 

    // allocate memory for source file 
    bf = malloc(srclen); 
    if (bf == NULL) { 
     fprintf(stderr, "ERROR: Couldn't allocate memory for source file\n"); 
     return 3; 
    } 

    // read source file in memory 
    if (srclen != fread(bf, sizeof(char), srclen, srcfile)) { 
     fprintf(stderr, "ERROR: Error while reading source file\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, "ERROR: Memory allocation failed\n"); 
     free(bf); 
     free(cells); 
     return 5; 
    } 

    cp = cells; // cell pointer initialized to most-left cell 
    ip = bf; // instruction pointer initialized to first character 
    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)); // allocate memory for new chunk 

        if (newcells == NULL) { 
         fprintf(stderr, "ERROR: Memory allocation failed\n"); 
         free(bf); 
         free(cells); 
         return 5; 
        } 

        cp = newcells + (cp - cells); // point cell pointer to cell in new chunk 
        cells = newcells; // point cells to new memory location (if altered) 
        memset(cp, 0, CELL_CHUNK_SIZE); // initialize new chunk 
        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++; // move past the opening bracket 
        while (nest > 0 || *ip != ']') { // skip to matching ] 
         if (*ip == '[') nest++; // enter nest 
         if (*ip == ']') nest--; // leave nest (or main loop, in which nesting > 0 fails) 

         ip++; // move right 
        } 

       } 
       break; 
      case ']': 
       if (*cp) { 
        ip--; // move before the closing bracket 
        while (nest > 0 || *ip != '[') { // rewind to matching [ 
         if (*ip == '[') nest--; // leave nest (or main loop, in which nesting > 0 fails) 
         if (*ip == ']') nest++; // enter nest 

         ip--; // move left 
        } 
        ip--; // move before the opening bracket 
       } 
       break; 
     } 

     ip++; // move to next instruction 
    } 


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

注意,这个程序编译没有错误( gcc -Wall -std=c99 brainfuck.c),运行时表现正常。

注意:如果您被名字brainfuck冒犯了,与它一起生活。这是一种由作者命名的编程语言,我尊重并使用该名称。

回答

11

夹板C99是否知道?

尝试/* ... */代替// ...和移动声明任何代码

+0

OMG我从来不知道单行注释是在C99推出。我的编译器从不抱怨,即使没有'-std = c99'。虽然可惜这不能解决我的问题。 – orlp 2011-03-27 01:55:05

+0

我在文章中添加了另外一个C99(与代码混合的声明也是新的) – pmg 2011-03-27 01:56:37

+0

@nightcracker:相当多的编译器接受'//'作为扩展名,但直到C99才正式成为语言的一部分。 – 2011-03-27 01:56:57

1

之前,您也可以致电夹板时使用+slashslashcomment。在这种情况下:

splint +slashslashcomment brainfuck.c


夹板手册的 Appendix B

P:- slashslashcomment

//注释使用。 ISO C99允许//评论,但早期的 标准没有。

(会把这一个评论,但不具备必要的REP)