示例#1
0
 public bool IsPOS(string nonTerminal)
 {
     return(POSTypes.Contains(nonTerminal));
 }
示例#2
0
        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);
                }
            }
        }