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 {
...
}
}
所以,我在我的 .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 {
...
}
}