Esempio n. 1
0
        bool CheckGrammar(out string reason)
        {
            reason = string.Empty;

            // First Rule cannot be intermediate.
            if (ProductionRules.First().IsIntermediate)
            {
                reason = "First rule cannot be marked as intermediate.";
                return(false);
            }

            // All Rule.Name UNION Terminal.Name Must be unique
            var allNames       = ProductionRules.Select(pr => pr.Name).Union(TerminalSymbols.Select(ts => ts.Name));
            var duplicateNames = allNames.GroupBy(s => s).Where(g => g.Count() > 1);

            if (duplicateNames.Any())
            {
                reason = "Duplicate names: " + string.Join(", ", duplicateNames.Select(duplicateName => duplicateName.Key));
                return(false);
            }

            // Each Rule should have a Non Null "Group" as the RHS - ie Produces has been called
            var nullRhsProductionRuleNames = ProductionRules.Where(pr => pr.Rhs == null || pr.Rhs.Count == 0).Select(pr => pr.Name);

            if (nullRhsProductionRuleNames.Any())
            {
                reason = "Rules which don't produce anything: " + string.Join(", ", nullRhsProductionRuleNames);
                return(false);
            }

            // A 'target' (i.e element of a RulePart) must exist in the list of Rule.Name UNION Terminal.Name
            var badTargetRuleNames = ProductionRules.Where(pr => pr.Rhs.Any(rp => rp.AsEnumerable().Any(target => !allNames.Contains(target.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).First())))).Select(r => r.Name);;

            if (badTargetRuleNames.Any())
            {
                reason = "Rules which produce unknown targets: " + string.Join(", ", badTargetRuleNames);
                return(false);
            }

            // A RuleOrTerminal should not have a RulePart where the first RuleOrTerminal is the rule.
            var directLeftRecursion = ProductionRules.Where(r => r.Rhs.AsEnumerable().Where(rp => rp.Count() > 0 && rp[0] == r.Name).Any());

            if (directLeftRecursion.Any())
            {
                reason = "Direct left recursion: " + string.Join(", ", directLeftRecursion);
                return(false);
            }

            return(true);
        }
Esempio n. 2
0
        public override string ToString()
        {
            StringBuilder result = new StringBuilder();

            TerminalSymbols.ForEach(symbol =>
            {
                if (symbol != Helper.IdentitySymbol && symbol != Helper.EmptySymbol)
                {
                    result.Append(String.Format("{0}, ", symbol));
                }
            });
            result.Remove(result.Length - 2, 2);
            result.Append(";" + Environment.NewLine);
            NonterminalSymbols.ForEach(symbol => result.Append(String.Format("{0}, ", symbol)));
            result.Remove(result.Length - 2, 2);
            result.Append(";" + Environment.NewLine);
            result.Append(Rules.GetString());
            result.Append(";" + Environment.NewLine);
            result.Append(StartSymbol);
            return(result.ToString());
        }