Brauche Hilfe bei C++-Code



  • Hallo,

    bin leider der absolute noob und will folgende datei ausführen:

    leider weiß ich nicht was ich bei "config.filename" (Zeile 34) usw. eingeben soll, damit der compiler mal keine Fehler zeigt 😞

    ich habe einen programmcode in der Sprache Beatnik un dieser c++ code ist quasi der interpreter dafür. Leider scheitere ich bereits an der Ausführung dieses Interpreter weil ich ---> Programmiernoob 😞

    kann mir da jmd helfen, wie ich diesen c++-code-interpreter zum laufen bekomme

    Hier der Code:

    /*  Copyright (C) 2007 Rami R Chowdhury
        'Beatnik' interpreter, as specified by Cliff Biffle
        (see http://www.cliff.biffle.org/esoterica/beatnik.html)
    
        Licensed under the GNU General Public License, version 2.
    
        NB: A working 'Hello World' can be found not at Biffle's
        page but at http://zaaf.nl/emacs/HelloWorld.beatnik.html
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    // My own simple integer-based stack implementation
    #include "istack.h"
    
    typedef struct _configuration
    {   // Obviously, holds configuration values
        int stack_size;
        char* filename;
    } configuration;
    
    // Forward declaration of functions, for convenience and so main() can go up top
    unsigned char get_score(char* word);
    int           handle_cmdline(int argc, char** argv, configuration* config);
    char*         parse(char* source, unsigned long* len);
    int           execute(char* bytecode, unsigned long max_len, istack* stack);
    
    int main(int argc, char** argv)
    {   // First, set configuration defaults
        configuration config;
        config.stack_size = 128;
        config.filename = NULL;
    
        if(handle_cmdline(argc, argv, &config) == -1)
        { // Error handling command-line. Just die gracefully.
            return -1;
        }
    
        // Now try and get the source code file...
        FILE* f = fopen(config.filename, "");
        if(!f)
        {
            fprintf(stderr, "Error opening Beatnik file (%s)!\n", config.filename);
            return -1;
        }
        // Determine file size by seeking to the end and checking position, then resetting
        unsigned long fsize = 0;
        fseek(f, 0, SEEK_END);
        fsize = (unsigned long) ftell(f);
        fseek(f, 0, SEEK_SET);
        // Allocates some memory for the file contents, and initializes some variables to
        // help read it in
        char* source = calloc(fsize + 1, 1);
        char* src_ptr = source;
        unsigned long byte_count;
        while(!feof(f) && !ferror(f))
        {   // 4k at a time
            byte_count = fread(src_ptr, 1, 4096, f);
            src_ptr += byte_count;
        }
        // An error occured -- die
        if(ferror(f))
        {
            fprintf(stderr, "Error reading the file %s!\n", config.filename);
            fclose(f);
            return -1;
        }
        // Close file like a good program
        fclose(f);
        // Initialize program execution state (parse() returns bytecode and sets max_len to length of
        // bytecode). Also, free source as it's now redundant.
        unsigned long max_len;
        char* bytecode = parse(source, &max_len);
        istack* stack = stack_init(config.stack_size);
        free(source);
        // Go, go Beatnik rangers!
        int return_val = execute(bytecode, max_len, stack);
        // Cleanup
        stack_destroy(stack);
        free(bytecode);
        // If execute() returned nonzero, do that as well.
        return return_val;
    }
    
    int handle_cmdline(int argc, char** argv, configuration* config)
    {   // Parses command-line options with getopt() (POSIX). Returns -1 on error.
        char opt;
        opterr = 0; // Disable getopt() errors
    
        while ((opt = getopt(argc, argv, "f:s:h")) != -1)
        {
            switch(opt)
            {
                case 'f':
                    /* Explicit setting of the filename. Generally unnecessary... */
                    config->filename = optarg;
                    break;
                case 's':
                    /* Setting the initial stack size (it will grow as required) */
                    config->stack_size = strtol(optarg, (char**) NULL, 10);
                    if ((config->stack_size < 1) || (config->stack_size > 16384))
                    {
                        fprintf(stderr, "Invalid initial stack size specified (%d)! Value must be between 1 and 16384!\n", config->stack_size);
                        return -1;
                    }
                    break;
                case 'h':
                    /* Duh, help and usage */
                    printf("Beatnik programming language interpreter\n");
                    printf("Copyright (C) 2007 Rami Chowdhury\n");
                    printf("----------------------------------------\n");
                    printf("Executes programs written in the Beatnik language, as specified by\n");
                    printf("Cliff Biffle (http://www.cliff.biffle.org/esoterica/beatnik.html).\n");
                    printf("USAGE: %s [-OPTS] [-f] FILENAME\n", argv[0]);
                    printf("\n");
                    printf("Recognizes the following options:\n");
                    printf("  -h            Shows this help message.\n");
                    printf("  -s [number]   Sets the initial size of the 'stack' on which Beatnik\n");
                    printf("                performs arithmetic. Low values of this may mean the\n");
                    printf("                stack  has to be resized often, which is slow and in-\n");
                    printf("                efficient. High values can waste memory.\n");
                    printf("                Defaults to 128, and can range from 1 to 16384. \n");
                    printf("  -f [file]     Specifies the Beatnik source code file to execute.\n");
                    printf("                This is generally unnecessary as the first non-option\n");
                    printf("                argument is assumed to be a Beatnik program file.\n");
                    return -1;
                    break;
                default:
                    fprintf(stderr, "Unrecognized option (-%c). Please try %s -h for usage information.\n", optopt, argv[0]);
                    return -1;
                    break;
            }
        }
    
        if (config->filename == NULL)
        {   // We need a file to execute!
            if (argv[optind] != NULL)
            {
                config->filename = argv[optind];
            }
            else
            {
                fprintf(stderr, "No source code file specified!\n");
                return -1;
            }
        }
    
        return optind;
    }
    
    char* parse(char* source, unsigned long* len)
    {   // Tokenizes source and returns a pointer to memory filled with bytecode
        /* REMINDER: uses strtok() so mutates source! */
        // Initially allocates enough memory for all the source text
        char* buf = calloc(strlen(source) + 1, 1);
        char* buf_ptr = buf;
        // Delimiters for tokenizing are any punctuation characters
        const char* punct = "!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \n\t\r";
        char* word = strtok(source, punct);
        while(word != NULL)
        {   // Keeps going till we run out of tokens
            (*buf_ptr) = get_score(word); buf_ptr++;
            // printf("%s scored %d\n", word, *(buf_ptr - 1));
            word = strtok(NULL, punct);
        }
        // Now allocates a properly sized bytecode region, and copies it in
        unsigned long code_len = (unsigned long) (buf_ptr - buf);
        char* bytecode = calloc(code_len + 2, 1);
        strncpy(bytecode, buf, code_len);
        free(buf);
    
        (*len) = code_len;  // tells main() how long the bytecode is
        return bytecode;
    }
    
    unsigned char get_score(char* word)
    {   // For convenience, Scrabble data is hardcoded ;-)
        unsigned short tile_scores[] =
        {
            1,  // a
            3,  // b
            3,  // c
            2,  // d
            1,  // e
            4,  // f
            2,  // g
            4,  // h
            1,  // i
            8,  // j
            5,  // k
            1,  // l
            3,  // m
            1,  // n
            1,  // o
            3,  // p
            10, // q
            1,  // r
            1,  // s
            1,  // t
            1,  // u
            4,  // v
            4,  // w
            8,  // x
            4,  // y
            10  // z
        };
    
        // Now making use of the above...
        unsigned char word_score = 0;
        unsigned int wlen = strlen(word);
        char *w = word, *wmax = word + wlen, c = 0;
        while (w <= wmax)
        {
            c = (*w);
            if (c < 91)
            {   // Uppercase letters are ASCII 65-90, lowercase are 97-122 -- thus
                // ('a' - 'A') == 32, adding it turns everything to lowercase.
                c += 32;
            }
            if ((c > 96) && (c < 123))
            {   // It's a letter, so increment word_score by its score. Since
                // 'a' == 97, subtracting 97 makes c a valid index into tile_scores
                word_score += tile_scores[c - 97];
                // printf("\t%c scored %d, total = %d\n", c, tile_scores[c - 97], word_score);
            }
            w++;
        }
        return word_score;
    }
    
    int execute(char* bytecode, unsigned long max_len, istack* stack)
    {
        char* cur_byte = bytecode;
        char opcode = 0; int tmp1 = 0, tmp2 = 0;
        while((cur_byte - bytecode) <= max_len)
        {   // Keep going till we run out of opcodes. The 'stop' opcode will exit the function as well.
            opcode = *cur_byte;
            switch(opcode)
            {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    /* Does nothing. The Beatnik Interpreter may mock you for your poor scoring, at its discretion. */
                    if (rand() < 5)
                    {
                        fprintf(stderr, "Yeah, dude, %d's a *great* score... <rolls eyes>", opcode);
                    }
                    cur_byte++;
                    break;
                case 5:
                    /* Finds the score of the next word and pushes it onto the stack. Skips the aforementioned next word. */
                    stack_push(stack, *(cur_byte + 1));
                    cur_byte += 2;
                    break;
                case 6:
                    /* Pops the top number off the stack and discards it. */
                    stack_pop(stack);
                    cur_byte++;
                    break;
                case 7:
                    /* Adds the top two values on the stack together, pushing the result. */
                    tmp1 = stack_pop(stack); tmp2 = stack_pop(stack);
                    stack_push(stack, (tmp1 + tmp2));
                    cur_byte++;
                    break;
                case 8:
                    /* Input a character from the user and push its value on the stack. Waits for a keypress. */
                    printf("Type a character: ");
                    tmp1 = getchar();
                    stack_push(stack, tmp1);
                    cur_byte++;
                    break;
                case 9:
                    /* Pop a number off the stack and output the corresponding ASCII character to the screen.*/
                    tmp1 = stack_pop(stack);
                    putchar(tmp1);
                    cur_byte++;
                    break;
                case 10:
                    /* Subtract the top value on the stack from the next value on the stack, pushing the result.*/
                    tmp1 = stack_pop(stack); tmp2 = stack_pop(stack);
                    stack_push(stack, (tmp2 - tmp1));
                    cur_byte++;
                    break;
                case 11:
                    /* Swap the top two values on the stack.*/
                    tmp1 = stack_pop(stack); tmp2 = stack_pop(stack);
                    stack_push(stack, tmp1); stack_push(stack, tmp2);
                    cur_byte++;
                    break;
                case 12:
                    /* Pop a value of the stack, and push it twice.*/
                    tmp1 = stack_pop(stack);
                    stack_push(stack, tmp1); stack_push(stack, tmp1);
                    cur_byte++;
                    break;
                case 13:
                    /* Pop a number from the stack, and figure out the score of the next word. If the number from the stack is zero, skip ahead by [score-of-next-word] words. (The skipping is actually n+1 words, because the word scored is also skipped.)*/
                    if(stack_pop(stack) == 0)
                    {
                        cur_byte += *(cur_byte + 1);
                    }
                    cur_byte += 2;
                    break;
                case 14:
                    /* Same as above, except skip if the value on the stack isn't zero. */
                    if(stack_pop(stack) != 0)
                    {
                        cur_byte += *(cur_byte + 1);
                    }
                    cur_byte += 2;
                    break;
                case 15:
                    /* Skip back n words, if the value on the stack is zero. */
                    if(stack_pop(stack) == 0)
                    {
                        cur_byte -= *(cur_byte + 1);
                    }
                    cur_byte++;
                    break;
                case 16:
                    /* Skip back if it's not zero. */
                    if(stack_pop(stack) == 0)
                    {
                        cur_byte -= *(cur_byte + 1);
                    }
                    cur_byte++;
                    break;
                case 17:
                    /* Stop the program */
                    return 0;
                    break;
                case 18:
                case 19:
                case 20:
                case 21:
                case 22:
                case 23:
                    /* Does nothing. However, the score is high enough that the Beatnik Interpreter will not mock you, unless it's had a really bad day.*/
                    break;
                default:
                    /* Garners "Beatnik applause" for the programmer. This generally consists of reserved finger-snapping.*/
                    fprintf(stderr, "Wow <snap> I'm impressed <snap>\n");
                    cur_byte++;
                    break;
            }
            // printf("Opcode %d, ", opcode);
            // stack_print(stack);
        }
        return 0;
    }
    


  • Das ist kein C++, dis ist pures C.



  • HighLigerBiMBam schrieb:

    Das ist kein C++, dis ist pures C.

    Dann würde der Code nicht kompilieren ;P



  • theliquidwave schrieb:

    HighLigerBiMBam schrieb:

    Das ist kein C++, dis ist pures C.

    Dann würde der Code nicht kompilieren ;P

    Scheint er ja auch nicht zu tun. Aber ohne konkrete Fehlermeldung kann man es nicht so genau sagen ...


  • Mod

    Vor allem musst du erst einmal einen C Compiler benutzen, da werden Sachen gemacht die in C++ illegal sind.

    In Zeile 34 sehe ich auch nichts falsches. NULL ist ein Standardmakro aus string.h. Das MUSS auf einem standardkonformen Compiler funktionieren. Du kannst versuchen es durch 0 zu ersetzen, wenn es tatsächlich nicht funktionieren sollte.



  • @Sep Welches Programm muss ich nehmen?

    Habe jetzt codeblocks genommen und der Fehler sieht so aus:

    Compiling: C:\Users\Vale\Desktop\beatnik\beatnik.c
    C:\Users\Vale\Desktop\beatnik\beatnik.c:34:23: warning: unknown escape sequence '\C'
    Linking console executable: C:\Users\Vale\Desktop\beatnik\beatnik.exe
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x1be): undefined reference to stack_init' C:\\Users\\Vale\\Desktop\\beatnik\\beatnik.o:beatnik.c:(.text+0x1fa): undefined reference tostack_destroy'
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x645): undefined reference to stack_push' C:\\Users\\Vale\\Desktop\\beatnik\\beatnik.o:beatnik.c:(.text+0x659): undefined reference tostack_pop'
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x66c): undefined reference to stack_pop' C:\\Users\\Vale\\Desktop\\beatnik\\beatnik.o:beatnik.c:(.text+0x67a): undefined reference tostack_pop'
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x695): undefined reference to `stack_push'

    collect2: ld returned 1 exit status
    Process terminated with status 1 (0 minutes, 1 seconds)
    23 errors, 1 warnings

    kann leider nicht alle Fehler posten, da das forum immer heult "max. 10 smilies sind erlaubt..."


  • Mod

    Zeile 34 ist kein echter Fehler, da hast du irgendein verrücktes Zeichen stehen, welches hier im Forum nicht auftaucht.

    Der Rest sind Linkerfehler. Da fehlt offensichtlich eine Bibliothek.



  • lolhonk schrieb:

    C:\Users\Vale\Desktop\beatnik\beatnik.c:34:23: warning: unknown escape sequence '\C'

    Das ist "nur" eine Warnung. An der Stelle steht wohl irgend ein Schrott. Probier mal, die Zeile neu einzugeben.

    lolhonk schrieb:

    Linking console executable: C:\Users\Vale\Desktop\beatnik\beatnik.exe
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x1be): undefined reference to stack_init' C:\\Users\\Vale\\Desktop\\beatnik\\beatnik.o:beatnik.c:(.text+0x1fa): undefined reference tostack_destroy'
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x645): undefined reference to stack_push' C:\\Users\\Vale\\Desktop\\beatnik\\beatnik.o:beatnik.c:(.text+0x659): undefined reference tostack_pop'
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x66c): undefined reference to stack_pop' C:\\Users\\Vale\\Desktop\\beatnik\\beatnik.o:beatnik.c:(.text+0x67a): undefined reference tostack_pop'
    C:\Users\Vale\Desktop\beatnik\beatnik.o:beatnik.c:(.text+0x695): undefined reference to `stack_push'

    Da fehlt offensichtlich mindestens eine weitere Datei (istack.c?), die die Stackimplementierung enthält.


  • Mod

    Super jetzt hast du genau die gleiche Antwort erhalten, wie in dem anderen Thread den du zu dem Thema aufgemacht hast. Unterlasse es, die gleiche Frage mehrmals zu stellen.


Anmelden zum Antworten