c - 在 yacc 中返回指针时出现段错误

标签 c pointers segmentation-fault yacc

当我的程序执行以下函数时,出现段错误。这是我的程序和函数的样子:

%{
#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;
}
.
.
.

当程序到达 newRule 函数内的 return tmp 行时,会发生错误。我不完全确定为什么程序会以这种方式运行,因为我以前在 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);
 }

Lex 文件

%{
#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 用于测试

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

最佳答案

在添加新节点之前,您必须先检查 ruleListHead 是否为 NULL

关于c - 在 yacc 中返回指针时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56105741/

相关文章:

c - <错误: Cannot access memory at address 0x0> 3d array malloc

c - 结构体中动态数组的迭代器

从多个线程调用相同的函数

C - 在系统函数调用后将 SHELL 输出保存在文件中

c - 如何将 unsigned char 打印为 ascii

转换新元素以将它们附加到单链表中

c - 将队列数据结构作为数组实现的问题

c++ - char 类型的参数与参数类型 LPWSTR 不兼容

c - 出现段错误 11 不确定在 C 中是否正确使用指针

c++ - 使用 std::set of pointers 时出现段错误...谁能解释一下?