代码之家  ›  专栏  ›  技术社区  ›  Huzo

yacc中返回指针时出现分段错误

  •  0
  • Huzo  · 技术社区  · 6 年前

    当我的程序执行以下功能时,我得到一个分段错误。这就是我的程序和函数的外观:

    %{
    #include "agent.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include "message.h"
    int yylex(void);
    void yyerror(char *);
    ruleListNode * ruleListHead;
    ruleNode *newRule(conNode *conditions, actNode *action);
    .
    .
    .
    %}
    %union {int iValue; char sIndex; ASTnode *nPtr; litNode *litPtr; ruleNode *rulePtr; exprNode *expPtr; actNode *actPtr; conNode *conPtr;};
    .
    .
    .
    %type <rulePtr> rule
    .
    .
    %%
    program:
        program rule SEMICOLON {addRule($2);}
        |
        ;
    
    rule:
        condition IMPLY action {$$=newRule($1, $3); printf("lets see");}
        ;
    .
    .
    .
    %%
    ruleNode *newRule(conNode* conditions, actNode* action){
        ruleNode * tmp;
        tmp = (ruleNode *) malloc(sizeof(ruleNode)); 
        tmp->conditions = conditions;
        tmp->action = action;
        printf("new rule\n");
        return tmp;
    }
    .
    .
    .
    

    return tmp 里面 newRule 功能。我不完全确定为什么程序会这样运行,因为我以前在C中返回指针时没有遇到过这个问题。我不确定以下信息是否足以确定问题。如果你需要更多的信息,请说明。

    编辑:整个代码供参考。 Yacc文件

    %{
    #include "agent.h"
    #include <stdio.h>
    #include <stdlib.h>
    int yylex(void);
    void yyerror(char *);
    ruleListNode * ruleListHead;
    void addRule(ruleNode *node);
    ruleNode *newRule(conNode *conditions, actNode *action);
    conNode *newCondition(litNode *formula, conNode *condition);
    litNode *newFormula(litNode *whatLiteral, int t_f_value);
    actNode *newAction(int actionId, exprNode *varexpr1, exprNode *varexpr2);
    exprNode *newExpr(exprNode *expr1, int operation, exprNode *expr2, int value);
    exprNode *newStatevar(exprNode* meOrOpp, exprNode* property);
    exprNode *newVarexpr(int existVar, char varName, exprNode *varexpr1);
    litNode *newComparison(exprNode *leftExpr, int comp_op, exprNode *rightExpr);
    litNode *newGenerator(int varType, char leftExpr, exprNode *midExpr, exprNode *rightExpr);
    litNode *newPredicate(int varType, exprNode *leftExpr, exprNode *rightExpr);
    exprNode *newPlayer(int p);
    exprNode *newProperty(int p);
    %}
    %union {int iValue; char sIndex; ASTnode *nPtr; litNode *litPtr; ruleNode *rulePtr; exprNode *expPtr; actNode *actPtr; conNode *conPtr;};
    %token <iValue> INTEGER
    %token <sIndex> VARIABLE
    %token DOT
    %token COMMA
    %token OPENP
    %token CLOSEP
    %token <iValue> TRUE
    %token <iValue> FALSE
    %token <iValue> IMPLY
    %token <iValue> AND
    %token <iValue> PLUS
    %token <iValue> MINUS
    %token <iValue> GREATEREQUAL
    %token <iValue> SMALLEREQUAL
    %token <iValue> GREATER
    %token <iValue> SMALLER
    %token <iValue> ISEQUAL
    %token <iValue> ISNOTEQUAL
    %token <iValue> ME
    %token <iValue> OPP
    %token <iValue> HP
    %token <iValue> RESOURCE
    %token <iValue> UNITNO
    %token <iValue> ROBOTNO
    %token <iValue> BUILDINGNO
    %token <iValue> HOPLITENO
    %token <iValue> LANCERNO
    %token <iValue> WALLNO
    %token <iValue> MINENO
    %token <iValue> ISMINE
    %token <iValue> ISWALL
    %token <iValue> ISLANCER
    %token <iValue> ISHOPLITE
    %token <iValue> ISUNIT
    %token <iValue> ISROBOT
    %token <iValue> ISBUILDING
    %token <iValue> ISEMPTYENEMYBASE
    %token <iValue> ISEMPTYMYBASE
    %token <iValue> ISEMPTY
    %token <iValue> ISFRIENDLY
    %token <iValue> ISENEMY
    %token <iValue> PLACEMINEAT
    %token <iValue> PLACEWALLAT
    %token <iValue> PLACELANCERAT
    %token <iValue> PLACEHOPLITEAT
    %token <iValue> PLACEBUILDINGAT
    %token <iValue> PLACEROBOTAT
    %token <iValue> PLACEUNITAT
    %token <iValue> RANDOMBTN
    %token <iValue> RANDOMBTNBASE
    %token <iValue> SEMICOLON
    
    %type <rulePtr> rule
    %type <conPtr> condition
    %type <litPtr> formula
    %type <actPtr> action
    %type <expPtr> expr
    %type <expPtr> varexpr
    %type <litPtr> predicate
    %type <litPtr> generator
    %type <litPtr> comparison
    %type <expPtr> statevar
    %type <expPtr> player
    %type <expPtr> property
    %%
    program:
        program rule SEMICOLON {addRule((ruleNode*)$2);}
        |
        ;
    
    rule:
        condition IMPLY action {$$=newRule($1, $3); printf("lets see");}
        ;
    
    condition:
        formula AND condition {$$=newCondition($1, $3);}
        |
        formula {$$=newCondition($1, NULL);}
        ;
    
    formula:
        predicate {$$ = newFormula($1, -1);}
        |
        generator {$$ = newFormula($1, -1);}
        |
        comparison {$$ = newFormula($1, -1);}
        |
        TRUE {$$ = newFormula(NULL, $1);}
        |
        FALSE {$$ = newFormula(NULL, $1);}
        ;
    
    action:
        PLACEMINEAT OPENP varexpr COMMA varexpr CLOSEP {$$=newAction($1, $3, $5);}
        |
        PLACEWALLAT OPENP varexpr COMMA varexpr CLOSEP {$$=newAction($1, $3, $5);}
        |
        PLACELANCERAT OPENP varexpr COMMA varexpr CLOSEP {$$=newAction($1, $3, $5);}
        |
        PLACEHOPLITEAT OPENP varexpr COMMA varexpr CLOSEP {$$=newAction($1, $3, $5);}
        |
        PLACEBUILDINGAT OPENP varexpr COMMA varexpr CLOSEP {$$=newAction($1, $3, $5);}
        |
        PLACEROBOTAT OPENP varexpr COMMA varexpr CLOSEP {$$=newAction($1, $3, $5);}
        |
        PLACEUNITAT OPENP varexpr COMMA varexpr CLOSEP {$$=newAction($1, $3, $5);}
        ;
    
    predicate:
        ISMINE OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISWALL OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISLANCER OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISHOPLITE OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISUNIT OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISROBOT OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISBUILDING OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISEMPTY OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISEMPTY OPENP expr COMMA expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISEMPTYMYBASE OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISEMPTYENEMYBASE OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISFRIENDLY OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        |
        ISENEMY OPENP expr COMMA expr CLOSEP {$$=newPredicate($1, $3, $5);}
        ;
    
    generator:
        RANDOMBTN OPENP VARIABLE COMMA expr COMMA expr CLOSEP {$$=newGenerator($1, $3, $5, $7);}
        |
        RANDOMBTNBASE OPENP VARIABLE COMMA expr CLOSEP {$$=newGenerator($1, $3, NULL, $5);}
        ;
    
    comparison:
        statevar GREATER expr {$$=newComparison($1, $2, $3);}
        |
        statevar SMALLER expr {$$=newComparison($1, $2, $3);}
        |
        statevar GREATEREQUAL expr {$$=newComparison($1, $2, $3);}
        |
        statevar SMALLEREQUAL expr {$$=newComparison($1, $2, $3);}
        |
        statevar ISEQUAL expr {$$=newComparison($1, $2, $3);}
        |
        statevar ISNOTEQUAL expr {$$=newComparison($1, $2, $3);}
        ;
    
    varexpr:
        VARIABLE {$$=newVarexpr(1, $1, NULL);}
        |
        expr {$$=newVarexpr(-1, 'n', $1);}
        ;
    
    expr:
        expr PLUS expr {$$=newExpr($1, $2, $3, -1);}
        |
        expr MINUS expr {$$=newExpr($1, $2, $3, -1);}
        |
        INTEGER {$$=newExpr(NULL, -1, NULL, $1);}
        ;
    
    statevar:
        player DOT property {$$=newStatevar($1, $3);}
        ;
    
    player:
        ME {$$=newPlayer($1);}
        | OPP {$$=newPlayer($1);}
        ;
    
    property:
        HP {$$=newProperty($1);}
        | RESOURCE {$$=newProperty($1);}
        | UNITNO {$$=newProperty($1);}
        | ROBOTNO {$$=newProperty($1);}
        | BUILDINGNO {$$=newProperty($1);}
        | HOPLITENO {$$=newProperty($1);}
        | LANCERNO {$$=newProperty($1);}
        | WALLNO {$$=newProperty($1);}
        | MINENO {$$=newProperty($1);}
        ;
    %%
    void addRule(ruleNode *node){
        printf("www");
        ruleListNode *newNode;
        newNode = malloc(sizeof(ruleListNode));
        newNode->curRule = node;
        printf("aaa");
    
        ruleListNode *tmp;
        tmp = ruleListHead;
        printf("bbb");
        while(tmp->next != NULL){
            printf("ccc");
            tmp = tmp->next;
        }
        tmp->next = newNode;
        printf("rule added\n");
    }
    
    ruleNode *newRule(conNode* conditions, actNode* action){
        ruleNode * tmp;
        tmp = malloc(sizeof(ruleNode));
        tmp->conditions = conditions;
        tmp->action = action;
        printf("new rule\n");
        return tmp;
    }
    
    conNode *newCondition(litNode* formula, conNode* condition){
        conNode * tmp;
        tmp = malloc(sizeof(conNode));
        tmp->left = formula;
        tmp->right = condition;
        printf("new condition\n");
        return tmp;
    }
    
    litNode *newFormula(litNode *whatLiteral, int t_f_value){
        litNode * tmp;
        tmp = malloc(sizeof(litNode));
        if(whatLiteral == NULL){
            tmp->literalType = t_f;
            tmp->true_false = t_f_value;
        }
        else if(whatLiteral->literalType == comp){
            tmp->literalType = whatLiteral->literalType;
            tmp->yExpr = whatLiteral->yExpr;
            tmp->comp_op= whatLiteral->comp_op;
            tmp->xExpr = whatLiteral->xExpr;
        }
        else if(whatLiteral->literalType == gene){
            tmp->literalType = whatLiteral->literalType;
            tmp->varType = whatLiteral->varType;
            tmp->yExpr = whatLiteral->yExpr;
            tmp->mExpr = whatLiteral->mExpr;
            tmp->xExpr = whatLiteral->xExpr;
        }
        else if(whatLiteral->literalType == pred){
            tmp->literalType = whatLiteral->literalType;
            tmp->varType = whatLiteral->varType;
            tmp->yExpr = whatLiteral->yExpr;
            tmp->xExpr = whatLiteral->xExpr;
        }
        printf("new formula\n");
        return tmp;
    }
    
    actNode* newAction(int actionId, exprNode *varexpr1, exprNode *varexpr2){
        actNode * tmp;
        tmp = malloc(sizeof(actNode)); 
        tmp->yExpr = varexpr1->left;
        tmp->xExpr = varexpr2->right;
        tmp->action = actionId;
        printf("new action\n");
        return tmp;
    }
    
    exprNode *newExpr(exprNode *expr1, int operation, exprNode *expr2, int value){
        exprNode * tmp;
        tmp = malloc(sizeof(exprNode)); 
        if(operation != -1){
            tmp->expType = aritExpr;
            tmp->existSym = 1;
            tmp->left = expr1;
            tmp->right = expr2;
            tmp->op = operation;
        }
        else{
            tmp->expType = constant;
            tmp->existSym = 0;
            tmp->iValue = value;
        }
        printf("new expr\n");
        return tmp;
    }
    
    exprNode *newStatevar(exprNode *meOrOpp, exprNode* property){
        exprNode * tmp;
        tmp = malloc(sizeof(exprNode));
        tmp->expType = stateVar;
        tmp->player = meOrOpp->player;
        tmp->prop = property->prop;
        printf("new statevar\n");
        return tmp;
    }
    
    exprNode *newVarexpr(int existVar, char varName, exprNode *varexpr1){
        exprNode * tmp;
        tmp = malloc(sizeof(exprNode));
        tmp->expType = varExpr;
        if(existVar != -1){
            tmp->symName = varName;
        }
        else{
            tmp->left = varexpr1;
        }
        printf("new varexpr\n");
        return tmp;
    }
    
    litNode *newComparison(exprNode *leftExpr, int comp_op, exprNode *rightExpr){
        litNode * tmp;
        tmp = malloc(sizeof(litNode));
        tmp->literalType = comp;
        tmp->yExpr = leftExpr;
        tmp->comp_op = comp_op;
        tmp->xExpr = rightExpr;
        printf("new comparison\n");
        return tmp;
    }
    
    litNode *newGenerator(int varType, char leftExpr, exprNode *midExpr, exprNode *rightExpr){
        litNode * tmp;
        tmp = malloc(sizeof(litNode));
        exprNode * var;
        var = malloc(sizeof(exprNode));
        var->symName = leftExpr;
        tmp->literalType = gene;
        tmp->varType = varType;
        tmp->yExpr = var;
        tmp->mExpr = midExpr;
        tmp->xExpr = rightExpr;
        printf("new generator\n");
        return tmp;
    }
    
    litNode *newPredicate(int varType, exprNode *leftExpr, exprNode *rightExpr){
        litNode * tmp;
        tmp = malloc(sizeof(litNode));
        tmp->literalType = pred;
        tmp->varType = varType;
        tmp->yExpr = leftExpr;
        tmp->xExpr = rightExpr;
        printf("new predicate\n");
        return tmp;
    }
    
    exprNode *newPlayer(int p){
        exprNode *tmp;
        tmp = malloc(sizeof(exprNode));
        tmp->player = p;
        printf("new player\n");
        return tmp;
    }
    
    exprNode *newProperty(int p){
        exprNode *tmp;
        tmp = malloc(sizeof(exprNode));
        tmp->prop = p;
        printf("new property\n");
        return tmp; 
    }
    
    int main(){
        int fd, human_id;
        char name[] = "Agent X";
    
        if(yyparse() != 0){
            exit(-1);
        }
        printf("%d",ruleListHead->curRule->nodeType);
    
    
    
    
        return 0;
    }
    
    void yyerror (char *s) {
       fprintf (stderr, "%s\n", s);
     }
    

    %{
    #include "agent.h"
    #include "y.tab.h"
    void yyerror(char *s);
    int yylex();
    %}
    %%
    [0-9]+ {printf("%s ", yytext); yylval.iValue = atoi(yytext); return INTEGER;}
    [a-z] {printf("%s ", yytext); yylval.sIndex = *yytext - 'a'; return VARIABLE;}
    ";" {printf("%s ", yytext); return SEMICOLON;}
    "." {printf("%s ", yytext); return DOT;}
    "," {printf("%s ", yytext); return COMMA;}
    "(" {printf("%s ", yytext); return OPENP;}
    ")" {printf("%s ", yytext); return CLOSEP;}
    "True" {printf("%s ", yytext); return TRUE;}
    "False" {printf("%s ", yytext); return FALSE;}
    "=>" {printf("%s ", yytext); return IMPLY;}
    "&" {printf("%s ", yytext); return AND;}
    "+" {printf("%s ", yytext); return PLUS;}
    "-" {printf("%s ", yytext); return MINUS;}
    ">=" {printf("%s ", yytext); return GREATEREQUAL;}
    "<=" {printf("%s ", yytext); return SMALLEREQUAL;}
    ">" {printf("%s ", yytext); return GREATER;}
    "<" {printf("%s ", yytext); return SMALLER;}
    "==" {printf("%s ", yytext); return ISEQUAL;}
    "!=" {printf("%s ", yytext); return ISNOTEQUAL;}
    "me" {printf("%s ", yytext); return ME;}
    "opp" {printf("%s ", yytext); return OPP;}
    "hp" {printf("%s ", yytext); return HP;}
    "resource" {printf("%s ", yytext); return RESOURCE;}
    "unitNo" {printf("%s ", yytext); return UNITNO;}
    "robotNo" {printf("%s ", yytext); return ROBOTNO;}
    "buildingNo" {printf("%s ", yytext); return BUILDINGNO;}
    "hopliteNo" {printf("%s ", yytext); return HOPLITENO;}
    "lancerNo" {printf("%s ", yytext); return LANCERNO;}
    "wallNo" {printf("%s ", yytext); return WALLNO;}
    "mineNo" {printf("%s ", yytext); return MINENO;}
    "isMine" {printf("%s ", yytext); return ISMINE;}
    "isWall" {printf("%s ", yytext); return ISWALL;}
    "isLancer" {printf("%s ", yytext); return ISLANCER;}
    "isHoplite" {printf("%s ", yytext); return ISHOPLITE;}
    "isUnit" {printf("%s ", yytext); return ISUNIT;}
    "isRobot" {printf("%s ", yytext); return ISROBOT;}
    "isBuilding" {printf("%s ", yytext); return ISBUILDING;}
    "isEmptyEnemyBase" {printf("%s ", yytext); return ISEMPTYENEMYBASE;}
    "isEmptyMyBase" {printf("%s ", yytext); return ISEMPTYMYBASE;}
    "isEmpty" {printf("%s ", yytext); return ISEMPTY;}
    "isFriendly" {printf("%s ", yytext); return ISFRIENDLY;}
    "isEnemy" {printf("%s ", yytext); return ISENEMY;}
    "placeMineAt" {printf("%s ", yytext); return PLACEMINEAT;}
    "placeWallAt" {printf("%s ", yytext); return PLACEWALLAT;}
    "placeLancerAt" {printf("%s ", yytext); return PLACELANCERAT;}
    "placeHopliteAt" {printf("%s ", yytext); return PLACEHOPLITEAT;}
    "placeBuildingAt" {printf("%s ", yytext); return PLACEBUILDINGAT;}
    "placeRobotAt" {printf("%s ", yytext); return PLACEROBOTAT;}
    "placeUnitAt" {printf("%s ", yytext); return PLACEUNITAT;}
    "randomBtnBase" {printf("%s ", yytext); return RANDOMBTNBASE;}
    "randomBtn" {printf("%s ", yytext); return RANDOMBTN;}
    [ \t] ;
    . yyerror("invalid character");
    %%
    int yywrap(void) {return 1;}
    

    agent.h头文件

    // #include "y.tab.h"
    #ifndef AGENT_HEADER_FILE
    #define AGENT_HEADER_FILE
    
    typedef enum { typeExpr, typeLit, typeCon, typeAct, typeRule  } nodeEnum;
    typedef enum { constant, stateVar, varExpr, aritExpr } exprType;
    typedef enum { comp, gene, pred, t_f} litType;
    
    /* experssion node */
    typedef struct exprNode {
        nodeEnum nodeType;  
        exprType expType; /* type of experssion */ 
        int existSym; /* boolean value whether exists symbol or not */ 
        struct exprNode * left; /* the pointer to left expression */
        struct exprNode * right; /* the pointer to right expression */ 
        int iValue; /* value of constant */ 
        char symName; /* name of the variable */ 
        int player; /* me or opponent */ 
        int prop; /* property */ 
        int op; /* operator */ 
    } exprNode;
    
    /* literal node */
    typedef struct litNode { 
        nodeEnum nodeType; 
        litType literalType; /* type of literal */ 
        int varType;
        exprNode * yExpr; /* experission for the row value */ 
        exprNode * mExpr; /* experission for the middle value */ 
        exprNode * xExpr; /* experission for the column value */ 
        int comp_op; /* logical comparison operator */ 
        int true_false;
    } litNode; 
    
    /* conditions node */
    typedef struct conNode {
        nodeEnum nodeType; 
        struct litNode * left; /* the pointer to the current Literal */ 
        struct conNode * right; /* next conditions */ 
        int logop; /* the logical operator */
    } conNode;
    
    /* actions node */
    typedef struct {
        nodeEnum nodeType; 
        int action; /* type of action */ 
        exprNode * yExpr; /* experission for the row value */ 
        exprNode * xExpr; /* experission for the column value */ 
    } actNode;
    
    typedef struct {
        nodeEnum nodeType; 
        conNode * conditions; /* conditions */ 
        actNode * action; /* action */
    } ruleNode; 
    
    typedef struct ruleListNode {
        ruleNode * curRule; 
        struct ruleListNode * next;
    } ruleListNode; 
    
    typedef struct nodeTypeTag {
        nodeEnum nodeType; 
        ruleNode rule; 
        conNode cond; 
        actNode act; 
        exprNode expr; 
        litNode lit; 
    } ASTnode;
    
    void playgame(char* name);
    
    #endif
    

    用于测试的test.txt

    空的(0,2,4)&me.mineNo<5=>placeMineAt(0,3);

    0 回复  |  直到 6 年前
        1
  •  1
  •   Reiss    6 年前

    你得检查一下 ruleListHead NULL 在添加新节点之前。

        2
  •  1
  •   Armali    6 年前

    addRule 不会为零而高兴 ruleListHead . –莫尔德尼洛