我想知道$变量如何与非令牌(如代码块)一起使用。我的问题可以简化为:
我有这样一条规则,中间有一段代码。在这种情况下,$ 3和$ 4是谁?
func-header: ret-type ID { strcpy(func_id,current_id); } LPAREN params RPAREN
答案 0 :(得分:3)
中间规则动作(MRA)被实现为与空序列匹配的非终结符。 (这种非终结符有时被称为“标记”。)中规则动作是生成的非终结符的语义动作。
与任何非终结符一样,这些自动生成的标记具有语义值,该语义值是通过在操作内部分配$$
来设置的。但是,MRA中$n
的编号与正常操作中的编号略有不同。在MRA内部,n
中的每个$n
都被转换为负索引,表示通过减少MRA自己的索引来减少标记时堆栈顶部的值。
yacc / bison始终允许使用负索引,但是根据手册的说明,它们非常危险,只有在您可以证明必须在堆栈的指示点上正确键入值的情况下才应使用负索引。对于自动生成的标记,yacc /野牛可以证明这一点,因为标记仅用于单个生产中,并且生成的负索引始终落入堆栈中被包含MRA的右侧占据的部分。 / p>
答案 1 :(得分:2)
在显示的规则中:
ret-type
是$1
。ID
是$2
。$3
。LPAREN
是$4
。params
是$5
。RPAREN
是$6
。换句话说,代码块充当非终端。