当使用右侧为空的规则编写(“理论”)语法时,总是使用诸如 ε(或 1)之类的符号来明确表示这种空性:
A → ε | a A
Yacc 和其他人中的这种语法看起来像
a: | 'a' a
或“更糟”
a: { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
事实上,在“现实世界的语法”(Yacc、Bison 等)中,规则的右侧空部分没有明确标记为空,这让我很困扰:很容易忽略 rhs 为空的事实,或者更糟糕的是:忘记插入|
并实际使用中间规则操作:
a: { $$ = new_list(); }
a 'a' { $$ = $1; $$->append($1); }
;
1)我不知道有任何工具可以使空 rhs 显式化。有吗?
未来版本的 Bison 可能支持专用符号,在非空 rhs 中使用时会出现错误,并在留下隐式空 rhs 时发出警告。
2)人们认为这有用吗?
3) 你建议的符号是什么?
目前,候选人是$empty
:
a: $empty { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
编辑
选择的语法是%empty
:
a: %empty { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
Indeed$empty
看起来像一个伪符号,例如$accept
Bison 为初始规则生成的$@n
伪符号,或者中间规则操作的伪符号,或者$eof
是文件结尾的伪符号。但它绝对不是符号,恰恰是符号的缺失。
另一方面,%
明确表示指令(某种属性/元数据),例如%pred
.
所以这是语法上的细微差别,但更符合整体语法。归功于 Joel E. Denny。