예제 #1
0
        public static Gramm ReadGramm(string filename)
        {
            string input      = File.ReadAllText(filename);
            Gramm  inputGramm = JsonConvert.DeserializeObject <Gramm>(input);

            return(inputGramm);
        }
        private static List <string> FindNTInRules(List <List <string> > rights, Gramm gr)
        {
            List <string> NT = new List <string>();

            foreach (var right in rights)
            {
                NT.AddRange(FindNTInRule(right, gr));
            }
            return(NT);
        }
예제 #3
0
        public static void WriteGramm(Gramm gr, string filename)
        {
            var options = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            };
            string output = JsonConvert.SerializeObject(gr, options);

            File.WriteAllText(filename, output);
        }
예제 #4
0
        static void Main(string[] args)
        {
            GramFileProcessor.WriteGramm(CreateTestGramm(), "TestGramm.json");

            Gramm input   = GramFileProcessor.ReadGramm("TestGramm.json");
            var   reachGr = UnreachableProcessor.RemoveUnreachable(input);
            var   newGr   = GrammProcessor.RemoveLR(reachGr);
            var   factGr  = FactProcessor.Fact(newGr);

            GramFileProcessor.WriteGramm(factGr, "ResultGramm.json");
        }
        private static List <string> FindNTInRule(List <string> right, Gramm gr)
        {
            List <string> NT = new List <string>();

            foreach (var t in right)
            {
                if (gr.NonTerms.Contains(t))
                {
                    NT.Add(t);
                }
            }
            return(NT);
        }
예제 #6
0
        private static string FindNewTerm(string left, Gramm gr)
        {
            bool   cont    = false;
            string newTerm = left;

            do
            {
                newTerm = newTerm + "'";
                cont    = gr.NonTerms.Contains(newTerm);
            } while (cont);

            return(newTerm);
        }
예제 #7
0
        private static List <List <string> > GetAllRightParts(string left, Gramm gr)
        {
            var rightParts = new List <List <string> >();

            foreach (var rule in gr.Rules)
            {
                if (rule.Left == left)
                {
                    rightParts.Add(rule.Rights);
                }
            }
            return(rightParts);
        }
예제 #8
0
        private static Gramm CreateTestGramm()
        {
            Gramm testGramm = new Gramm();

            testGramm.Terms.Add("a");
            testGramm.Terms.Add("b");
            testGramm.Terms.Add("c");
            testGramm.Terms.Add("d");
            testGramm.Terms.Add("e");

            testGramm.NonTerms.Add("E");
            testGramm.NonTerms.Add("F");
            testGramm.NonTerms.Add("T");
            testGramm.NonTerms.Add("H");
            testGramm.NonTerms.Add("Z");
            testGramm.St = "E";


            testGramm.Rules.Add(new Rule("E", new List <string>()
            {
                "E", "a"
            }));
            testGramm.Rules.Add(new Rule("F", new List <string>()
            {
                "T", "F"
            }));
            testGramm.Rules.Add(new Rule("T", new List <string>()
            {
                "a", "E"
            }));
            testGramm.Rules.Add(new Rule("E", new List <string>()
            {
                "a", "F", "a"
            }));
            testGramm.Rules.Add(new Rule("H", new List <string>()
            {
                "a", "F", "a"
            }));
            testGramm.Rules.Add(new Rule("H", new List <string>()
            {
                "E", "E", "a"
            }));
            testGramm.Rules.Add(new Rule("Z", new List <string>()
            {
                "Z", "Z"
            }));

            return(testGramm);
        }
예제 #9
0
        public static Dictionary <string, List <List <string> > > GetAllSymbRules(Gramm gr)
        {
            var lefts     = new HashSet <string>();
            var symbRules = new Dictionary <string, List <List <string> > >();

            foreach (var rule in gr.Rules)
            {
                if (!lefts.Contains(rule.Left))
                {
                    lefts.Add(rule.Left);
                    symbRules.Add(rule.Left, GetAllRightParts(rule.Left, gr));
                }
            }
            return(symbRules);
        }
예제 #10
0
        public static Gramm Fact(Gramm gr)
        {
            var symbRules    = GrammProcessor.GetAllSymbRules(gr);
            var newSymbRules = new Dictionary <string, List <List <string> > >(symbRules);

            foreach (var rule in symbRules)
            {
                var  left = rule.Key;
                bool flag = true;

                while (flag)
                {
                    var rights     = newSymbRules[left];
                    var fullRights = GetFullRights(rights);
                    var msub       = GetMSub(fullRights);
                    if (msub.Length == 0)
                    {
                        flag = false;
                        break;
                    }
                    var subRights    = GetSubRights(fullRights, msub);
                    var nonSubRights = fullRights.Except(subRights).ToList();
                    var cutRights    = GetCutRights(subRights, msub);

                    List <List <string> > newRights = new List <List <string> >();
                    var newTerm = FindNewTerm(left, gr);
                    newRights.Add(GetRight(msub + newTerm));
                    newRights.AddRange(GetRights(nonSubRights));
                    newSymbRules[left] = newRights;
                    newSymbRules.Add(newTerm, GetRights(cutRights));
                    gr.NonTerms.Add(newTerm);
                }
            }

            gr.Rules = new List <Rule>();
            foreach (var rule in newSymbRules)
            {
                foreach (var right in rule.Value)
                {
                    gr.Rules.Add(new Rule(rule.Key, right));
                }
            }

            return(gr);
        }
