我目前减少了野牛,这意味着将逗号分隔的列表与几个可选的不同规则相匹配:
arg_list
:
| expr_list
| assignment_list
| expr_list ',' assignment_list
| varargs
| expr_list ',' varargs
| assignment_list ',' varargs
| expr_list ',' assignment_list ',' varargs
| varkwdargs
| expr_list ',' varkwdargs
| assignment_list ',' varkwdargs
| expr_list ',' assignment_list ',' varkwdargs
| varargs ',' varkwdargs
| expr_list ',' varargs ',' varkwdargs
| assignment_list ',' varargs ',' varkwdargs
| expr_list ',' assignment_list ',' varargs ',' varkwdargs
;
如果不清楚,这意味着实现(在伪代码中):
arg_list
:
| expr_list [',' assignment_list] [',' varargs] [',' varkwdargs]
| assignment_list [',' varargs] [',' varkwdargs]
| varargs [',' varkwdargs]
| varkwdargs
;
这样做的方法是实施,例如:
optional_assignment_list:
:
| ',' assignment_list
;
然而,后一个公式不是 LALR(1),因为在 Bison 看到逗号的每一步,它必须决定是转移并寻找一个 *assignment_list* 还是减少一个空的 *optional_assignment_list* 并继续前进寻找* optional_varargs *。
我正在尝试寻找是否有更好的方法来表示这一点。我已经能够通过引入 *optional_varkwdargs* 来减少备选方案的数量,但这仍然留下了 9 个备选方案来减少,我猜这比 16 个要好:
optional_varkwdargs
:
| ',' varkwdargs
;
arg_list
:
| expr_list optional_varkwdargs
| assignment_list optional_varkwdargs
| expr_list ',' assignment_list optional_varkwdargs
| varargs optional_varkwdargs
| expr_list ',' varargs optional_varkwdargs
| assignment_list ',' varargs optional_varkwdargs
| expr_list ',' assignment_list ',' varargs optional_varkwdargs
| varkwdargs
;
任何想法,将不胜感激。