私は現在、カンマ区切りのリストをいくつかのオプションの異なるルールと一致させることを目的とした bison の削減を行っています。
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
;
どんなアイデアでも大歓迎です。