Здравствуйте, Аноним, Вы писали:
А> pattern:VPattern; //ExpandableRule
А> textPattern is pattern = "text"s;
А> attributePattern is pattern = "attribute"S identifier S "{"s textPattern "}"s;
А> elementPattern is pattern = "element"S identifier S "{"s pattern "}"s;
А> groupPattern is pattern = pattern (S ','S pattern)+;
А> interlivePattern is pattern = pattern (S '&'S pattern)+;
А> choicePattern is pattern = pattern (S '|'S pattern)+;
Это не PEG. Это какая-то ранняя версия грамматики N2/Nitra. Это, несомненно, левая рекурсия. В принципе в таком виде она допустима, но похоже что ее автор что-то понимает не так.
Nitra поддерживает прямую левую рекурсию для расширяемых правил. Именно таким образом в Nitra описываются операторы. Но вместа циклов (в правой части правил) нужно применять так же рекурсию и приоритеты операторов. Тогда будет появляться требуемая иерархия выражений. То как одни выражения будут вкладываться в другие определяется приоритетами.
Вот так эту грамматику можно записать на Nitra (если я правильно уловил суть):
syntax Pattern;
{
| TextPattern = "text";
| AttributePattern = "attribute" Identifier "{" Pattern "}";
| ElementPattern = "element" Identifier "{" Pattern "}";
| GroupPattern = Pattern ',' Pattern precedence 10;
| ChoicePattern = Pattern '|' Pattern precedence 20;
| InterlivePattern = Pattern '&' Pattern precedence 30;
}
PS
Пробельные правила теперь вручную расставлять не надо. Они ставятся автоматически.