#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    8
    Rep Power
    0

    Struct Pointer Segmentation Fault


    Code:
    #ifndef _COMPILER_H_
    #define _COMPILER_H_
     
     
    /*
     * compiler.h
     * 
     */
      
    #define TRUE 1
    #define FALSE 0
     
     
    #define NOOPSTMT    100
    #define PRINTSTMT    101
    #define ASSIGNSTMT    102
    #define IFSTMT        103        // This is used for all control statements (if, while, repeat)
    #define GOTOSTMT    104
     
     
    #define KEYWORDS    7
    #define RESERVED    27
    #define VAR            1
    #define IF            2
    #define WHILE        3 
    #define REPEAT        4
    #define UNTIL         5
    #define PRINT         6
    #define ARRAY         7
    #define PLUS         8
    #define MINUS         9
    #define DIV         10
    #define MULT         11
    #define EQUAL         12
    #define COLON         13
    #define COMMA         14
    #define SEMICOLON     15
    #define LBRAC         16
    #define RBRAC         17
    #define LPAREN         18
    #define RPAREN         19
    #define LBRACE         20
    #define RBRACE         21
    #define NOTEQUAL     22
    #define GREATER     23
    #define LESS         24
    #define ID             25
    #define NUM         26
    #define ERROR         27
     
     
    // This implementation does not allow tokens that are more
    // than 100 characters long
    #define MAX_TOKEN_LENGTH 100
     
     
    // The following global variables are defined in compiler.c:
    extern char token[MAX_TOKEN_LENGTH];
    extern int  ttype ;
     
     
    //---------------------------------------------------------
    // Data structures:
     
     
    struct varNode
    {
        char* name;
        int   value;
    };
     
     
    struct gotoStatement
    {
        struct statementNode * target;
    };
     
     
    struct assignmentStatement
    {
        struct varNode * lhs;
        struct varNode * op1;
        struct varNode * op2;
        int op;        // PLUS, MINUS, MULT, DIV --> lhs = op1 op op2;
                    // 0                      --> lhs = op1;
    };
     
     
    struct printStatement
    {
        struct varNode * id;
    };
     
     
    struct ifStatement
    {
        struct varNode * op1;
        struct varNode * op2;
        int relop;    // GREATER, LESS, NOTEQUAL
        struct statementNode * true_branch;
        struct statementNode * false_branch;
    };
     
     
    struct statementNode
    {
        int stmt_type;        // NOOPSTMT, PRINTSTMT, ASSIGNSTMT, IFSTMT, GOTOSTMT
        struct assignmentStatement * assign_stmt;    // NOT NULL iff stmt_type == ASSIGNSTMT
        struct printStatement      * print_stmt;    // NOT NULL iff stmt_type == PRINTSTMT
        struct ifStatement         * if_stmt;        // NOT NULL iff stmt_type == IFSTMT
        struct gotoStatement       * goto_stmt;        // NOT NULL iff stmt_type == GOTOSTMT
        struct statementNode       * next;            // next statement in the list or NULL 
    };
     
     
    //---------------------------------------------------------
    // Functions that are provided:
     
     
    void print_debug(const char * format, ...);
    void ungetToken();
    int  getToken();
     
     
    /*
     * You need to write a function with the signature that follows this comment. 
     * It is supposed to parse the input program and generate an intermediate 
     * representation for it. Write all your code in a separate file and include 
     * this header file.
     
     
     */
    struct ifStatement * relop();
    struct statementNode * parse_program_and_generate_intermediate_representation();
     
     
     
     
    #endif /* _COMPILER_H_ */
    ///////////////////////////////////////parse_graph.c follows
     
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "compiler.h"
    struct ifStatement* relop()
        {
        struct ifStatement* relo;
        ttype = getToken();
        if (ttype == GREATER)
            { 
            relo = malloc(sizeof(struct ifStatement));
            relo->relop = GREATER;
            relo->op1 = malloc(sizeof(struct varNode));
            relo->op2 = malloc(sizeof(struct varNode)); 
            relo->true_branch = malloc(sizeof(struct statementNode));
            relo->false_branch = malloc(sizeof(struct statementNode));
            relo->true_branch = NULL;
            relo->false_branch = NULL;
            return relo;
            }else
        if (ttype == LESS)
            {
            relo = malloc(sizeof(struct ifStatement));
            relo->relop = LESS;
            relo->op1 = malloc(sizeof(struct varNode));
            relo->op2 = malloc(sizeof(struct varNode)); 
            relo->true_branch = malloc(sizeof(struct statementNode));
            relo->false_branch = malloc(sizeof(struct statementNode));
            relo->true_branch = NULL;
            relo->false_branch = NULL;
            return relo;
            }else
        if (ttype == NOTEQUAL)
            {
            relo = malloc(sizeof(struct ifStatement));
            relo->relop = NOTEQUAL;
            relo->op1 = malloc(sizeof(struct varNode));
            relo->op2 = malloc(sizeof(struct varNode)); 
            relo->true_branch = malloc(sizeof(struct statementNode));
            relo->false_branch = malloc(sizeof(struct statementNode));
            relo->true_branch = NULL;
            relo->false_branch = NULL;
            return relo;
     
     
            }
         
          
        }
    struct varNode * primary()
        { 
        struct varNode *primar;
        ttype = getToken();
        if (ttype == NUM)
            {
            primar = malloc(sizeof(struct varNode));
            primar->value = atoi(token);
            return primar;
            }
        if (ttype == ID)
            {
            primar = malloc(sizeof(struct varNode));
            primar->name;
            return primar;
            }
     
     
          
        }
    struct assignmentStatement * oper()
        {
        struct assignmentStatement * opp;
        ttype = getToken();
        if (ttype == PLUS)
            {
            opp = malloc(sizeof(struct assignmentStatement));
            opp->op = PLUS;
            }
        if (ttype == MINUS)
            {
            opp = malloc(sizeof(struct assignmentStatement));
            opp->op = MINUS;
            }
        if (ttype == MULT)
            {
            opp = malloc(sizeof(struct assignmentStatement));
            opp->op = MULT;
            }
        if (ttype == DIV)
            {
            opp = malloc(sizeof(struct assignmentStatement));
            opp->op = DIV;
            }
        }
    struct ifStatement * condition ()
        {
        struct ifStatement *cond;
         
        ttype = getToken();
        if(ttype == NUM | ttype == ID)
            {
            //printf("1");
            ungetToken();
            cond = malloc(sizeof(struct ifStatement));
            cond->op1 = primary();
            //cond->op1->value;
            ttype = getToken();
            if ( ttype == GREATER | ttype == LESS | ttype == NOTEQUAL )
                {
                ungetToken();
                cond = relop();
                cond->relop;
                //printf("%d",cond->relop);
                ttype = getToken();
                if(ttype == NUM | ttype == ID)
                    {
                    ungetToken();
                    cond->op2 = primary();
                    //cond->op2->value);
                    return cond;
                    }
                }
             
            }
        }
    struct assignmentStatement * expr()
        {
        struct assignmentStatement * expr;
        ttype = getToken();
        if(ttype == NUM | ttype == ID)
            {
            ungetToken();
            expr = malloc(sizeof(struct assignmentStatement));
            //expr->lhs = NULL;
            expr->op1 = primary();
            //expr->op1->value; 
            //printf("%d",expr->op1->value);
            ttype = getToken();
            if (ttype == PLUS | ttype == MINUS | ttype == MULT | ttype == DIV)
                {
                ungetToken();
                expr = oper();
                //printf("%d", ttype);
                ttype = getToken();
                if(ttype == NUM | ttype == ID)
                    {
                    ungetToken();
                    expr->op2 = primary();
                    //printf("%d",expr->op2->value);
                    }
     
     
                }
            }
        }
    struct assignmentStatement * assign_stmt()
        {
        struct assignmentStatement * assign;
        ttype = getToken();
        if (ttype == ID)
            {
             
            assign = malloc(sizeof(struct assignmentStatement));
            assign->lhs->name;
            printf("%d\t", ttype);
            ttype = getToken();
            if (ttype == EQUAL)
                {printf("%d\t", ttype);
                ttype = getToken();
                if (ttype == NUM | ttype == ID)
                    {//printf("%d\t", ttype);
                    ungetToken();
                    assign =expr();
                    printf("%d", assign->op1->value);
                    /*if(ttype == SEMICOLON)
                        {
                        ungetToken();
                        assign->op1 = primary();
                        printf("%d", assign->op1->value);return assign;
                        }
                    //assign = expr();
                    //printf("%d", assign->op1->value);
                    if (ttype == PLUS | ttype == MINUS | ttype == MULT | ttype == DIV)
                        {printf("%d\t", ttype);
                        //ttype = getToken();
                        printf("%d\t", ttype);
                        ungetToken();
                        ungetToken();
                        printf("%d\t", ttype);
     
     
                        assign = expr();
                        //assign->op1->value;
                        //printf("%d", assign->op1->value);
                        return assign;
                        }else { return assign;}*/
                    }
                 
                }
            }
        }
    So for a project I am writing a compiler for a simple lang assuming there are no
    lexical or semantic errors. My problem is when i test assign_stmt() in main on say
    a = 4 + 4, the Id and the equal are parsed,but when i call assign = expr(); to parse the 4+4, i get a seg fault if i call printf(assign->op1->value); i cant figure out why this is occurring because if just call expr(); in main on 4+4 printf(exp->op1->value); then i receive the right answer, a 4. ANY HELP APPRECIATED


    also getToken receives the next token in the list and ungetToken puts it back
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    8
    Rep Power
    0
    Thats not very helpful
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by gatar
    Thats not very helpful
    Nor is your cross-posting, which causes duplication of effort on our part and prevents any kind of teamwork among us to solve your problem. As well as keeping us from knowing whether the problem has already been solved, completely wasting our own time and effort. Plus, you will be ignoring what we offer, against completely wasting our own time and effort.

    Besides, cross-posting is extremely rude. Same to you, buddy!

    And since you have others working on this for you, we don't need to do anything.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    8
    Rep Power
    0
    I'm posting on forums that are not related and not guaranteed to have the same user base. Ie it is possible that someone different would see the post on another forum. And I don't see why you would assume that just because it is posted somewhere else that I would ignore and not look into a response.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    8
    Rep Power
    0
    And thank you for coming here to complain about my post rather than contribute to the problem posted in anyway.
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    You need to split your separate files into separate code listings.

    Why are you ignoring warnings? Here is what I get when I compile your code (MinGW gcc on Win7):
    C:\otros\dcw>gcc -Wall gatar01.c
    gatar01.c: In function `relop':
    gatar01.c:51: warning: control reaches end of non-void function
    gatar01.c: In function `primary':
    gatar01.c:65: warning: statement with no effect
    gatar01.c:71: warning: control reaches end of non-void function
    gatar01.c: In function `oper':
    gatar01.c:96: warning: control reaches end of non-void function
    gatar01.c: In function `condition':
    gatar01.c:102: warning: suggest parentheses around comparison in operand of |
    gatar01.c:110: warning: suggest parentheses around comparison in operand of |
    gatar01.c:110: warning: suggest parentheses around comparison in operand of |
    gatar01.c:114: warning: statement with no effect
    gatar01.c:117: warning: suggest parentheses around comparison in operand of |
    gatar01.c:127: warning: control reaches end of non-void function
    gatar01.c: In function `expr':
    gatar01.c:132: warning: suggest parentheses around comparison in operand of |
    gatar01.c:141: warning: suggest parentheses around comparison in operand of |
    gatar01.c:141: warning: suggest parentheses around comparison in operand of |
    gatar01.c:141: warning: suggest parentheses around comparison in operand of |
    gatar01.c:147: warning: suggest parentheses around comparison in operand of |
    gatar01.c:157: warning: control reaches end of non-void function
    gatar01.c: In function `assign_stmt':
    gatar01.c:166: warning: statement with no effect
    gatar01.c:172: warning: suggest parentheses around comparison in operand of |
    gatar01.c:203: warning: control reaches end of non-void function

    C:\otros\dcw>
    That means that your code is broken. Only a blithering idiot would try running a program that is clearly broken (as evidenced by all the warnings that the compiler is throwing at you) and expect the results to actually mean anything. Running broken code results in expected program behavior. So please explain to us why you ignored all those warnings and ran your program anyway. And also please explain to us how you could possibly have imagined that your program's behavior could mean anything all all except that you were stupid enough to try to run broken code.

    Never ignore warnings!

    The warnings are telling you that several of your functions, which you declared to return a value, in fact do not even try to return a value. You lied to the compiler, which as a very bad thing to do:
    Originally Posted by Henry Spencer
    If you lie to the compiler, it will get its revenge.
    Now, since I had to edit your code listing in order to split it into separate files for compiling, the line numbers in the warnings will undoubtedly not line up with your own code.

    For these warnings,
    gatar01.c:65: warning: statement with no effect
    gatar01.c:114: warning: statement with no effect
    gatar01.c:166: warning: statement with no effect
    , the corresponding lines are:
    Code:
            primar->name;
     . . . 
                cond->relop;
     . . .
            assign->lhs->name;
    I have absolutely no idea what you thought you were telling the compiler with those.

    These warnings,
    gatar01.c:102: warning: suggest parentheses around comparison in operand of |
    gatar01.c:110: warning: suggest parentheses around comparison in operand of |
    gatar01.c:110: warning: suggest parentheses around comparison in operand of |
    gatar01.c:117: warning: suggest parentheses around comparison in operand of |
    gatar01.c:132: warning: suggest parentheses around comparison in operand of |
    gatar01.c:141: warning: suggest parentheses around comparison in operand of |
    gatar01.c:141: warning: suggest parentheses around comparison in operand of |
    gatar01.c:141: warning: suggest parentheses around comparison in operand of |
    gatar01.c:147: warning: suggest parentheses around comparison in operand of |
    gatar01.c:172: warning: suggest parentheses around comparison in operand of |
    , are because of if-statements like line 102:
    Code:
        if(ttype == NUM | ttype == ID)
    Really? Do you really intend to evaluate the equality tests and then bit-wise OR them together? Wherever were you taught that odd-ball technique? Can you still get a refund on the tuition you paid for that?

    | is a bit-wise operator. || is a relational operator. You might want to research into the difference between the two.

    Remember:

    1. Always turn warnings on and up!

    2. Never try to run a program that's throwing warnings. Only run a program that has compiled cleanly; ie, a program that compiles with no errors and with no warnings.

    3. Never ignore warnings!
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by gatar
    I'm posting on forums that are not related and not guaranteed to have the same user base. Ie it is possible that someone different would see the post on another forum. And I don't see why you would assume that just because it is posted somewhere else that I would ignore and not look into a response.
    Because that is what dirty little cross-posters do. We've seen that happen far too many times.

    Give one forum a chance before you move on to another.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    8
    Rep Power
    0
    I can understand that annoyance with cross posting, I was just hoping to get a timely reply because I am on a deadline.Also thank you for the knowledgeable reply. As far as the warnings go, I agree they would be very useful, I am compiling using WinSCP and gcc but i do not receive any warnings upon compilation, any suggestions on how to turn them on?
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Look at my invocation of gcc. Also consult help on gcc (gcc --help). There is also a man page on gcc which has a section called Warning Options.

    -Wall turns on all warnings. I always use this one, without fail.

    -Werror treats warnings as errors, as you should.

    --pedantic I haven't used this one, but I think that it makes error/warning detection more strict, AKA "turning warnings up!").
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    8
    Rep Power
    0
    Thanks! I also found in answer to my original question that the second call to assign->op2 = expr(); was returning a seg fault because there was not return exp in expr(). BESIDES all the other problems I now know I have haha

IMN logo majestic logo threadwatch logo seochat tools logo