yacc 操作
使用每条语法规则,您可以指定每次解析器识别输入流中的规则时要执行的操作。 操作是 C 语言语句,它进行输入、输出、调用子程序并改变外部向量和变量。
操作返回值并获取前面的操作返回的值。 词法分析器也能为标记返回值。
在语法文件中指定包含一个或多个语句的操作{}(花括号)。 下面的示例是带有操作的语法规则:
A : '('B')'
{
hello(1, "abc" );
}和
XXX : YYY ZZZ
{
printf("a message\n");
flag = 25;
}在操作之间传递值
要获取其他操作生成的值,操作可以使用以美元符号开头的 yacc 参数关键字 ($1,$2, ...)。 这些关键字引用规则右侧的组件返回的值,从左到右进行读取。 例如,如果规则为:
A : B C D ;then$1具有识别 B 的规则返回的值,$2具有可识别 C 的规则返回的值,并且$3由识别 D 的规则返回的值。
要返回值,操作将设置伪变量$$某种价值。 例如,以下操作返回值:1:
{ $$ = 1;}缺省情况下,规则的值是其中第一个元素的值 ($1)。 因此,您不需要为具有以下格式的规则提供操作:
A : B ;以下附加 yacc 参数关键字以$(美元符号) 允许进行类型检查:
- $<标记>$
- $<标记>编号
$<标记>Number 将所引用的联合成员的类型强加给引用<标记>。这会将 .标记 添加到引用中,以便访问由 标记 标识的联合成员。 此构造相当于指定$$.标记 或$1.标记。 当您使用规则中间的操作时,如果无法通过以下命令指定返回类型,那么可以使用此构造:%type 声明。 如果%已为非终端名称声明 type ,请勿使用<标记>构造; 并集引用将自动完成。
将操作放在规则中间
要在完成规则之前控制语法分析过程,请将操作写到规则中间。 如果此规则通过以下命令返回值:$关键字,遵循此规则的操作可以使用该值。 此规则也能使用其前面的操作的返回值。 因此,以下规则集x至1和y到返回的值C. 规则的价值A是返回的值B,遵循缺省规则。
A : B
{
$$ =1;
}
C
{
x = $2;
y = $3;
}
;在内部,yacc 命令为出现在中间的操作创建新的非终止符号名。 它还创建将此名称与空字符串匹配的新的规则。 因此,yacc 命令处理前面的程序就如同它是以下面的格式所写的:
$ACT : /* empty */
{
$$ = 1;
}
;
A : B $ACT C
{
x = $2;
y = $3;
}
;其中$ACT是空操作。