c - 使用 Bison 构建 AST 时指针无效

标签 c bison abstract-syntax-tree flex-lexer

我正在尝试为简单的编程语言构建 AST(家庭作业)。 但是我无法使其工作:似乎中间值($1,$2,...)无效,并且与我在“子表达式”中返回的内容不对应。

这是我项目的 Bison 代码(我认为问题出在这里,而不是在我的 AST 函数中):我在遇到无效值的地方添加了注释。这是我使用 Bison 的第一个项目,所以我不确定我是否做对了。

我也使用 Flex,但 Flex 代码似乎可以正常工作。

谢谢。

%{
#include <stdio.h>

#include "node.h"
#include "print_node.h"

int yylex();
int yyerror(char * s);

CommandNode * root = NULL;
%}

%union
{
    struct ExpressionNode * expression;
    struct CommandNode    * command;
    int    number;
    char * var;
}

%type   <expression>    E T F
%type   <command>       C

%token  <number>        NUMBER
%token  <var>           VAR

%token                  AF SKIP SEQ IF THEN ELSE WHILE DO ADD SUB MUL EOL

%%

root:           C EOL      { root = $1; return 0; /************ $1 seems to be garbage ************/ }
                ;

E:              E ADD T    { $$ = newAddNode($1,$3); }
        |       E SUB T    { $$ = newSubNode($1,$3); }
        |       T          { $$ = $1;                }
        ;

T:              T MUL F    { $$ = newMulNode($1,$3); }
        |       F          { $$ = $1;                }
        ;

F:              '(' E ')'  { $$ = $2;                }
        |       NUMBER     { $$ = newNumberNode($1); }
        |       VAR        { $$ = newVarNode($1);    }
        ;

C:              SKIP                 { $$ = newSkipNode();       }
        |       VAR AF E             { $$ = newAfNode($1,$3);    }
        |       '(' C ')'            { $$ = $2;                  }
        |       IF E THEN C ELSE C   { $$ = newIfNode($2,$4,$6); }
        |       WHILE E DO C         { $$ = newWhileNode($2,$4); }
        |       C SEQ C              { $$ = newSeqNode($1,$3); /************ $1 and $3 seems to be garbage ************/ }
        ;

%%

int main()
{
    yyparse();
}

int yyerror(char * s)
{
    fprintf(stderr, "yyerror: %s\n", s);
}

最佳答案

最常见的是,您描述的症状发生是因为您的词法分析器(弹性代码,您不显示)直接返回yytext。由于 yytext 指向扫描仪的内部缓冲区,因此在该情况下看起来很好,但在读取下一个标记后,其值会神秘地发生变化。如果您有如下这样的弹性规则,就会发生这种情况:

[a-zA-A][a-zA-Z0-9]*    { yylval.var = yytext; return VAR; }

要修复它,您需要在将 yytext 返回到解析器之前复制它。类似的东西

[a-zA-A][a-zA-Z0-9]*    { yylval.var = strdup(yytext); return VAR; }

可以解决这个问题,尽管它会让你面临内存泄漏。

关于c - 使用 Bison 构建 AST 时指针无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42726054/

相关文章:

haskell - 使用箭头作为原子值评估 AST(作为 GADT)

c - 使用 Minimax 的 C 语言 3x3 Tic-Tac-Toe

c - 是什么导致了这里的内存访问错误?

c - y.tab.c 不是在带有 bison -d 的 Fedora 上生成的

syntax - Roslyn 语法树差异

java - 如何使用 java 解析器在 AST 中构建 for 语句?

c - fatal error : tlpi_hdr. h:没有那个文件或目录

在不使用 strcmp 的情况下比较 C 中两个二维数组的元素

javascript - 使用 Flex 解析器解析 Javascript 代码

c - yyerror 的 Bison 冲突类型