private long CalcPossibilitiesOfDepth(CFGExpressionGrammar grammar, int depth) { long pos = 0; var terminalSymbols = grammar.AllowedSymbols.Where(x => x.MaximumArity <= 0 && !(x is GroupSymbol)); var nonterminalSymbols = grammar.AllowedSymbols.Where(x => x.MinimumArity > 0 && !(x is ProgramRootSymbol) && !(x is StartSymbol) && !(x is Defun) && (x is CFGProduction || !(x is CFGSymbol))); var startSymbols = grammar.GetAllowedChildSymbols(grammar.StartSymbol, 0); foreach (var symbol in nonterminalSymbols) { depthPerSymbolTrees.Add(symbol, new Dictionary <int, int>()); } for (int i = 2; i < depth + 1; i++) { foreach (var ntSymbol in nonterminalSymbols) { int symPos = 1; for (int j = 0; j < ntSymbol.MaximumArity; j++) { int symbolArityPos = 0; foreach (var childSymbol in grammar.GetAllowedChildSymbols(ntSymbol, j)) { if (terminalSymbols.Contains(childSymbol)) { symbolArityPos++; } else { if (depthPerSymbolTrees[childSymbol].ContainsKey(i - 1)) { symbolArityPos += depthPerSymbolTrees[childSymbol][i - 1]; } } } symPos *= symbolArityPos; } depthPerSymbolTrees[ntSymbol].Add(i, symPos); } } foreach (var sy in startSymbols) { if (depthPerSymbolTrees.ContainsKey(sy)) { pos += depthPerSymbolTrees[sy].ContainsKey(depth) ? depthPerSymbolTrees[sy][depth] : 0; } else { pos += 1; } } return(pos); }
private ISymbol GetSymbol(CFGExpressionGrammar grammar, string name) { return(grammar.Symbols.First(x => x.Name == name)); }