예제 #11
0
        public static Gramm RemoveUnreachable(Gramm gr)
        {
            var           symbRules = GrammProcessor.GetAllSymbRules(gr);
            bool          changed   = true;
            List <string> UsedNT    = new List <string>()
            {
                gr.St
            };

            while (changed)
            {
                int len = UsedNT.Count;
                foreach (var rule in symbRules)
                {
                    if (UsedNT.Contains(rule.Key))
                    {
                        UsedNT = UsedNT.Union(FindNTInRules(rule.Value, gr)).ToList();
                    }
                }
                if (UsedNT.Count == len)
                {
                    changed = false;
                }
            }

            List <string> unreachable = gr.NonTerms.Except(UsedNT).ToList();

            gr.NonTerms = UsedNT;
            foreach (var un in unreachable)
            {
                symbRules.Remove(un);
            }

            gr.Rules = new List <Rule>();
            foreach (var rule in symbRules)
            {
                foreach (var right in rule.Value)
                {
                    gr.Rules.Add(new Rule(rule.Key, right));
                }
            }

            return(gr);
        }
예제 #12
0
        private static Gramm CreateTestGramm()
        {
            Gramm testGramm = new Gramm();

            //testGramm.Terms.Add("+");
            //testGramm.Terms.Add("*");
            //testGramm.Terms.Add("(");
            //testGramm.Terms.Add(")");
            testGramm.Terms.Add("a");
            testGramm.Terms.Add("b");
            testGramm.Terms.Add("c");
            testGramm.Terms.Add("d");
            testGramm.Terms.Add("e");

            testGramm.NonTerms.Add("E"); //Escape
            testGramm.NonTerms.Add("F"); //From
            testGramm.NonTerms.Add("T"); //Tarkov
            testGramm.NonTerms.Add("H");
            //testGramm.NonTerms.Add("S");
            //testGramm.NonTerms.Add("A");
            //testGramm.NonTerms.Add("B");
            //testGramm.NonTerms.Add("C");

            testGramm.St = "E";
            //testGramm.St = "S";


            testGramm.Rules.Add(new Rule("E", new List <string>()
            {
                "E", "a"
            }));
            testGramm.Rules.Add(new Rule("F", new List <string>()
            {
                "T", "F"
            }));
            testGramm.Rules.Add(new Rule("T", new List <string>()
            {
                "a", "E"
            }));
            testGramm.Rules.Add(new Rule("E", new List <string>()
            {
                "a", "F", "a"
            }));
            testGramm.Rules.Add(new Rule("H", new List <string>()
            {
                "a", "F", "a"
            }));
            testGramm.Rules.Add(new Rule("H", new List <string>()
            {
                "E", "E", "a"
            }));

            //testGramm.Rules.Add(new Rule("S", new List<string>() { "A", "a"}));
            //testGramm.Rules.Add(new Rule("S", "b"));
            //testGramm.Rules.Add(new Rule("A", new List<string>() { "A", "c"}));
            //testGramm.Rules.Add(new Rule("A", new List<string>() {"S", "d"}));
            //testGramm.Rules.Add(new Rule("A", new List<string>() { "a", "b" }));
            //testGramm.Rules.Add(new Rule("A", new List<string>() { "a", "b", "c" }));
            //testGramm.Rules.Add(new Rule("A", new List<string>() { "a", "b", "c", "S" }));
            //testGramm.Rules.Add(new Rule("A", new List<string>() { "b", "b", "b", "b", "S" }));
            //testGramm.Rules.Add(new Rule("A", new List<string>() { "a", "b", "c", "A" }));
            //testGramm.Rules.Add(new Rule("A", new List<string>() { "a", "b", "S" }));

            //testGramm.Rules.Add(new Rule("A", new List<string>() { "c", "d", "B" }));

            //testGramm.Rules.Add(new Rule("B", new List<string>() { "a", "b", "S" }));
            //testGramm.Rules.Add(new Rule("B", new List<string>() { "a", "b", "A" }));

            //testGramm.Rules.Add(new Rule("C", new List<string>() { "b", "S" }));

            return(testGramm);
        }
