C BISON AST生产打印置乱值
我正在尝试制作一个简单的解析器。这是一个家庭作业,但也为自己的实验。我已经完成了lexer和解析器,现在我正在尝试输出一个AST。问题是,例如,当我添加两个整数时,结果树会打印出无法识别的符号。有效输入应为C BISON AST生产打印置乱值,c,compiler-construction,bison,abstract-syntax-tree,yacc,C,Compiler Construction,Bison,Abstract Syntax Tree,Yacc,我正在尝试制作一个简单的解析器。这是一个家庭作业,但也为自己的实验。我已经完成了lexer和解析器,现在我正在尝试输出一个AST。问题是,例如,当我添加两个整数时,结果树会打印出无法识别的符号。有效输入应为+(1,1),有效输出应为(+11)。相反,我得到的是(+�|K�|k)。我尝试过很多事情,但实际上没有任何显著的结果。sprintf函数返回空终止符,因此这可能不是问题所在。下面是解析器代码(.y文件): lexer文件: %{ #include "parser.h" %} DIGIT [0
+(1,1)
,有效输出应为(+11)
。相反,我得到的是(+�|K�|k)
。我尝试过很多事情,但实际上没有任何显著的结果。sprintf
函数返回空终止符,因此这可能不是问题所在。下面是解析器代码(.y文件):
lexer文件:
%{
#include "parser.h"
%}
DIGIT [0-9]
LETTER [a-zA-Z]
%%
LET {printf("Encountered LET\n"); return(LET);}
IN {printf("Encountered IN\n"); return(IN);}
AND {printf("Encountered AND\n"); return(AND);}
{DIGIT}+ {yylval = atoi(yytext); return NUMBER;}
{LETTER}* { if (strlen(yytext) <= 8){
yylval = strlen(yytext);
printf( "<ID, %s> ", yytext );
return(ID);
} else {
yytext[8] = '\0';
printf("WARNING! Long identifier. Truncating to 8 chars\n");
printf( "<ID, %s> ", yytext );
return(ID);
}
}
[ \t] ;
[\n] return(END);
"+" return(PLUS);
"-" return(MINUS);
"*" return(TIMES);
"=" return(EQUALS);
"(" return(LP);
")" return(RP);
"," return(COMMA);
<<EOF>> return(0);
%%
int yywrap (void) {return 1;}
文件tree.h只包含一些声明,没有什么大不了的,而且肯定与问题无关
为什么数字看起来像这样?我怎样才能修好它?任何帮助都将不胜感激。这个问题实际上与bison或flex无关。它在您的
make\u number\u leaf
实现中:
TREE *make_number_leaf(int n){
TREE *leafNum = malloc(sizeof(TREE));
char *c, ch[8];
// ^ local variable
sprintf(ch, "%d", n); /* Effective way to convert int to string */
c = ch;
leafNum->token = c;
// ^ dangling pointer
// Remainder omitted
}
如上面的注释所示,ch
是一个本地(堆栈分配)变量,其生存期在函数返回时结束。将其地址分配给变量c
不会改变这一点。因此,存储在leafNum->token
中的c
的值将在函数返回时变为悬空指针
因此,当您稍后尝试打印令牌时,您正在打印随机内存的内容
你需要malloc
一个字符缓冲区,当你空闲时,记得释放它。(但是,如果leafNum->token
是字符串文字,则不能调用free
,因此需要更聪明一些。)
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
#include "treedefs.h"
int main(int argc, char **argv){
yyparse();
return 0;
}
typedef struct tree{
char *token;
TREE *l;
TREE *r;
TREE *child;
}TREE;
/* Make number leaves */
TREE *make_number_leaf(int n){
TREE *leafNum = malloc(sizeof(TREE));
char *c, ch[8];
sprintf(ch, "%d", n); /* Effective way to convert int to string */
c = ch;
leafNum->token = c;
leafNum->l = NULL;
leafNum->r = NULL;
leafNum->child = NULL;
printf("NUM Leaf is: %s\n", leafNum->token);
return (leafNum);
}
/* Addition tree */
TREE *make_plus_tree(TREE *l, TREE *r){
TREE *plusTree = malloc(sizeof(TREE));
plusTree->token = "+";
plusTree->l = l;
plusTree->r = r;
plusTree->child = NULL;
return (plusTree);
}
void printtree(TREE *tree)
{
if (tree->l || tree->r){
printf("(");
}
printf(" %s ", tree->token);
if (tree->l){
printtree(tree->l);
}
if (tree->r){
printtree(tree->r);
}
if (tree->l || tree->r){
printf(")");
}
}
TREE *make_number_leaf(int n){
TREE *leafNum = malloc(sizeof(TREE));
char *c, ch[8];
// ^ local variable
sprintf(ch, "%d", n); /* Effective way to convert int to string */
c = ch;
leafNum->token = c;
// ^ dangling pointer
// Remainder omitted
}