public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) { bool allowTrailingDelimiter = (options & TermListOptions.AllowTrailingDelimiter) != 0; if (delimiter == null) { //it is much simpler case listNonTerminal.SetFlag(TermFlags.IsList); listNonTerminal.Rule = _currentGrammar.Empty | listNonTerminal + listMember; return(listNonTerminal.Rule); } //Note that deceptively simple version of the star-rule // Elem* -> Empty | Elem | Elem* + delim + Elem // does not work when you have delimiters. This simple version allows lists starting with delimiters - // which is wrong. The correct formula is to first define "Elem+"-list, and then define "Elem*" list // as "Elem* -> Empty|Elem+" NonTerminal plusList = new NonTerminal(listMember.Name + "+"); plusList.Rule = MakePlusRule(plusList, delimiter, listMember); plusList.SetFlag(TermFlags.NoAstNode); //to allow it to have AstNodeType not assigned if (allowTrailingDelimiter) { listNonTerminal.Rule = _currentGrammar.Empty | plusList | plusList + delimiter; } else { listNonTerminal.Rule = _currentGrammar.Empty | plusList; } listNonTerminal.SetFlag(TermFlags.IsListContainer); return(listNonTerminal.Rule); }
public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { if (delimiter == null) { listNonTerminal.Rule = listMember | listNonTerminal + listMember; } else { listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember; } listNonTerminal.SetFlag(TermFlags.IsList); return(listNonTerminal.Rule); }