Я работаю над проектом синтаксического анализа, в котором используется адаптация этой грамматики для регулярных выражений Perl http://www.cs.sfu.ca/~cameron/Teaching/384/99-3/regexp-plg.html. Я упростил эту грамматику для своих собственных целей, например так (обратите внимание, что, поскольку «|» является токеном, вместо этого я использую запятую «,», поэтому отдельные произведения для данного нетерминала):
<RE> := <union>, <simple>
<union> := <RE> | <simple>
<simple> := <concat>, <basic>
<concat> := <simple><basic>
<basic> := <zero>, <one>, <onezero>, <elem>
<zero> := <elem>*
<one> := <elem>+
<onezero> := <elem>?
<elem> := <group>, <any>, <literal>, <class>
<group> := (<RE>)
<class> := [<items>]
<items> := <item>, <item><items>
<item> := <range>, <literal>
Я хочу написать синтаксический анализатор LL(1) для обработки этой грамматики, а для синтаксического анализатора LL(1) продукция для <items>
имеет некоторую двусмысленность. Чтобы исправить это, я мог бы разложить их по левым множителям, добавив новый нетерминал <X>
, например так:
<items> := <item><X>
<X> := <items>, epsilon
Но мне интересно, могу ли я просто изменить порядок второго производства в <items>
, вот так:
<items> := <item>, <items><item>
и не добавлять новый нетерминал? Не похоже, что это что-то ломает, в конце концов, весь смысл этого производства в том, чтобы разрешить любое переменное количество последовательных <item>
символов, и мы все равно получим это, если изменим порядок. Я что-то упустил, или просто изменение порядка в обратном порядке достигает той же цели, что и левый факторинг в этой ситуации?