【问题标题】:Problem when try get $4 with some arguments- YACC -> C尝试使用一些参数获取 $4 时出现问题 - YACC -> C
【发布时间】:2020-12-19 22:41:34
【问题描述】:

当我尝试为另一个条件获取 2 个或更多参数时,我是堆栈。 最大的想法是构建符号表来识别代码中的错误,我正在构建一棵树,但现在我们需要构建表,但我不想使用这棵树.. 所以我尝试与我制作的 LinkList 一起使用。 这是我在 c 中的链接列表:

    typedef struct linkList {
        char* data;
        struct linkList* next;
}linkList;

对不起,不清楚,我会尝试用例子来解释。

这里是我的一些情况:

s: Program { };
Program: Proc_Func {$$ = mknode("CODE",$1,NULL); };
Proc_Func: Proc_Func Funct {$$ = mknode("",$1,$2); }
          | Proc_Func Proce {$$ = mknode("",$1,$2); }
          | Funct {$$ =$1;}// mknode("",$1,NULL); }
          | Statement {$$ = mknode("",$1,NULL); }
          | Proce {$$ = mknode("",$1,NULL); }
          |{$$=NULL;};
Funct: FUNC id LBRACKET Param RBRACKET RETURN Type LBRACE Body RBRACE {$$ = mknode("FUNC",mknode("",mknode("",$2,NULL),mknode("ARGS",$4,mknode("RETURN",$7,NULL))),mknode("",$9,NULL)); 
buildLinkList($2,$4,$7,$9);};
Proce: PROC id LBRACKET Param RBRACKET LBRACE Body RBRACE {$$ = mknode("PROC",mknode("",mknode("",$2,NULL),mknode("ARGS",$4,mknode("",$7,NULL))),NULL); };
Param: Param_list {$$ = mknode("",$1,NULL); }
    |{$$ =NULL;};
     
Param_list: Var_id COLON Type {$$ = mknode("",$3,mknode("",$1,mknode(")",NULL,NULL))); }
          | Param_list SEMICOLON Param_list {$$ = mknode("",$1,mknode("",$3,NULL)); };
Var_id: id COMMA Var_id {$$ = $1;}//mknode("",mknode("",$1,NULL),$3); }
      | id {$$ = mknode(yytext,NULL,NULL);};
Type: BOOL {$$ = mknode("BOOLEAN",NULL,NULL); }
    | CHAR {$$ = mknode("CHAR",NULL,NULL); }
    | INT {$$ = mknode("INT",NULL,NULL); }
    | REAL {$$ = mknode("REAL",NULL,NULL); }
    | INT_P {$$ = mknode("INT_P",NULL,NULL); }
    | REAL_P {$$ = mknode("REAL_P",NULL,NULL); }
    | CHAR_P {$$ = mknode("CHAR_P",NULL,NULL); };

Body: Proc_Func Declares Statements {$$= mknode ("BODY",mknode("",$1,NULL),mknode("",$2,mknode("",$3,mknode("",NULL,NULL))));};


Declares: Declares Declare {$$= mknode ("",$1,$2);}
        |{$$=NULL;};
Declare: VAR Var_id COLON Type SEMICOLON {$$= mknode ("VAR",$2,$4);};
Statements: Statements Statement {$$= mknode ("",$1,$2);}
            |{$$=NULL;};
Statement: IF LBRACKET exp RBRACKET ST_Block {$$ = mknode("IF",mknode("(",$3,mknode(")",NULL,NULL)),$5);}
         | IF LBRACKET exp RBRACKET ST_Block ELSE ST_Block {$$=mknode("IF ELSE", mknode("",$3,mknode("",NULL,NULL)),mknode("",$5,mknode("",$7,NULL)));}
         | WHILE LBRACKET exp RBRACKET ST_Block {$$=mknode("WHILE",mknode("(",$3,mknode(")",NULL,NULL)),$5);}
         | ST_Assign SEMICOLON {$$=mknode("",$1,NULL);}
         | exp SEMICOLON {$$=$1;}
         | RETURN exp SEMICOLON {$$=mknode("RETURN",$2,NULL);}
         | NEW_Block {$$=$1;};


ST_Block: Statement {$$=$1;}
        | Declare {$$=$1;}
        | Proce {$$=$1;}
        | Funct {$$=$1;}
        | SEMICOLON {$$=mknode("",NULL,NULL);};
        

