public bool IsPOS(string nonTerminal) { return(POSTypes.Contains(nonTerminal)); }
public void RemoveNonTerminalCounts(Rule rule) { var lhs = rule.Name.NonTerminal; if (!nonTerminalCounts.ContainsKey(lhs)) { throw new Exception( string.Format("nonterminal {0} in rule {1} is missing from NonTerminalCounts dictionary", lhs, rule)); } nonTerminalCounts[lhs].lhsCounts--; var productionNonterminals = new List <string>(); if (!rule.IsEpsilonRule()) { int i = 0; foreach (var item in rule.Production) { var rhs = item.NonTerminal; productionNonterminals.Add(rhs); if (!nonTerminalCounts.ContainsKey(rhs)) { throw new Exception( string.Format("nonterminal {0} in rule {1} is missing from NonTerminalCounts dictionary", lhs, rule)); } nonTerminalCounts[rhs].rhsCounts--; if (!RHSDictionary.ContainsKey(rhs)) { throw new Exception(string.Format("nonterminal {0} in rule {1} is missing from RHSDictionary dictionary", rhs, rule)); } //remove from RHSDictionary. RHSDictionary[rhs].Remove(new Tuple <int, int>(rule.Number, i)); i++; } } var lhsCountsOfLHS = nonTerminalCounts[lhs]; //the counts of the Left-hand sided of the rule. //if the removed rule has a LHS that no longer has any other LHS appearances, we can replace all its RHS appearances with another nonterminal, //because we cannot invoke that non-terminal anymore. if (lhsCountsOfLHS.lhsCounts == 0 && lhsCountsOfLHS.rhsCounts > 0 && !POSTypes.Contains(lhs) && lhs != StartSymbol) { //alternatively - do nothing. The resulting grammar will not use these rules. } var lhStoDelete = new List <string>(); if (!rule.IsEpsilonRule()) { foreach (var item in productionNonterminals) { var rhsCountsofRhs = nonTerminalCounts[item]; //the counts of the right-hand sided of the rule terms //if the removed rule has a specific RHS, X, that no longer has any other RHS appearances, we can delete the rules that has X as their LHS //because they will not be triggered (orphaned rules) if (rhsCountsofRhs.rhsCounts == 0 && rhsCountsofRhs.lhsCounts > 0 && !POSTypes.Contains(item) && item != StartSymbol) { var possiblePOS = item.Substring(0, item.Length - 1); if (!POSTypes.Contains(possiblePOS)) { lhStoDelete.Add(item); } } } } foreach (var item in lhStoDelete) { var rules = Rules[item]; var removedRulesNumbers = rules.Select(x => x.Number); foreach (var removedRuleNumber in removedRulesNumbers.ToArray()) { DeleteRule(ruleNumberDictionary[removedRuleNumber]); } } //after updating all counts of nonterminals in the rule, check if the type is still used. //if not, remove it. if (lhsCountsOfLHS.lhsCounts == 0 && lhsCountsOfLHS.rhsCounts == 0 && !POSTypes.Contains(lhs) && lhs != StartSymbol) { var possiblePOS = lhs.Substring(0, lhs.Length - 1); if (!POSTypes.Contains(possiblePOS)) { Console.WriteLine("removed type {0}", lhs); NonTerminalsTypeDictionary.Remove(lhs); nonTerminalCounts.Remove(lhs); } } }