Bison:$ 变量($1 $2 等)如何与非令牌一起使用?

Bison: How $ variables ($1 $2 etc) work with non-tokens?

我想知道 $ 变量如何与非标记一起使用,例如代码块。我的问题可以简化为:

我有这样一条规则,中间有一段代码。在这种情况下谁是 3 美元和 4 美元?

func-header: ret-type ID { strcpy(func_id,current_id); } LPAREN params RPAREN

在显示的规则中:

  • ret-type</code>.</li> <li><code>ID</code>.</li> <li>代码块是<code>.
  • LPAREN</code>.</li> <li><code>params</code>.</li> <li><code>RPAREN.

换句话说,代码块充当non-terminals。

Mid-rule 操作 (MRA) 实现为 non-terminals,它匹配一个空序列。 (这样的 non-terminals 有时被称为 "markers"。) mid-rule 动作是生成的 non-terminal.

的语义动作

与任何 non-terminal 一样,这些 automatically-generated 标记具有语义值,通过在操作中分配 $$ 来设置。但是,MRA 中 $n 的编号与正常操作中的编号略有不同。在 MRA 内部,$n 中的每个 n 都被转换为负索引,表示通过减去 MRA 的 iwn 索引减少标记时堆栈顶部的值。

yacc/bison 始终允许使用负索引,但正如手册所述,它们非常危险,只有在您可以证明正确键入的值必然位于堆栈上的指示点时才应使用。在automatically-generated个标记的情况下,yacc/bison可以证明这一点,因为该标记仅在单个生产中使用,并且生成的负索引总是落入right-hand占用的堆栈部分含有 MRA 的一面。