在 Bison 中使用自定义类型时访问标识符内容

Access identifier content when using a custom type in Bison

我使用 flex 和 bison 准备好了扫描器和解析器。

解析器直接在动作中构建树,为此我创建了一个名为 STreeNode 的结构,我正在使用

#define YYSTYPE_IS_DECLARED
typedef STreeNode* YYSTYPE;

结构是:

typedef struct tagSTreeNode
{
    EOperationType type;
    int count;
    struct tagSTreeNode **children;
    char *string;
} STreeNode;

大约有 40 个标记,对于每条规则,我都有

unlabeled_statement:
        assignment                                                          {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
        | function_call_statement                                           {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
        | goto                                                              {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
        | return                                                            {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
        | conditional                                                       {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
        | repetitive                                                        {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
        | empty_statement                                                   {$$ = createNode(eUNLABELED_STATEMENT, 1, );}
        ;

createNode 函数的签名是

STreeNode *createNode(EOperationType type, int count, ...) {

这棵树工作正常。问题是访问变量名、函数名等的真实值。由于 YYSTYPE 是一个结构,$x 没有我想保存在结构中的 char * 字符串元素上的字符串值。

我有一个名为 IDENTIFIER 的 %token 和另一个名为 INTEGER 的令牌,它们应该接收我想要的值。

经过研究,我发现我可以尝试使用 union { } 来获得特定类型的每个标记。也许这会有所帮助?如果是这样,我一定需要指定每个令牌的类型吗?如何实施?

yytext呢?难道不能用来实现这个目标吗?

谢谢!

--- 编辑 --

所以我创建了

%union {
    char *string;
    STreeNode *node;
}

并指定每个终端和非终端类型都是其中之一。节点仍在工作,但使用 (例如 $1) 的字符串返回空值。

我还需要更改扫描仪中的任何内容吗?我的扫描仪有:

[a-zA-Z][a-z0-9A-Z]*        { return IDENTIFIER; }
[0-9]+                      { return INTEGER; }

再次感谢。

如果你的标记有一个类型设置,词法分析器需要将 yylval 设置为有问题的类型。类似于:

[a-zA-Z][a-z0-9A-Z]*        { yylval.string = strdup(yytext); return IDENTIFIER; }
[0-9]+                      { yylval.string = strdup(yytext); return INTEGER; }