예제 #13
0
        public static Gramm RemoveLR(Gramm gr)
        {
            var symbRules = GetAllSymbRules(gr);
            var lefts     = symbRules.Keys.ToList();

            for (int i = 0; i < lefts.Count; i++)
            {
                string left   = lefts[i];
                var    rights = new List <List <string> >(symbRules[left]);

                //Подстановка старых, "чистых правил" в новые
                for (int j = 0; j < i; j++)
                {
                    string prevLeft = lefts[j];
                    for (int k = 0; k < rights.Count; k++)
                    {
                        var right = rights[k];

                        if (right[0] == prevLeft)
                        {
                            var prevRights = new List <List <string> >(symbRules[prevLeft]);
                            rights.RemoveAt(k);
                            right.RemoveAt(0);

                            foreach (var prevRight in prevRights)
                            {
                                var newRight = new List <string>(prevRight);
                                newRight.AddRange(right);
                                rights.Add(newRight);
                            }
                        }
                    }
                }

                symbRules.Remove(left);

                //Устранение непосредственной рекурсии
                if (rights.Any(x => x.First() == left))
                {
                    string newTerm = left + "'";
                    gr.NonTerms.Add(newTerm);
                    var sRights  = new List <List <string> >();
                    var prRights = new List <List <string> >();

                    foreach (var right in rights)
                    {
                        if (right.First() == left)
                        {
                            right.RemoveAt(0);

                            var newRight = new List <string>();
                            newRight.AddRange(right);
                            newRight.Add(newTerm);
                            sRights.Add(newRight);
                        }
                        else
                        {
                            var newRight = new List <string>();
                            newRight.AddRange(right);
                            newRight.Add(newTerm);
                            prRights.Add(newRight);
                        }
                    }

                    symbRules.Add(left, prRights);
                    symbRules.Add(newTerm, sRights);
                }
                else
                {
                    symbRules.Add(left, rights);
                }
            }

            gr.Rules = new List <Rule>();
            foreach (var rule in symbRules)
            {
                foreach (var right in rule.Value)
                {
                    gr.Rules.Add(new Rule(rule.Key, right));
                }
            }

            return(gr);
        }
예제 #14
0
        private static Gramm CreateFinGramm()
        {
            Gramm testGramm = new Gramm();

            //4
            testGramm.NonTerms.Add("Expr");
            testGramm.NonTerms.Add("LogExpr");
            testGramm.NonTerms.Add("LogOne");
            testGramm.NonTerms.Add("LogSec");
            testGramm.NonTerms.Add("LogFir");
            testGramm.NonTerms.Add("LogVal");
            testGramm.NonTerms.Add("LogTerm");
            testGramm.NonTerms.Add("Id");

            testGramm.NonTerms.Add("Prog");
            testGramm.NonTerms.Add("Block");
            testGramm.NonTerms.Add("OpList");
            testGramm.NonTerms.Add("Op");

            testGramm.NonTerms.Add("LogExpr_");
            testGramm.NonTerms.Add("LogOne_");
            testGramm.NonTerms.Add("OpList_");

            testGramm.St = "Expr";

            testGramm.Rules.Add(new Rule("Expr", new List <string>()
            {
                "LogExpr"
            }));

            testGramm.Rules.Add(new Rule("LogExpr", new List <string>()
            {
                "LogOne", "LogExpr_"
            }));

            testGramm.Rules.Add(new Rule("LogExpr_", new List <string>()
            {
                "!", "LogOne", "LogExpr_"
            }));
            testGramm.Rules.Add(new Rule("LogExpr_", new List <string>()
            {
                "Eps"
            }));

            testGramm.Rules.Add(new Rule("LogOne", new List <string>()
            {
                "LogSec", "LogOne_"
            }));

            testGramm.Rules.Add(new Rule("LogOne_", new List <string>()
            {
                "&", "LogSec", "LogOne_"
            }));
            testGramm.Rules.Add(new Rule("LogOne_", new List <string>()
            {
                "Eps"
            }));

            testGramm.Rules.Add(new Rule("LogSec", new List <string>()
            {
                "LogFir"
            }));
            testGramm.Rules.Add(new Rule("LogSec", new List <string>()
            {
                "~", "LogFir"
            }));

            testGramm.Rules.Add(new Rule("LogFir", new List <string>()
            {
                "LogVal"
            }));
            testGramm.Rules.Add(new Rule("LogFir", new List <string>()
            {
                "Id"
            }));

            testGramm.Rules.Add(new Rule("LogVal", new List <string>()
            {
                "true"
            }));
            testGramm.Rules.Add(new Rule("LogVal", new List <string>()
            {
                "false"
            }));

            testGramm.Rules.Add(new Rule("LogTerm", new List <string>()
            {
                "~"
            }));
            testGramm.Rules.Add(new Rule("LogTerm", new List <string>()
            {
                "&"
            }));
            testGramm.Rules.Add(new Rule("LogTerm", new List <string>()
            {
                "!"
            }));


            testGramm.Rules.Add(new Rule("Prog", new List <string>()
            {
                "Block"
            }));
            testGramm.Rules.Add(new Rule("Block", new List <string>()
            {
                "begin", "OpList", "end"
            }));
            testGramm.Rules.Add(new Rule("OpList", new List <string>()
            {
                "Op", "OpList_"
            }));
            testGramm.Rules.Add(new Rule("OpList_", new List <string>()
            {
                ";", "Op", "OpList_"
            }));
            testGramm.Rules.Add(new Rule("OpList_", new List <string>()
            {
                "Eps"
            }));
            testGramm.Rules.Add(new Rule("Op", new List <string>()
            {
                "Id", "=", "Expr"
            }));



            return(testGramm);
        }