private void CollectAllRecursive(ABnfTerm element) { //Terminal Terminal term = element as Terminal; // Do not add pseudo terminals defined as static singletons in Grammar class (Empty, Eof, etc) // We will never see these terminals in the input stream. // Filter them by type - their type is exactly "Terminal", not derived class. if (term != null && !AllTerms.Contains(term) && term.GetType() != typeof(Terminal)) { AllTerms.Add(term); return; } //NonTerminal NonTerminal nt = element as NonTerminal; if (nt == null || AllTerms.Contains(nt)) return; if (nt.Name == null) { if (nt.Rule != null && !string.IsNullOrEmpty(nt.Rule.Name)) nt.Name = nt.Rule.Name; else nt.Name = "NT" + (_unnamedCount++); } AllTerms.Add(nt); if (nt.Rule == null) { ThrowError("Non-terminal {0} has uninitialized Rule property.", nt.Name); return; } //check all child elements foreach (BnfTermList elemList in nt.Rule.Data) for (int i = 0; i < elemList.Count; i++) { ABnfTerm child = elemList[i]; if (child == null){ ThrowError("Rule for NonTerminal {0} contains null as an operand in position {1} in one of productions.", nt, i); continue; //for i loop } //Check for nested expression - convert to non-terminal BnfExpression expr = child as BnfExpression; if (expr != null) { child = new NonTerminal(null, expr); elemList[i] = child; } CollectAllRecursive(child); } }
public BnfExpression MakeStarRule(NonTerminal listNonTerminal, ABnfTerm listMember) { return MakeStarRule(listNonTerminal, null, listMember); }
public BnfExpression MakeStarRule(NonTerminal listNonTerminal, ABnfTerm delimiter, ABnfTerm listMember) { if (delimiter == null) { //it is much simpler case listNonTerminal.SetOption(TermOptions.IsList); listNonTerminal.Rule = Empty | listNonTerminal + listMember; return listNonTerminal.Rule; } NonTerminal tmp = new NonTerminal(listMember.Name + "+"); tmp.SetOption(TermOptions.IsTransient); //important - mark it as Transient so it will be eliminated from AST tree MakePlusRule(tmp, delimiter, listMember); listNonTerminal.Rule = Empty | tmp; listNonTerminal.SetOption(TermOptions.IsStarList); return listNonTerminal.Rule; }
public BnfExpression MakePlusRule(NonTerminal listNonTerminal, ABnfTerm delimiter, ABnfTerm listMember) { listNonTerminal.SetOption(TermOptions.IsList); if (delimiter == null) listNonTerminal.Rule = listMember | listNonTerminal + listMember; else listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember; return listNonTerminal.Rule; }