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); }
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); }
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!"); } }