Bison 语法 %type 和 %token

Bison Grammar %type and %token

为什么我必须在下面的语法片段中明确使用 $<nVal>4

我认为 %type <nVal> expr 行不需要,所以我可以简单地输入 </code>?</p> <p>难道不能对 <code>expr 使用不同的定义以便我可以吗?

%union
{
  int   nVal;
  char *pszVal;
}

%token <nVal>   tkNUMBER
%token <pszVal> tkIDENT
%type  <nVal>   expr

%%

for_statement : tkFOR 
                tkIDENT   { printf( "I:%s\n",  );  }
                tkEQUALS 
                expr      { printf( "A:%d\n", $<nVal>4 );    }  // Why not just ?
                tkTO 
                expr      { printf( "B:%d\n", $<nVal>6 );    }  // Why not just ?
                step-statement 
                list 
                next-statement;

expr : tkNUMBER { $$ = ; }
;

更新 按照 rici 的回答。这现在很有用:

for_statement : tkFOR 
                tkIDENT   { printf( "I:%s\n",  );  }
                tkEQUALS 
                expr      { printf( "A:%d\n",  /* $<nVal>5 */ );    }
                tkTO 
                expr      { printf( "A:%d\n",  /* $<nVal>8 */ );    }
                step-statement 
                list 
                next-statement;

Why is it that I have to use $<nVal>4 explicitly in the below grammar snippet?

实际上,如果你想引用expr,你应该使用</code>。 <code>tkEQUALS,它没有声明类型,所以任何使用都必须显式指定类型。 </code> 是前一个中间规则操作,它没有值,因为 <code>$$ 没有在该操作中分配。

同理,第二个expr就是</code>; <code> 是第二个中间规则动作,它也没有值(也没有类型)。

参见Bison manual

The mid-rule action itself counts as one of the components of the rule. This makes a difference when there is another action later in the same rule (and usually there is another at the end): you have to count the actions along with the symbols when working out which number n to use in $n.