Bison %union 使用

Bison %union use

所以,我在我的 .y 语法中设置了一个 AST,下面是如何使用它的示例片段:

typedef struct node
{
  struct node *left;
  struct node *right;
  char *token;
} node;

...

exp    : term             {$$ = ;}
        | exp PLUS term     {$$ = mknode(, , "+");}
        | exp MINUS term    {$$ = mknode(, , "-");}
        ;
...
node *mknode(node *left, node *right, char *token)
{
  /* malloc the node */
  node *newnode = (node *)malloc(sizeof(node));
  char *newstr = (char *)malloc(strlen(token)+1);
  strcpy(newstr, token);
  newnode->left = left;
  newnode->right = right;
  newnode->token = newstr;
  return(newnode);
 }

我的问题是,像这样设置,是否仍然可以将 %union 用于其他值? 即

%union{
    int value;
}
exp    : term             {
                             $$ = ;
                             $<value>$ = $<value>1;
                          }
        | exp PLUS term     {
                               if($<value>1 == $<value>3) {
                                   $$ = mknode(, , "+");
                                   $<value>$ = $<value>1;
                               }
                            }
...etc

或者设置 $$ 会覆盖使用联合变量的能力吗?

您的示例显示将两个值分配给同一联合的不同元素,因此第二个值将覆盖第一个值。 $$ 是当前动作生成的联合值栈槽,而 </code> 和 <code> 是对应那些非终结符的联合值槽,它们被写入 $$ 在这些规则的操作中。

使用 <type> 只是覆盖要使用的联合中的默认字段,这通常由代码中的 %type 声明(您未显示)决定。因此,如果您的代码中有
%type <value> exp,则 $$$<value>$ 指的是同一事物——[=21= 的 value 字段] 动作运行后将被压入 bison 值堆栈的变量。

如果你想为 bison 值堆栈上的同一个非终结符设置多个值,请在联合中使用结构:

%union {
    struct {
        node *node;
        int value;
    } node_and_value;
    :
}

%type <node_and_value> exp term

%%

exp    : term             {
                             $$ = ; /* copy the whole struct */
                             /* this is the default action, so could be left off */
                          }
        | exp PLUS term   {
                              if(.value == .value) {
                                  $$.node = mknode(.node, .node, "+");
                                  $$.value = .value;
                              } else {
                                  ...
                              }
                          }