예제 #1
0
        public List <TerminalState> CalculateFirst(NonTerminalState state)
        {
            var result = new List <TerminalState>();

            var states = Sentences.Where(t => t.Left.Name == state.Name);

            foreach (var sentence in states)
            {
                for (int i = 0; i < sentence.Right.Count; ++i)
                {
                    var s = sentence.Right[i];
                    if (s is TerminalState)
                    {
                        result.Add(s as TerminalState);
                        break;
                    }
                    else if (s is NonTerminalState)
                    {
                        result.AddRange(CalculateFirst(s as NonTerminalState).Except(new List <TerminalState>()
                        {
                            TerminalState.Lambda
                        }));

                        if (!Sentences.Any(a => a.Left.Name == s.Name && a.Right.Contains(TerminalState.Lambda)))
                        {
                            break;
                        }
                    }
                }
            }

            return(result);
        }
예제 #2
0
        public List <TerminalState> CalculateFollow(NonTerminalState state)
        {
            var result = new List <TerminalState>();

            if (state.IsStart)
            {
                result.Add(TerminalState.EoF);
            }

            foreach (var sentence in Sentences)
            {
                for (int i = 0; i < sentence.Right.Count; ++i)
                {
                    var s = sentence.Right[i];
                    if (s.Name == state.Name)
                    {
                        var j = i + 1;

                        if (i == sentence.Right.Count - 1)
                        {
                            if (sentence.Left.Name != s.Name)
                            {
                                result.AddRange(CalculateFollow(sentence.Left));
                            }

                            break;
                        }

                        while (j <= sentence.Right.Count)
                        {
                            if (j == sentence.Right.Count)
                            {
                                if (sentence.Left.Name != s.Name)
                                {
                                    result.AddRange(CalculateFollow(sentence.Left));
                                }

                                break;
                            }

                            var next = sentence.Right[j++];
                            if (next is TerminalState)
                            {
                                result.Add(next as TerminalState);
                                break;
                            }
                            else if (next is NonTerminalState)
                            {
                                result.AddRange((next as NonTerminalState).FirstList.Except(new List <TerminalState>()
                                {
                                    TerminalState.Lambda
                                }));

                                if (!Sentences.Any(a => a.Left.Name == next.Name && a.Right.Contains(TerminalState.Lambda)))
                                {
                                    break;
                                }
                            }
                        }

                        break;
                    }
                }
            }

            return(result);
        }
예제 #3
0
        static void Main(string[] args)
        {
            Console.OutputEncoding = System.Text.Encoding.Unicode;

            string path;

            if (args.Length != 0)
            {
                path = args[0];
            }
            else
            {
                Console.WriteLine("Enter Input File Path:");
                path = Console.ReadLine();
            }

            //var end = path.LastIndexOf("\\");
            var root = Path.GetDirectoryName(path);
            var name = Path.GetFileNameWithoutExtension(path);

            var Alphabet = new List <TerminalState>();
            var States   = new List <NonTerminalState>();
            var Vectors  = new List <Sentence>();

            string[] lines = System.IO.File.ReadAllLines(path);
            foreach (var line in lines)
            {
                var parts   = line.Split(' ');
                var command = parts[0];
                switch (command)
                {
                case "state":
                    var state = new NonTerminalState()
                    {
                        Name = parts[1], IsStart = line.Contains("-start")
                    };
                    States.Add(state);
                    break;

                case "vector":
                    var name1  = parts[1];
                    var name2  = parts[2];
                    var state1 = States.SingleOrDefault(u => u.Name == name1);
                    var state2 = new List <IState>();
                    foreach (var a in name2)
                    {
                        IState s = Alphabet.FirstOrDefault(t => t.Name == a.ToString());
                        if (s != null)
                        {
                            state2.Add(s);
                        }
                        else
                        {
                            s = States.FirstOrDefault(t => t.Name == a.ToString());
                            if (s != null)
                            {
                                state2.Add(s);
                            }
                        }
                    }
                    if (state1 != null && state2.Count > 0)
                    {
                        Vectors.Add(new Sentence()
                        {
                            Left = state1, Right = state2
                        });
                    }
                    break;

                case "alphabet":
                    var alphabet = parts[1].Split(',');
                    Alphabet.AddRange(alphabet.Select(s => new TerminalState()
                    {
                        Name = s
                    }));
                    Alphabet.Add(TerminalState.Lambda);
                    Alphabet.Add(TerminalState.EoF);
                    break;
                }
            }

            var parser = new Parser(Alphabet.Except(new List <TerminalState>()
            {
                TerminalState.Lambda
            }).Select(t => t.Name).ToList(), States.Select(t => t.Name).ToList(), Vectors);

            try
            {
                parser.GenerateLL1Table();

                var result = parser.PirntLL1Table();

                var dest = root + "\\" + name + ".html";
                File.WriteAllText(dest, result);

                Console.WriteLine("done!");
            }
            catch (NotLL1Exception)
            {
                Console.WriteLine("The Grammer Is Not LL1!");
            }
        }