NEW_Block: LBRACE Proc_Func Declares Statements RBRACE {$$= mknode ("{",$2,mknode("",$3,mknode("",$4,("}",NULL,NULL))));};
    
ST_Assign: Ll ASSIGN exp {$$= mknode("=",$1,$3);};

Ll: id LSQRBR exp RSQRBR
  | id {$$ = mknode("",$1,NULL); }
  | ;

exp: exp EQUAL exp {$$= mknode ("==",$1,$3);}
   | exp NOTEQ exp {$$= mknode ("!=",$1,$3);}
   | exp BIGGER exp {$$= mknode (">",$1,$3);}
   | exp BIGGEREQ exp {$$= mknode (">=",$1,$3);}
   | exp SMALLER exp {$$= mknode ("<",$1,$3);}
   | exp SMALLEREQ exp {$$= mknode ("<=",$1,$3);}
   | exp AND exp {$$= mknode ("&&",$1,$3);}
   | exp OR exp {$$= mknode ("||",$1,$3);}
   | exp PLUS exp {$$= mknode ("+",$1,$3);}
   | exp MINUS exp {$$= mknode ("-",$1,$3);}
   | exp MULTIPLY exp {$$= mknode ("*",$1,$3);}
   | exp DIV exp {$$= mknode ("/",$1,$3);}
   | NOT exp {$$= mknode ("!",$2,NULL);}
   | BOOLTRUE {$$= mknode ("",mknode("BOOLEAN",$1,NULL),NULL);}
   | BOOLFALSE {$$= mknode ("",mknode("BOOLEAN",$1,NULL),NULL);}
   |id {$$ = mknode("",$1,NULL); }
   |CHAR_LTL {$$= mknode ($1,mknode("CHAR",NULL,NULL),NULL);}
   | NUM {$$ = mknode(yytext,NULL,NULL); };
id: ID {$$ = $1; mknode(yytext,NULL,NULL); };
   //| NULLL;

这是构建链接列表的函数:

    void buildLinkList(char *d1,char *d2,char *d3,char *d4)
{
    linkList *link1 = NULL;
    link1=(linkList*)malloc(sizeof(linkList));
    link1->data = (char*)malloc(sizeof(d1)+1);
    strcpy(link1->data,d1);
    linkList* link2= (linkList*)malloc(sizeof(linkList));
    link2->data=(char*)malloc(sizeof(linkList));
    strcpy(link2->data,d2);
    link1->next=link2;
    linkList *link3= (linkList*)malloc(sizeof(linkList));
    link3->data=(char*)malloc(sizeof(linkList));
    strcpy(link3->data,d3);
    link2->next=link3;
    linkList* link4= (linkList*)malloc(sizeof(linkList));
    link4->data=(char*)malloc(sizeof(linkList));
    strcpy(link4->data,d4);
    link3->next=link4;
    //printf("%s",link1->data);
    //printf("%s",link2->data);
    

我尝试返回链接列表,但它不起作用.. 所以我尝试将所有参数发送到一个列表。 在“Funct”条件下,您可以看到我调用了函数 buildLinkList,我发送了 $2,$4,$7,$9。

$2- 我可以将它“缓存”在我的列表中并成功打印它。但是 $4 是“param”并且它返回给我一些变量,当我尝试打印它时,我无法将它们推送到我的列表中我得到垃圾。 我尝试了很多方法来传递它和其他想法,请帮助我破解它,欢迎其他想法。

谢谢!

【问题讨论】:

    标签: c parsing yacc lex symbol-table


    【解决方案1】:

    我认为问题出在此处(以及相关行):

    link1->data = (char*)malloc(sizeof(d1)+1);
    

    这里,sizeof(d1) 给出了名为d1指针 的大小,而不是它指向的字符串 的大小。对于长度超过指针大小的字符串,这将为您随后复制的字符串分配不足的空间。

    要解决此问题,请将 sizeof(d1) 更改为 strlen(d1)。或者,考虑使用strdup,它既分配您需要的空间,又将字符串内容复制到该空间中。

    【讨论】:

    • 首先非常感谢您的回答..!我试过了,不幸的是它没有成功:(它也给了我一个垃圾..
    猜你喜欢
    • 2022-10-15
    • 1970-01-01
    • 2011-04-22
    • 2020-01-16
    • 1970-01-01
    • 2021-10-13
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多