Fehler bei Strukturen



  • Hi,

    versuch mal das hier. Es sollte funktionieren, habe es aber nicht getestet.

    enum ExpressionType { 
        AND,
        OR,
        NOT,
        TERM,
        UNARY_TERM,
        BINARY_TERM,
        TERNARY_TERM
    };
    
    typedef union  expression      Expression;
    typedef struct andexpression   AndExpression;
    typedef struct orexpression    OrExpression;
    typedef struct unaryexpression UnaryExpression;
    
    union expression {
        AndExpression   and;
        OrExpression    or;
        UnaryExpression not;
        TermExpression  term;
    };
    
    struct andexpression{
        ExpressionType type;
        Expression left;
        Expression right;
    };
    
    struct orexpression {
        ExpressionType type;
        Expression left;
        Expression right;
    };
    
    struct unaryexpression {
        ExpressionType type;
        UnaryOperator op;
        Expression exp;
    };
    

    Gruß mcr



  • Auch das hier sollte klappen:

    enum ExpressionType { 
        AND,
        OR,
        NOT,
        TERM,
        UNARY_TERM,
        BINARY_TERM,
        TERNARY_TERM
    };
    
    typedef union expression Expression;
    
    typedef struct {
        ExpressionType type;
        Expression     left;
        Expression     right;
    } AndExpression;
    
    typedef struct{
        ExpressionType type;
        Expression     left;
        Expression     right;
    } OrExpression;
    
    typedef struct{
        ExpressionType type;
        UnaryOperator  op;
        Expression     exp;
    } UnaryExpression;
    
    union expression {
        AndExpression   and;
        OrExpression    or;
        UnaryExpression not;
        TermExpression  term;
    };
    

    Bis auf die Tatsache, dass UnaryOperator und TermExpression nicht definiert
    sind. Aber das ist im vorigen Post auch der Fall. 🙂

    Gruß mcr



  • And, or und not sind (wie einige andere) reserviert und dürfen daher nicht für eigene Bezeichner verwendet werden.

    Das Syntaxhighlighting des Forums zeigt das übrigens auch.



  • hallo zusammen,

    also leider geht das so auch nicht. nun bekomme ich folgende fehler:

    In file included from newmain.c:11:
    DSMQL.h:150: error: syntax error before "ExpressionType"
    DSMQL.h:150: warning: no semicolon at end of struct or union
    DSMQL.h:153: error: syntax error before '}' token
    DSMQL.h:153: warning: data definition has no type or storage class
    DSMQL.h:156: error: syntax error before "ExpressionType"
    DSMQL.h:156: warning: no semicolon at end of struct or union
    DSMQL.h:159: error: syntax error before '}' token
    DSMQL.h:159: warning: data definition has no type or storage class
    DSMQL.h:162: error: syntax error before "ExpressionType"
    DSMQL.h:162: warning: no semicolon at end of struct or union
    DSMQL.h:163: warning: data definition has no type or storage class
    DSMQL.h:164: warning: built-in function 'exp' declared as non-function
    DSMQL.h:165: error: syntax error before '}' token
    DSMQL.h:165: warning: data definition has no type or storage class
    DSMQL.h:168: error: syntax error before "AndExpression"
    DSMQL.h:168: warning: no semicolon at end of struct or union
    DSMQL.h:169: warning: data definition has no type or storage class
    DSMQL.h:170: error: syntax error before "not"
    DSMQL.h:170: warning: data definition has no type or storage class
    DSMQL.h:171: error: syntax error before "term"
    DSMQL.h:171: warning: data definition has no type or storage class
    In file included from newmain.c:12:
    D:/Programme/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/math.h:153:
    error: 'exp' redeclared as different kind of symbol
    DSMQL.h:164: error: previous declaration of 'exp' was here
    DSMQL.h:157: error: storage size of `left' isn't known
    DSMQL.h:158: error: storage size of `right' isn't known
    DSMQL.h:164: error: storage size of `exp' isn't known
    

    Jemand noch einen Tip? Oder einen alternative Idee wie man solch einen Ansatz in C verwirklichen könnte?

    Danke schon mal.



  • Mist, da habe ich doch noch einen Fehler übersehen:

    typedef enum { 
        AND,
        OR,
        NOT,
        TERM,
        UNARY_TERM,
        BINARY_TERM,
        TERNARY_TERM
    } ExpressionType;
    

    Gruß mcr

    PS: beim nächsten Fehler gib uns mal ein komplett kompilier-fähiges
    Beispiel. So kann man dir nicht wirklich weiterhelfen.



  • Hi,

    erst mal danke für deine Hilfe. Wie meinst du das? Was brauchst du?
    Also ich will eine Art Baum aufbauen, welcher Ausdrücke enthält.
    Also gegeben sei: A < 2 AND B > 5, daraus will ich machen:

    Expression:
       type = AND_EX,
       left = TermExpression,
              var = A,
              operation = <,
              value = 2
       right = TermExpression,
              var = B,
              operation = >,
              value = 5
    

    Reicht das?



  • uwerothfeld schrieb:

    Hi,

    erst mal danke für deine Hilfe. Wie meinst du das? Was brauchst du?
    Also ich will eine Art Baum aufbauen, welcher Ausdrücke enthält.
    Also gegeben sei: A < 2 AND B > 5, daraus will ich machen:

    Expression:
       type = AND_EX,
       left = TermExpression,
              var = A,
              operation = <,
              value = 2
       right = TermExpression,
              var = B,
              operation = >,
              value = 5
    

    Reicht das?

    Nein, schick mal deinen kompletten Code!

    Gruß mcr

    PS: falls es zu viel ist, dann benutz z.B. filehosting.at.
    Dort kannst du eine Datei (z.b. alle deine Dateien gepackt)
    uploaden, dann bekommst du einen Link, den du hier posten
    kannst.



  • Hallo zusammen,

    also ich habe mal es etwas eingekürzt und ich denke man sollte verstehen wie ich es meine. Der Code ist compilerfähig, mal abgesehen von dem Struktur Problem. Ich habe ein GET, welches einen codierten Ausdruck enthält, diesen will ich in eine Baumrepräsentation umwandeln. Achso, was ich noch sagen sollte, malloc und Co sind auf der Zielplattform nicht anwendbar.

    Die SAMPLE.h

    #ifndef SAMPLE_H
    #define SAMPLE_H
    
    enum ops{
      //simple requests
      GET = 1,
      SET = 2,
      UPDATE = 3,
    
      //simple replies
      ANSWER = 4,
      SACK = 5,
      UACK = 6,
    
      // number that added to a request type causes it to become a reply type
      REPDIFF = 3, 
    };
    
    enum bool{
      false = 0,
      true,
    };
    
    // DEBUG ONLY
    typedef unsigned char uint8_t;
    typedef unsigned short uint16_t;
    typedef unsigned int uint32_t;
    typedef unsigned long int uint64_t;
    typedef unsigned char addr_t;
    typedef unsigned char error_t;
    
    //here the type for timestamp/version is defined
    typedef uint32_t ts_t;
    
    //here the type to represent the variable id
    typedef uint8_t var_id_t;
    
    //here the type to represent the request number
    typedef uint8_t reqno_t;
    
    typedef enum { 
        AND_EX, 
        OR_EX, 
        NOT_EX, 
        TERM, 
        UNARY_TERM, 
        BINARY_TERM, 
        TERNARY_TERM 
    } ExpressionType;
    
    typedef struct {
    
        ExpressionType type;
        int varid;
        int operator;
        int value1;
        int value2;
    
    } termexpression;
    
    typedef struct{ 
    
        ExpressionType type; 
        Expression     left; 
        Expression     right; 
    
    } andexpression;
    
    typedef termexpression  TermExpression;
    typedef andexpression      Expression;
    
    typedef union {
    
        TermExpression term;
        AndExpression  andEx;
    
    } Expression;
    
    #endif /*SAMPLE_H */
    

    Die test.c Datei:

    #include <stdio.h>
    #include <stdlib.h>
    
    #include "SAMPLE.h"
    
    enum{
        SUCCESS,
        ERROR
    };
    
    int get_num(char** pi, unsigned char* pos, char n ){
    
        short   res = 0;
        int     bitcnt = n;
        char    bitIndex;
        int     resindex = n-1;
        int     byte_number = *pos/8;
    
        bitIndex = 7 - (*pos-(8*byte_number));
    
        if( n >  sizeof(int)*8 ){
            return -1;
        }//End if
    
        while(bitcnt>0){
    
            if(*(*pi+byte_number) & (1<<bitIndex)){
                res |= (1 << resindex);
            }//End if
    
            bitIndex--;
            bitcnt--;
            resindex--;
    
            if(bitIndex == -1){
                bitIndex=7;
                byte_number++;
            }//End if
        }//End while
    
        *pos+=n;
    
        return res;
    }//End get_num
    
    Expression createExpression(uint8_t* data, uint8_t* pos,ExpressionType type){
    
        if(type != TERM){
    
            Expression ex;
            int nextType;
            ex.type = type;
    
            nextType = get_num((char**)&data,pos,2);
    
            switch (nextType){
    
            case 0: 
                ex.left = createExpression(data, pos, AND_EX);
                break;
            case 1:
                ex.left = createExpression(data, pos, OR_EX);
                break;
            case 2:
                ex.left = createExpression(data, pos, NOT_EX);
                break;
            case 3:
                ex.left = createExpression(data, pos, TERM);
                break;
    
            }//End switch
    
            nextType = get_num((char**)&data,pos,2);
    
            switch (nextType){
    
            case 0: 
                ex.right = createExpression(data, pos, AND_EX);
                break;
            case 1:
                ex.right = createExpression(data, pos, OR_EX);
                break;
            case 2:
                ex.right = createExpression(data, pos, NOT_EX);
                break;
            case 3:
                ex.right = createExpression(data, pos, TERM);
                break;
    
            }//End switch
    
            return ex;
    
        }//End if
        //Term expression, holds a UNARY,BINARY or TERNARY OPERATION
        else{
    
            TermExpression term;
            term.type = get_num((char**)&data, pos, 2);
            term.varid = get_num((char**)&data, pos, 3);
            term.operator = get_num((char**)&data, pos, 4);
    
            if(term.type == BINARY_TERM || term.type == TERNARY_TERM){
    
                term.value1 = get_num((char**)&data, pos, 8);
    
            }//End if
            if(term.type == TERNARY_TERM){
    
                term.value2 = get_num((char**)&data, pos, 8);
            }//End if
    
            return term;
    
        }//End else
    
    }//End createAnd
    
    void handleGet(uint8_t* data, uint8_t dataLenght){
    
        //GET ID, TEMP WHERE HUM > 4 AND HUM != 6
        //010 - two variables
        //000 - id var
        //010 - temp var
        //011 - 3 Knoten in Where
        //00  - AND Expression
        //11  - Term
        //01  - Binary Term 
        //011 - HUM
        //0000 - >
        //00000100 - 4
        //11  - Term
        //01  - Binary Term
        //011 - HUM
        //0101 - !=
        //00000110 - 6
    
        int i;
        uint8_t pos = 0;
        uint8_t getSize = get_num((char**)&data, &pos, 8);
        uint8_t getVars[getSize];
        Expression ex;
    
        //recreate the query
        for(i=0;i<getSize;i++){
    
            getVars[i]= get_num((char**)&data,&pos,8);
    
        }//End for
    
        switch (get_num((char**)&data,&pos, 2)){
    
            case 0: 
                ex = createExpression(data, &pos, AND_EX);
                break;
            case 1:
                ex = createExpression(data, &pos, OR_EX);
                break;
            case 2:
                ex = createExpression(data, &pos, NOT_EX);
                break;
            case 3:
                ex = createExpression(data, &pos, TERM);
                break;
        }//End switch
    
        //do more stuff ...
    
        //int get_num(char** pi, unsigned char* pos, char n ){
    
    }//End decode
    
    /*
     *
     */
    int main(int argc, char** argv) {
    
        uint8_t get[7] = {65, 51, 88, 2, 107, 80, 96 };
    
        handleGet(&get[0],7*8);
    
        return (EXIT_SUCCESS);
    }//End main
    

    Also Fehler bekomme ich:

    In file included from test.c:6:
    SAMPLE.h:69: error: syntax error before "Expression"
    SAMPLE.h:69: warning: no semicolon at end of struct or union
    SAMPLE.h:70: warning: data definition has no type or storage class
    SAMPLE.h:72: warning: data definition has no type or storage class
    SAMPLE.h:76: error: syntax error before "Expression"
    SAMPLE.h:76: warning: data definition has no type or storage class
    SAMPLE.h:81: error: syntax error before "AndExpression"
    SAMPLE.h:81: warning: no semicolon at end of struct or union
    SAMPLE.h:83: warning: data definition has no type or storage class
    test.c:51: error: syntax error before "createExpression"
    test.c: In function `createExpression':
    test.c:55: error: syntax error before "ex"
    test.c:57: error: `ex' undeclared (first use in this function)
    test.c:57: error: (Each undeclared identifier is reported only once
    test.c:57: error: for each function it appears in.)
    test.c:118: error: incompatible types in return
    test.c: In function `handleGet':
    test.c:148: error: syntax error before "ex"
    test.c:161: error: `ex' undeclared (first use in this function)
    

    Ich danke euch schon vielmals 🙂



  • Ich habe mir deinen Code mal angesehen und habe einige Fehler gefunden.

    Ich bin mir nicht so sicher, was get_num() eigentlich machen soll. Aber mal
    abgesehen davon:
    Der Kompiler kann die Größe von AndExpression nicht korrekt ermitteln,
    da sich die Struktur selbst enthält. An dieser Stelle müßtest du dann
    mit Pointer, malloc und free arbeiten.

    Ein weiteres Problem ist:
    In deinem Beispiel übergibst du der handleGet()-Funktion ein Array,
    was aus 7 8-bit worten besteht und die dataLength von 7*8=56.
    Anschließend bestimmst du getSize = get_num(data, 0, 8), welches dir
    das erste Element von get[] zurückgibt: 65
    Anschließend entnimmst du deinem Array get 65 Element der Größe 8bit.
    Aber so viele hast du nicht mehr!

    Ein weiteres Problem ist:
    getSize ist eine Variable, die nicht zur Kompilierzeit bekannt ist.
    uint8_t getVars[getSize]; ist erst ab C99 erlaubt. Hier solltest du
    besser mit malloc() arbeiten.

    Ich könnte dir noch weitere Fehler aufzählen.

    Vielleicht beschreibst du mal mit einem ausführlichen Beispiel, was
    du programmieren möchtest.
    Ich glaube, dein Ansatz ist nicht gerade der beste.

    Gruß mcr

    EDIT: ich habe überlesen, dass du malloc und Co nicht verwenden darfst.
    Hm, da muss man sich dann was anderes einfallen lassen. Was, weiß ich
    ich noch nicht. Ich warte erst mal auf dein Beispiel.



  • Hallo,

    erst mal danke für die Hilfe. Zum einen muß ich sagen, da hat sich beim extrahieren aus meinem Gesamtcode ein Fehler ergeben, der Codeabschnitt muß wie folgt aussehen:

    int i;
        uint8_t pos = 0;
        uint8_t getSize = get_num((char**)&data, &pos, 3);
        uint8_t getVars[getSize];
        Expression ex;
    
        //recreate the query
        for(i=0;i<getSize;i++){
    
            getVars[i]= get_num((char**)&data,&pos,3);
    
        }//End for
    

    So nun zu den Details:

    Zunächst erst einmal das Beispiel. Es wird bei einem Sender eine Anfrage generiert. Diese wird in eine Bit Repräsentation gebracht und zum Empfänger gesendet. Dieser muß nun diese wieder zurückwandeln in die ursprüngliche Anfrage. Dazu wird die Expression Struktur benötigt und die Funktion get_num.

    Die Funktion get_num bekommt einen Strom von Bits, von welchem es dann ab einer bestimmten Position eine bestimmte Anzahl an Bits abschneidet. Oben drei bits, aus dem ersten Feld von data, da data[0] = 65, heißt ist es in Bit: 01000001, davon die ersten drei sind 010, was wiederum 2 ist. Dies enstpricht der in der Anzahl in der Anfrage codierten Variablen. Darauf werden die ids für die Variablen ausgelesen und in eine int Repräsentation gewandelt. Eine Variable ist ebenfalls mit drei Bit codiert. Dies dazu. Von daher stimmt das schon, mal abgesehen davon das es 3 bit und nicht 8 heißen muß.

    Der Ansatz ist notwendig, da nur wenig versendet werden kann und das Zielsystem wie gesagt keine dynamische Speicherverwaltung unterstützt. Nun ist halt die Frage wie bekomme ich das Composit Pattern in C abgebildet, bzw. hat jemand eine Alternatividee? C99 ist ok.

    Was noch für Fehler?

    Vielen Dank.



  • Ok, so langsam habe ich es verstanden.

    Vielleicht baust du dir dazu keinen Baum auf, sondern versuchst mal mit
    Hilfe der "polnische Notation" einen Stack aufzubauen.

    Z.B.

    (HUM > 4) AND (HUM != 6)
    

    hat drei Elemente. Also:

    Expression stack[num];  //num = 3
    
    stack[0] = Op:   AND
    stack[1] = Term: (HUM != 6)
    stack[2] = Term: (HUM > 4)
    

    D.h. Wenn du an Stelle 0 nun den Operator AND findest, weißt du, dass das
    Ergebnis der nächsten zwei Elemente zusammengehören.

    So kannst du dann auch z.B.

    (a > 1) AND ((b = 0) OR (b = 1))
    

    realisieren.

    stack[0] = Op:   AND
    stack[1] = Term: (a > 1)
    stack[2] = Op:   OR
    stack[3] = Term: (b = 0)
    stack[4] = Term: (b = 1)
    

    Hierbei ist das zweite Elemente (gesehen vom stack[0]) eine weitere
    Verzweigung.

    Somit brauchst du in dem Typ AndExpression nicht den Typ
    Expression, da dies durch den Stack realisiert wird.

    Ich hoffe, dies hilft dir weiter.

    Hier vielleicht noch ein wenig Codesäuberung:

    int get_num(uint8_t *pi, int* pos, unsigned int n ){
        int     res    = 0;
        int     bitcnt = n;
        int     bitIndex;
        int     resindex    = n-1;
        int     byte_number = *pos/8;
    
        bitIndex = 7 - (*pos-(8*byte_number));
    
        if ( n >  sizeof(int)*8 ) {
            return -1;
        }
    
        while (bitcnt>0) {
            if (pi[byte_number] & (1<<bitIndex)){
                res |= (1 << resindex);
            }
            bitIndex--;
            bitcnt--;
            resindex--;
    
            if(bitIndex == -1){
                bitIndex=7;
                byte_number++;
            }
        }
        *pos+=n;
        return res;
    }
    
    void handleGet(uint8_t* data, int dataLength){
        int i;
        int pos = 0;
        uint8_t getSize = get_num(data, &pos, 3);
        uint8_t getVars[getSize];
    
        printf("Datenstrom: ");
        for (int j=0; j<dataLength;) printf(" %x ", get_num(data, &j, 4));
    
        printf("\n");
        printf("getSize: %d\n", getSize);
    
        /*recreate the query */
        for(i=0;i<getSize;i++){
            getVars[i]= get_num(data,&pos,3);
        }
    
        for (i=0; i<getSize;++i) printf(" %d ", getVars[i]);
    
        // Bis hierhin erstmal ein wenig Debug-Code.
        // ...
    }
    
    int main(void) {
        uint8_t get[7] = {65, 51, 88, 2, 107, 80, 96 };
    
        for (int i=0; i<7; ++i) printf(" %x ", get[i]);
        printf("\n");
    
        handleGet(get, 7*8);
        printf("\n");
    
        return (EXIT_SUCCESS);
    }
    


  • Hi,

    erst einmal vielen Dank für deine Hilfe. Nun werde ich es halt mit dem Stack machen. Wollte es eigentlich nicht, dachte es muß im hochgepriesenen C doch ne Möglichkeit geben, soetwas zu machen, aber ohne malloc hat man da wohl schlechte Karten. Dann halt mit Stack. Noch ne Frage neben bei, was hast du an meinen Code geändert? Sehe keinen wirklichen unterschied.

    Vielen Dank.

    Gruß uwe



  • Schau dir mal die Parameterlisten der Funktionen an.

    Gruß mcr



  • ah alles klar. Vielen Dank für deine Hilfe.

    🙂


Anmelden zum Antworten